diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2023-11-21 14:57:17 +0100 |
---|---|---|
committer | Íñigo Huguet <ihuguet@redhat.com> | 2024-02-21 11:49:20 +0100 |
commit | 3bb34edc5331f9ffafac5ca45ba07adbcc0ae071 (patch) | |
tree | 24cbc2dfa8534501dbc0b42f59dbd6c08326faf0 | |
parent | f8e020c29eb7f166b2a7aad54f49e9ea4172a2a0 (diff) |
core: persist state of software generic devices across restarts
When a generic connection has a custom device-handler, it always
generates a NMDeviceGeneric, even when the link that gets created is
of a type natively supported by NM. On service restart, we need to
keep track that the device is generic or otherwise a different device
type will be instantiated.
(cherry picked from commit f2613be150ed10e651b4273ddddccd914cb866da)
-rw-r--r-- | src/core/devices/nm-device-factory.c | 16 | ||||
-rw-r--r-- | src/core/devices/nm-device-factory.h | 2 | ||||
-rw-r--r-- | src/core/nm-config.c | 29 | ||||
-rw-r--r-- | src/core/nm-config.h | 5 | ||||
-rw-r--r-- | src/core/nm-manager.c | 13 |
5 files changed, 54 insertions, 11 deletions
diff --git a/src/core/devices/nm-device-factory.c b/src/core/devices/nm-device-factory.c index 381e0d88e7..69c2a38f13 100644 --- a/src/core/devices/nm-device-factory.c +++ b/src/core/devices/nm-device-factory.c @@ -28,6 +28,10 @@ G_DEFINE_ABSTRACT_TYPE(NMDeviceFactory, nm_device_factory, G_TYPE_OBJECT) /*****************************************************************************/ +static NMDeviceFactory *generic_factory; + +/*****************************************************************************/ + static void nm_device_factory_get_supported_types(NMDeviceFactory *factory, const NMLinkType **out_link_types, @@ -66,7 +70,8 @@ nm_device_factory_create_device(NMDeviceFactory *factory, if (plink) { g_return_val_if_fail(!connection, NULL); g_return_val_if_fail(strcmp(iface, plink->name) == 0, NULL); - nm_assert(factory == nm_device_factory_manager_find_factory_for_link_type(plink->type)); + nm_assert(factory == nm_device_factory_manager_find_factory_for_link_type(plink->type) + || factory == generic_factory); } else if (connection) nm_assert(factory == nm_device_factory_manager_find_factory_for_connection(connection)); else @@ -185,6 +190,12 @@ static void __attribute__((destructor)) _cleanup(void) } NMDeviceFactory * +nm_device_factory_get_generic_factory(void) +{ + return generic_factory; +} + +NMDeviceFactory * nm_device_factory_manager_find_factory_for_link_type(NMLinkType link_type) { g_return_val_if_fail(factories_by_link, NULL); @@ -300,9 +311,12 @@ _load_internal_factory(GType factory_gtype, gpointer user_data) { gs_unref_object NMDeviceFactory *factory = NULL; + GType nm_generic_device_factory_get_type(void); factory = g_object_new(factory_gtype, NULL); _add_factory(factory, NULL, callback, user_data); + if (factory_gtype == nm_generic_device_factory_get_type()) + generic_factory = factory; } static void diff --git a/src/core/devices/nm-device-factory.h b/src/core/devices/nm-device-factory.h index fc3d9dd43a..004ae9b1bf 100644 --- a/src/core/devices/nm-device-factory.h +++ b/src/core/devices/nm-device-factory.h @@ -234,4 +234,6 @@ NMDeviceFactory *nm_device_factory_manager_find_factory_for_connection(NMConnect void nm_device_factory_manager_for_each_factory(NMDeviceFactoryManagerFactoryFunc callback, gpointer user_data); +NMDeviceFactory *nm_device_factory_get_generic_factory(void); + #endif /* __NETWORKMANAGER_DEVICE_FACTORY_H__ */ diff --git a/src/core/nm-config.c b/src/core/nm-config.c index 5db4a92a4f..43eb364699 100644 --- a/src/core/nm-config.c +++ b/src/core/nm-config.c @@ -2354,9 +2354,10 @@ _nm_config_state_set(NMConfig *self, gboolean allow_persist, gboolean force_pers "route-metric-default-aspired" #define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_ROUTE_METRIC_DEFAULT_EFFECTIVE \ "route-metric-default-effective" -#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_ROOT_PATH "root-path" -#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_NEXT_SERVER "next-server" -#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_DHCP_BOOTFILE "dhcp-bootfile" +#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_ROOT_PATH "root-path" +#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_NEXT_SERVER "next-server" +#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_DHCP_BOOTFILE "dhcp-bootfile" +#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_GENERIC_SOFTWARE "generic-software" static NM_UTILS_LOOKUP_STR_DEFINE( _device_state_managed_type_to_str, @@ -2457,6 +2458,12 @@ _config_device_state_data_new(int ifindex, GKeyFile *kf) device_state->route_metric_default_aspired = route_metric_default_aspired; device_state->route_metric_default_effective = route_metric_default_effective; + device_state->generic_sw = + nm_config_keyfile_get_boolean(kf, + DEVICE_RUN_STATE_KEYFILE_GROUP_DEVICE, + DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_GENERIC_SOFTWARE, + FALSE); + p = (char *) (&device_state[1]); if (connection_uuid) { memcpy(p, connection_uuid, connection_uuid_len); @@ -2502,7 +2509,7 @@ nm_config_device_state_load(int ifindex) ? ", nm-owned=1" : (device_state->nm_owned == NM_TERNARY_FALSE ? ", nm-owned=0" : ""); - _LOGT("device-state: %s #%d (%s); managed=%s%s%s%s%s%s%s%s, " + _LOGT("device-state: %s #%d (%s); managed=%s%s%s%s%s%s%s%s%s, " "route-metric-default=%" G_GUINT32_FORMAT "-%" G_GUINT32_FORMAT "", kf ? "read" : "miss", ifindex, @@ -2519,6 +2526,7 @@ nm_config_device_state_load(int ifindex) "", ""), nm_owned_str, + device_state->generic_sw ? ", generic-software" : "", device_state->route_metric_default_aspired, device_state->route_metric_default_effective); @@ -2577,7 +2585,8 @@ nm_config_device_state_write(int ifindex, guint32 route_metric_default_aspired, guint32 route_metric_default_effective, NMDhcpConfig *dhcp4_config, - NMDhcpConfig *dhcp6_config) + NMDhcpConfig *dhcp6_config, + gboolean generic_sw) { char path[NM_STRLEN(NM_CONFIG_DEVICE_STATE_DIR "/") + DEVICE_STATE_FILENAME_LEN_MAX + 1]; GError *local = NULL; @@ -2664,6 +2673,13 @@ nm_config_device_state_write(int ifindex, dhcp_bootfile); } + if (generic_sw) { + g_key_file_set_boolean(kf, + DEVICE_RUN_STATE_KEYFILE_GROUP_DEVICE, + DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_GENERIC_SOFTWARE, + TRUE); + } + for (IS_IPv4 = 1; IS_IPv4 >= 0; IS_IPv4--) { NMDhcpConfig *dhcp_config = IS_IPv4 ? dhcp4_config : dhcp6_config; gs_free NMUtilsNamedValue *values = NULL; @@ -2691,7 +2707,7 @@ nm_config_device_state_write(int ifindex, g_error_free(local); return FALSE; } - _LOGT("device-state: write #%d (%s); managed=%s%s%s%s%s%s%s, " + _LOGT("device-state: write #%d (%s); managed=%s%s%s%s%s%s%s%s, " "route-metric-default=%" G_GUINT32_FORMAT "-%" G_GUINT32_FORMAT "%s%s%s" "%s%s%s" "%s%s%s", @@ -2700,6 +2716,7 @@ nm_config_device_state_write(int ifindex, _device_state_managed_type_to_str(managed), NM_PRINT_FMT_QUOTED(connection_uuid, ", connection-uuid=", connection_uuid, "", ""), NM_PRINT_FMT_QUOTED(perm_hw_addr_fake, ", perm-hw-addr-fake=", perm_hw_addr_fake, "", ""), + generic_sw ? ", generic-software" : "", route_metric_default_aspired, route_metric_default_effective, NM_PRINT_FMT_QUOTED(next_server, ", next-server=", next_server, "", ""), diff --git a/src/core/nm-config.h b/src/core/nm-config.h index acec8d05cd..e65582c34a 100644 --- a/src/core/nm-config.h +++ b/src/core/nm-config.h @@ -176,6 +176,8 @@ struct _NMConfigDeviceStateData { /* whether the device was nm-owned (0/1) or -1 for * non-software devices. */ NMTernary nm_owned : 3; + /* whether the device is a generic one created by NM */ + bool generic_sw : 1; }; NMConfigDeviceStateData *nm_config_device_state_load(int ifindex); @@ -188,7 +190,8 @@ gboolean nm_config_device_state_write(int guint32 route_metric_default_aspired, guint32 route_metric_default_effective, NMDhcpConfig *dhcp4_config, - NMDhcpConfig *dhcp6_config); + NMDhcpConfig *dhcp6_config, + gboolean generic); void nm_config_device_state_prune_stale(GHashTable *preserve_ifindexes, NMPlatform *preserve_in_platform); diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c index 2cf9cb1ddf..9284ae8c43 100644 --- a/src/core/nm-manager.c +++ b/src/core/nm-manager.c @@ -4213,8 +4213,12 @@ platform_link_added(NMManager *self, } add: - /* Try registered device factories */ - factory = nm_device_factory_manager_find_factory_for_link_type(plink->type); + if (dev_state && dev_state->generic_sw) { + factory = nm_device_factory_get_generic_factory(); + } else { + /* Try registered device factories */ + factory = nm_device_factory_manager_find_factory_for_link_type(plink->type); + } if (factory) { gboolean ignore = FALSE; gs_free_error GError *error = NULL; @@ -7860,7 +7864,10 @@ nm_manager_write_device_state(NMManager *self, NMDevice *device, int *out_ifinde route_metric_default_aspired, route_metric_default_effective, nm_device_get_dhcp_config(device, AF_INET), - nm_device_get_dhcp_config(device, AF_INET6))) + nm_device_get_dhcp_config(device, AF_INET6), + nm_device_is_software(device) + && nm_device_get_device_type(device) + == NM_DEVICE_TYPE_GENERIC)) return FALSE; NM_SET_OUT(out_ifindex, ifindex); |