summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2023-11-21 14:57:17 +0100
committerÍñigo Huguet <ihuguet@redhat.com>2024-02-21 11:49:20 +0100
commit3bb34edc5331f9ffafac5ca45ba07adbcc0ae071 (patch)
tree24cbc2dfa8534501dbc0b42f59dbd6c08326faf0
parentf8e020c29eb7f166b2a7aad54f49e9ea4172a2a0 (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.c16
-rw-r--r--src/core/devices/nm-device-factory.h2
-rw-r--r--src/core/nm-config.c29
-rw-r--r--src/core/nm-config.h5
-rw-r--r--src/core/nm-manager.c13
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);