mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-07-22 02:35:25 +00:00
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.
This commit is contained in:
parent
df6c35ec75
commit
f2613be150
|
@ -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
|
||||
|
@ -184,6 +189,12 @@ static void __attribute__((destructor)) _cleanup(void)
|
|||
nm_clear_pointer(&factories_by_setting, g_hash_table_unref);
|
||||
}
|
||||
|
||||
NMDeviceFactory *
|
||||
nm_device_factory_get_generic_factory(void)
|
||||
{
|
||||
return generic_factory;
|
||||
}
|
||||
|
||||
NMDeviceFactory *
|
||||
nm_device_factory_manager_find_factory_for_link_type(NMLinkType link_type)
|
||||
{
|
||||
|
@ -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
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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, "", ""),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue