manager: make system_create_virtual_device() return a GError

This is done so that AddAndActivate() will return sensible errors in a
future patch that makes it support creating virtual devices.

In effect, all errors are logged in one place, therefore the log levels
are different. I don't think we're losing anything of value by being
a little less verbose here.

(cherry picked from commit 45d82f720c)
This commit is contained in:
Lubomir Rintel
2025-02-20 16:39:08 +01:00
parent 949c7b84a3
commit 4a1c51317e

View File

@@ -2594,7 +2594,7 @@ nm_manager_remove_device(NMManager *self, const char *ifname, NMDeviceType devic
* Returns: A #NMDevice that was just realized; %NULL if none
*/
static NMDevice *
system_create_virtual_device(NMManager *self, NMConnection *connection)
system_create_virtual_device(NMManager *self, NMConnection *connection, GError **error)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self);
NMDeviceFactory *factory;
@@ -2605,20 +2605,20 @@ system_create_virtual_device(NMManager *self, NMConnection *connection)
NMDevice *device = NULL;
NMDevice *parent = NULL;
NMDevice *dev_candidate;
gs_free_error GError *error = NULL;
NMLogLevel log_level;
g_return_val_if_fail(NM_IS_MANAGER(self), NULL);
g_return_val_if_fail(NM_IS_CONNECTION(connection), NULL);
iface = nm_manager_get_connection_iface(self, connection, &parent, &parent_spec, &error);
if (!iface) {
_LOG3D(LOGD_DEVICE, connection, "can't get a name of a virtual device: %s", error->message);
iface = nm_manager_get_connection_iface(self, connection, &parent, &parent_spec, error);
if (!iface)
return NULL;
}
if (parent_spec && !parent) {
/* parent is not ready, wait */
g_set_error(error,
NM_MANAGER_ERROR,
NM_MANAGER_ERROR_DEPENDENCY_FAILED,
"Parent device for '%s' not available",
iface);
return NULL;
}
@@ -2626,7 +2626,11 @@ system_create_virtual_device(NMManager *self, NMConnection *connection)
c_list_for_each_entry (dev_candidate, &priv->devices_lst_head, devices_lst) {
if (nm_device_check_connection_compatible(dev_candidate, connection, FALSE, NULL)) {
if (nm_device_is_real(dev_candidate)) {
_LOG3D(LOGD_DEVICE, connection, "already created virtual interface name %s", iface);
g_set_error(error,
NM_MANAGER_ERROR,
NM_MANAGER_ERROR_UNKNOWN_DEVICE,
"Device named '%s' already exists",
iface);
return NULL;
}
@@ -2640,27 +2644,22 @@ system_create_virtual_device(NMManager *self, NMConnection *connection)
factory = nm_device_factory_manager_find_factory_for_connection(connection);
if (!factory) {
_LOG3E(LOGD_DEVICE,
connection,
"(%s) NetworkManager plugin for '%s' unavailable",
iface,
nm_connection_get_connection_type(connection));
g_set_error(error,
NM_MANAGER_ERROR,
NM_MANAGER_ERROR_UNKNOWN_DEVICE,
"'%s' plugin for '%s' unavailable",
nm_connection_get_connection_type(connection),
iface);
return NULL;
}
device = nm_device_factory_create_device(factory, iface, NULL, connection, NULL, &error);
if (!device) {
_LOG3W(LOGD_DEVICE, connection, "factory can't create the device: %s", error->message);
device = nm_device_factory_create_device(factory, iface, NULL, connection, NULL, error);
if (!device)
return NULL;
}
_LOG3D(LOGD_DEVICE, connection, "create virtual device %s", nm_device_get_iface(device));
if (!add_device(self, device, &error)) {
_LOG3W(LOGD_DEVICE,
connection,
"can't register the device with manager: %s",
error->message);
if (!add_device(self, device, error)) {
g_object_unref(device);
return NULL;
}
@@ -2679,10 +2678,8 @@ system_create_virtual_device(NMManager *self, NMConnection *connection)
return device;
}
if (!find_controller(self, connection, device, NULL, NULL, NULL, &error)) {
_LOG3D(LOGD_DEVICE, connection, "skip activation: %s", error->message);
if (!find_controller(self, connection, device, NULL, NULL, NULL, error))
return device;
}
/* Create backing resources if the device has any autoconnect connections */
connections = nm_settings_get_connections_sorted_by_autoconnect_priority(priv->settings, NULL);
@@ -2699,18 +2696,8 @@ system_create_virtual_device(NMManager *self, NMConnection *connection)
continue;
/* Create any backing resources the device needs */
if (!nm_device_create_and_realize(device, connection, parent, &error)) {
log_level =
g_error_matches(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_MISSING_DEPENDENCIES)
? LOGL_DEBUG
: LOGL_ERR;
_NMLOG3(log_level,
LOGD_DEVICE,
connection,
"couldn't create the device: %s",
error->message);
if (!nm_device_create_and_realize(device, connection, parent, error))
return NULL;
}
retry_connections_for_parent_device(self, device);
break;
@@ -2753,6 +2740,7 @@ connection_changed(NMManager *self, NMSettingsConnection *sett_conn)
{
NMConnection *connection;
NMDevice *device;
gs_free_error GError *error = NULL;
if (NM_FLAGS_ANY(nm_settings_connection_get_flags(sett_conn),
NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE
@@ -2764,9 +2752,11 @@ connection_changed(NMManager *self, NMSettingsConnection *sett_conn)
if (!nm_connection_is_virtual(connection))
return;
device = system_create_virtual_device(self, connection);
if (!device)
device = system_create_virtual_device(self, connection, &error);
if (!device) {
_LOG3D(LOGD_DEVICE, connection, "Can't create a virtual device: %s", error->message);
return;
}
/* Maybe the device that was created was needed by some other
* connection's device (parent of a VLAN). Let the connections