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 f2613be150
)
This commit is contained in:

committed by
Íñigo Huguet

parent
f8e020c29e
commit
3bb34edc53
@@ -28,6 +28,10 @@ G_DEFINE_ABSTRACT_TYPE(NMDeviceFactory, nm_device_factory, G_TYPE_OBJECT)
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static NMDeviceFactory *generic_factory;
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nm_device_factory_get_supported_types(NMDeviceFactory *factory,
|
nm_device_factory_get_supported_types(NMDeviceFactory *factory,
|
||||||
const NMLinkType **out_link_types,
|
const NMLinkType **out_link_types,
|
||||||
@@ -66,7 +70,8 @@ nm_device_factory_create_device(NMDeviceFactory *factory,
|
|||||||
if (plink) {
|
if (plink) {
|
||||||
g_return_val_if_fail(!connection, NULL);
|
g_return_val_if_fail(!connection, NULL);
|
||||||
g_return_val_if_fail(strcmp(iface, plink->name) == 0, 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)
|
} else if (connection)
|
||||||
nm_assert(factory == nm_device_factory_manager_find_factory_for_connection(connection));
|
nm_assert(factory == nm_device_factory_manager_find_factory_for_connection(connection));
|
||||||
else
|
else
|
||||||
@@ -184,6 +189,12 @@ static void __attribute__((destructor)) _cleanup(void)
|
|||||||
nm_clear_pointer(&factories_by_setting, g_hash_table_unref);
|
nm_clear_pointer(&factories_by_setting, g_hash_table_unref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NMDeviceFactory *
|
||||||
|
nm_device_factory_get_generic_factory(void)
|
||||||
|
{
|
||||||
|
return generic_factory;
|
||||||
|
}
|
||||||
|
|
||||||
NMDeviceFactory *
|
NMDeviceFactory *
|
||||||
nm_device_factory_manager_find_factory_for_link_type(NMLinkType link_type)
|
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)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
gs_unref_object NMDeviceFactory *factory = NULL;
|
gs_unref_object NMDeviceFactory *factory = NULL;
|
||||||
|
GType nm_generic_device_factory_get_type(void);
|
||||||
|
|
||||||
factory = g_object_new(factory_gtype, NULL);
|
factory = g_object_new(factory_gtype, NULL);
|
||||||
_add_factory(factory, NULL, callback, user_data);
|
_add_factory(factory, NULL, callback, user_data);
|
||||||
|
if (factory_gtype == nm_generic_device_factory_get_type())
|
||||||
|
generic_factory = factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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,
|
void nm_device_factory_manager_for_each_factory(NMDeviceFactoryManagerFactoryFunc callback,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
|
NMDeviceFactory *nm_device_factory_get_generic_factory(void);
|
||||||
|
|
||||||
#endif /* __NETWORKMANAGER_DEVICE_FACTORY_H__ */
|
#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"
|
"route-metric-default-aspired"
|
||||||
#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_ROUTE_METRIC_DEFAULT_EFFECTIVE \
|
#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_ROUTE_METRIC_DEFAULT_EFFECTIVE \
|
||||||
"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_ROOT_PATH "root-path"
|
||||||
#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_NEXT_SERVER "next-server"
|
#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_DHCP_BOOTFILE "dhcp-bootfile"
|
||||||
|
#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_GENERIC_SOFTWARE "generic-software"
|
||||||
|
|
||||||
static NM_UTILS_LOOKUP_STR_DEFINE(
|
static NM_UTILS_LOOKUP_STR_DEFINE(
|
||||||
_device_state_managed_type_to_str,
|
_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_aspired = route_metric_default_aspired;
|
||||||
device_state->route_metric_default_effective = route_metric_default_effective;
|
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]);
|
p = (char *) (&device_state[1]);
|
||||||
if (connection_uuid) {
|
if (connection_uuid) {
|
||||||
memcpy(p, connection_uuid, connection_uuid_len);
|
memcpy(p, connection_uuid, connection_uuid_len);
|
||||||
@@ -2502,7 +2509,7 @@ nm_config_device_state_load(int ifindex)
|
|||||||
? ", nm-owned=1"
|
? ", nm-owned=1"
|
||||||
: (device_state->nm_owned == NM_TERNARY_FALSE ? ", nm-owned=0" : "");
|
: (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 "",
|
"route-metric-default=%" G_GUINT32_FORMAT "-%" G_GUINT32_FORMAT "",
|
||||||
kf ? "read" : "miss",
|
kf ? "read" : "miss",
|
||||||
ifindex,
|
ifindex,
|
||||||
@@ -2519,6 +2526,7 @@ nm_config_device_state_load(int ifindex)
|
|||||||
"",
|
"",
|
||||||
""),
|
""),
|
||||||
nm_owned_str,
|
nm_owned_str,
|
||||||
|
device_state->generic_sw ? ", generic-software" : "",
|
||||||
device_state->route_metric_default_aspired,
|
device_state->route_metric_default_aspired,
|
||||||
device_state->route_metric_default_effective);
|
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_aspired,
|
||||||
guint32 route_metric_default_effective,
|
guint32 route_metric_default_effective,
|
||||||
NMDhcpConfig *dhcp4_config,
|
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];
|
char path[NM_STRLEN(NM_CONFIG_DEVICE_STATE_DIR "/") + DEVICE_STATE_FILENAME_LEN_MAX + 1];
|
||||||
GError *local = NULL;
|
GError *local = NULL;
|
||||||
@@ -2664,6 +2673,13 @@ nm_config_device_state_write(int ifindex,
|
|||||||
dhcp_bootfile);
|
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--) {
|
for (IS_IPv4 = 1; IS_IPv4 >= 0; IS_IPv4--) {
|
||||||
NMDhcpConfig *dhcp_config = IS_IPv4 ? dhcp4_config : dhcp6_config;
|
NMDhcpConfig *dhcp_config = IS_IPv4 ? dhcp4_config : dhcp6_config;
|
||||||
gs_free NMUtilsNamedValue *values = NULL;
|
gs_free NMUtilsNamedValue *values = NULL;
|
||||||
@@ -2691,7 +2707,7 @@ nm_config_device_state_write(int ifindex,
|
|||||||
g_error_free(local);
|
g_error_free(local);
|
||||||
return FALSE;
|
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"
|
"route-metric-default=%" G_GUINT32_FORMAT "-%" G_GUINT32_FORMAT "%s%s%s"
|
||||||
"%s%s%s"
|
"%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),
|
_device_state_managed_type_to_str(managed),
|
||||||
NM_PRINT_FMT_QUOTED(connection_uuid, ", connection-uuid=", connection_uuid, "", ""),
|
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, "", ""),
|
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_aspired,
|
||||||
route_metric_default_effective,
|
route_metric_default_effective,
|
||||||
NM_PRINT_FMT_QUOTED(next_server, ", next-server=", next_server, "", ""),
|
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
|
/* whether the device was nm-owned (0/1) or -1 for
|
||||||
* non-software devices. */
|
* non-software devices. */
|
||||||
NMTernary nm_owned : 3;
|
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);
|
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_aspired,
|
||||||
guint32 route_metric_default_effective,
|
guint32 route_metric_default_effective,
|
||||||
NMDhcpConfig *dhcp4_config,
|
NMDhcpConfig *dhcp4_config,
|
||||||
NMDhcpConfig *dhcp6_config);
|
NMDhcpConfig *dhcp6_config,
|
||||||
|
gboolean generic);
|
||||||
|
|
||||||
void nm_config_device_state_prune_stale(GHashTable *preserve_ifindexes,
|
void nm_config_device_state_prune_stale(GHashTable *preserve_ifindexes,
|
||||||
NMPlatform *preserve_in_platform);
|
NMPlatform *preserve_in_platform);
|
||||||
|
@@ -4213,8 +4213,12 @@ platform_link_added(NMManager *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
add:
|
add:
|
||||||
/* Try registered device factories */
|
if (dev_state && dev_state->generic_sw) {
|
||||||
factory = nm_device_factory_manager_find_factory_for_link_type(plink->type);
|
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) {
|
if (factory) {
|
||||||
gboolean ignore = FALSE;
|
gboolean ignore = FALSE;
|
||||||
gs_free_error GError *error = NULL;
|
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_aspired,
|
||||||
route_metric_default_effective,
|
route_metric_default_effective,
|
||||||
nm_device_get_dhcp_config(device, AF_INET),
|
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;
|
return FALSE;
|
||||||
|
|
||||||
NM_SET_OUT(out_ifindex, ifindex);
|
NM_SET_OUT(out_ifindex, ifindex);
|
||||||
|
Reference in New Issue
Block a user