From 7bad40109ecb8ed9569e24fd64892a3cad916133 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 10 Jul 2018 11:50:21 +0200 Subject: [PATCH] core: return error reason from nm_manager_get_best_device_for_connection() Still unused, but will be used to give a better failure reason when no device is found. The difficulty here is to select the failure message from the most appropriate device. This might still need some tweaking by setting the error codes accordingly and re-ordering checks so that failure cares that are more accurate are handled first. --- src/nm-manager.c | 53 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/src/nm-manager.c b/src/nm-manager.c index 95799eb42..f54d649ca 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -3236,7 +3236,8 @@ static NMDevice * nm_manager_get_best_device_for_connection (NMManager *self, NMConnection *connection, gboolean for_user_request, - GHashTable *unavailable_devices) + GHashTable *unavailable_devices, + GError **error) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMActiveConnectionState ac_state; @@ -3245,6 +3246,7 @@ nm_manager_get_best_device_for_connection (NMManager *self, NMDevice *device; NMDeviceCheckConAvailableFlags flags; gs_unref_ptrarray GPtrArray *all_ac_arr = NULL; + gs_free_error GError *local_best = NULL; flags = for_user_request ? NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST : NM_DEVICE_CHECK_CON_AVAILABLE_NONE; @@ -3319,15 +3321,53 @@ found_better: /* Pick the first device that's compatible with the connection. */ c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) { + GError *local = NULL; - if (unavailable_devices && g_hash_table_contains (unavailable_devices, device)) + if ( unavailable_devices + && g_hash_table_contains (unavailable_devices, device)) continue; - if (nm_device_check_connection_available (device, connection, flags, NULL, NULL)) + if (nm_device_check_connection_available (device, + connection, + flags, + NULL, + error ? &local : NULL)) return device; + + if (error) { + gboolean reset_error; + + if (!local_best) + reset_error = TRUE; + else if (local_best->domain != NM_UTILS_ERROR) + reset_error = (local->domain == NM_UTILS_ERROR); + else { + reset_error = ( local->domain == NM_UTILS_ERROR + && local_best->code < local->code); + } + + if (reset_error) { + g_clear_error (&local_best); + g_set_error (&local_best, + local->domain, + local->code, + "device %s not available because %s", + nm_device_get_iface (device), + local->message); + } + g_error_free (local); + } } - /* No luck. :( */ + if (error) { + if (local_best) + g_propagate_error (error, g_steal_pointer (&local_best)); + else { + nm_utils_error_set_literal (error, + NM_UTILS_ERROR_UNKNOWN, + "no suitable device found"); + } + } return NULL; } @@ -3782,7 +3822,8 @@ find_slaves (NMManager *manager, slave_device = nm_manager_get_best_device_for_connection (manager, candidate, FALSE, - devices); + devices, + NULL); if (!slaves) { /* what we allocate is quite likely much too large. Don't bother, it is only @@ -4589,7 +4630,7 @@ validate_activation_request (NMManager *self, return NULL; } } else if (!is_vpn) { - device = nm_manager_get_best_device_for_connection (self, connection, TRUE, NULL); + device = nm_manager_get_best_device_for_connection (self, connection, TRUE, NULL, NULL); if (!device) { gs_free char *iface = NULL;