mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-25 07:10:39 +01:00
core: config: implement storing to disk for Device.SetManaged()
If NM_DEVICE_MANAGED_FLAGS_TO_DISK is passed, add an [.intern.device-ifname] section to NetworkManager-intern.conf so it is persisted across reboots. Allow also to clear previously stored configurations by passing NM_DEVICE_MANAGED_FLAGS_CLEAR_DISK.
This commit is contained in:
parent
9f256c3e86
commit
528356a4b2
7 changed files with 202 additions and 7 deletions
|
|
@ -397,10 +397,12 @@
|
|||
<!--
|
||||
SetManaged:
|
||||
@managed: Whether the device is managed.
|
||||
@flags: Flags which would modify the behavior of the SetManaged call. Invalid flags are rejected.
|
||||
@flags: (<link linkend="NMDeviceManagedFlags">NMDeviceManagedFlags</link>) flags.
|
||||
@since: 1.58
|
||||
|
||||
Set the managed state of the device.
|
||||
Set the managed state of the device. With the flags argument different
|
||||
behaviors can be achieved, like storing the new managed state to disk or
|
||||
clearing previous managed state from disk.
|
||||
-->
|
||||
<method name="SetManaged">
|
||||
<arg name="managed" type="b" direction="in"/>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ src/core/NetworkManagerUtils.c
|
|||
src/core/devices/adsl/nm-device-adsl.c
|
||||
src/core/devices/bluetooth/nm-bluez-manager.c
|
||||
src/core/devices/bluetooth/nm-device-bt.c
|
||||
src/core/devices/nm-device.c
|
||||
src/core/devices/nm-device-6lowpan.c
|
||||
src/core/devices/nm-device-bond.c
|
||||
src/core/devices/nm-device-bridge.c
|
||||
|
|
|
|||
|
|
@ -14943,15 +14943,71 @@ typedef struct {
|
|||
NMDeviceManagedFlags managed_flags;
|
||||
} SetManagedData;
|
||||
|
||||
/**
|
||||
* set_managed:
|
||||
* @self: the device
|
||||
* @managed: the new managed state to set.
|
||||
* @flags: flags to select different behaviors like storing to disk.
|
||||
* @error: return location for a #GError, or %NULL
|
||||
*
|
||||
* Sets the managed state of the device. If the %NM_DEVICE_MANAGED_FLAGS_TO_DISK
|
||||
* flag is set, the new state will be persisted to disk so it will be restored
|
||||
* after a reboot. If the %NM_DEVICE_MANAGED_FLAGS_CLEAR_DISK flag is set, the
|
||||
* managed flag will be cleared from disk.
|
||||
*
|
||||
* Returns: %TRUE if the managed state was set successfully, %FALSE otherwise.
|
||||
*/
|
||||
static gboolean
|
||||
set_managed(NMDevice *self, gboolean managed, NMDeviceManagedFlags flags, GError **error)
|
||||
{
|
||||
gboolean old;
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
|
||||
gboolean managed_old;
|
||||
NMTernary managed_to_disk, managed_to_disk_old;
|
||||
|
||||
g_object_get(self, NM_DEVICE_MANAGED, &old, NULL);
|
||||
g_object_set(self, NM_DEVICE_MANAGED, managed, NULL);
|
||||
if (flags & NM_DEVICE_MANAGED_FLAGS_CLEAR_DISK)
|
||||
flags |= NM_DEVICE_MANAGED_FLAGS_TO_DISK;
|
||||
|
||||
if (flags & NM_DEVICE_MANAGED_FLAGS_TO_DISK) {
|
||||
managed_to_disk = flags & NM_DEVICE_MANAGED_FLAGS_CLEAR_DISK ? NM_TERNARY_DEFAULT : managed;
|
||||
|
||||
managed_to_disk_old = nm_config_get_device_managed(nm_manager_get_config(priv->manager),
|
||||
nm_device_get_iface(self));
|
||||
|
||||
if (!nm_config_set_device_managed(nm_manager_get_config(priv->manager),
|
||||
self,
|
||||
managed_to_disk,
|
||||
flags & NM_DEVICE_MANAGED_FLAGS_BY_MAC,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
/* Update the unmanaged flags after the change on disk */
|
||||
nm_device_set_unmanaged_by_user_conf(self);
|
||||
|
||||
if (!(flags & NM_DEVICE_MANAGED_FLAGS_CLEAR_DISK)
|
||||
&& !!nm_device_get_unmanaged_flags(self, NM_UNMANAGED_USER_CONF) != !managed) {
|
||||
/* We failed to make the new state effective on disk. Maybe the new config
|
||||
* collides with other config. Try to revert and return error. Otherwise,
|
||||
* we would set the runtime state correctly, but get an unexpected state
|
||||
* after a reboot. */
|
||||
nm_config_set_device_managed(nm_manager_get_config(priv->manager),
|
||||
self,
|
||||
managed_to_disk_old,
|
||||
flags & NM_DEVICE_MANAGED_FLAGS_BY_MAC,
|
||||
error);
|
||||
g_set_error(error,
|
||||
NM_DEVICE_ERROR,
|
||||
NM_DEVICE_ERROR_FAILED,
|
||||
_("failed to persist 'managed=%d' on disk, other configurations may be "
|
||||
"overriding it"),
|
||||
managed);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
g_object_get(self, NM_DEVICE_MANAGED, &managed_old, NULL);
|
||||
g_object_set(self, NM_DEVICE_MANAGED, !!managed, NULL);
|
||||
g_object_get(self, NM_DEVICE_MANAGED, &managed, NULL);
|
||||
if (old != managed)
|
||||
if (managed_old != managed)
|
||||
_notify(self, PROP_MANAGED);
|
||||
|
||||
return TRUE;
|
||||
|
|
|
|||
|
|
@ -2076,6 +2076,121 @@ nm_config_set_connectivity_check_enabled(NMConfig *self, gboolean enabled)
|
|||
g_key_file_unref(keyfile);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* nm_config_get_device_managed:
|
||||
* @self: the NMConfig instance
|
||||
* @ifname: the interface name
|
||||
*
|
||||
* Returns: the current managed state of the device in the intern keyfile. If it
|
||||
* is not set or it's invalid, returns %NM_TERNARY_DEFAULT.
|
||||
*/
|
||||
NMTernary
|
||||
nm_config_get_device_managed(NMConfig *self, const char *ifname)
|
||||
{
|
||||
NMConfigPrivate *priv;
|
||||
const GKeyFile *keyfile = NULL;
|
||||
gs_free char *group = NULL;
|
||||
|
||||
g_return_val_if_fail(NM_IS_CONFIG(self), FALSE);
|
||||
g_return_val_if_fail(NM_CONFIG_GET_PRIVATE(self)->config_data, FALSE);
|
||||
g_return_val_if_fail(ifname, FALSE);
|
||||
|
||||
priv = NM_CONFIG_GET_PRIVATE(self);
|
||||
keyfile = _nm_config_data_get_keyfile_intern(priv->config_data);
|
||||
group = g_strdup_printf(NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_DEVICE "-%s", ifname);
|
||||
|
||||
if (!keyfile)
|
||||
return NM_TERNARY_DEFAULT;
|
||||
|
||||
return (NMTernary) nm_config_keyfile_get_boolean(keyfile,
|
||||
group,
|
||||
NM_CONFIG_KEYFILE_KEY_DEVICE_MANAGED,
|
||||
NM_TERNARY_DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_config_set_device_managed:
|
||||
* @self: the NMConfig instance
|
||||
* @device: the NMDevice instance associated with this config change
|
||||
* @ifname: the interface name
|
||||
* @hwaddr: the hardware address
|
||||
* @managed: the managed state to set
|
||||
* @by_mac: if %TRUE, match by MAC address, otherwise by interface name. This is
|
||||
* only used when @managed = TRUE.
|
||||
* @error: return location for a #GError, or %NULL
|
||||
*
|
||||
* Sets the managed state of the device to the intern keyfile. Here we store the
|
||||
* configuration received via the D-Bus API. Configurations from other config
|
||||
* files are still in place and may have higher precedence.
|
||||
*
|
||||
* Prior to setting the new state, the existing configuration is removed. If
|
||||
* @managed is set to %NM_TERNARY_DEFAULT, we only do the removal of the previous
|
||||
* configuration.
|
||||
*/
|
||||
gboolean
|
||||
nm_config_set_device_managed(NMConfig *self,
|
||||
NMDevice *device,
|
||||
NMTernary managed,
|
||||
gboolean by_mac,
|
||||
GError **error)
|
||||
{
|
||||
NMConfigPrivate *priv;
|
||||
g_autoptr(GKeyFile) keyfile = NULL;
|
||||
gs_free char *group_by_name = NULL;
|
||||
gs_free char *group_by_mac = NULL;
|
||||
gs_free char *match_value = NULL;
|
||||
gboolean changed = FALSE;
|
||||
const char *ifname = nm_device_get_iface(device);
|
||||
const char *hwaddr = nm_device_get_permanent_hw_address(device);
|
||||
|
||||
g_return_val_if_fail(NM_IS_CONFIG(self), FALSE);
|
||||
g_return_val_if_fail(NM_CONFIG_GET_PRIVATE(self)->config_data, FALSE);
|
||||
g_return_val_if_fail(ifname && hwaddr, FALSE);
|
||||
|
||||
priv = NM_CONFIG_GET_PRIVATE(self);
|
||||
keyfile = nm_config_data_clone_keyfile_intern(priv->config_data);
|
||||
group_by_name = g_strdup_printf(NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_DEVICE "-%s", ifname);
|
||||
group_by_mac =
|
||||
g_strdup_printf(NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_DEVICE ".by-mac.%s", hwaddr);
|
||||
|
||||
/* Remove existing configs. Search them by group name [.intern.device-*] or [.intern.device.by-mac.*]. In
|
||||
* the intern file, 'device' sections are only used for this purpose, so we won't remove
|
||||
* any other device's config. */
|
||||
if (g_key_file_remove_group(keyfile, group_by_name, NULL)
|
||||
|| g_key_file_remove_group(keyfile, group_by_mac, NULL))
|
||||
changed = TRUE;
|
||||
|
||||
/* If the new state is not explicitly TRUE of FALSE, we only remove the configs */
|
||||
if (managed == NM_TERNARY_DEFAULT)
|
||||
goto done;
|
||||
|
||||
/* Set new values */
|
||||
if (by_mac)
|
||||
match_value = g_strdup_printf("mac:%s", hwaddr);
|
||||
else
|
||||
match_value = g_strdup_printf("interface-name:=%s", ifname);
|
||||
|
||||
g_key_file_set_value(keyfile,
|
||||
by_mac ? group_by_mac : group_by_name,
|
||||
NM_CONFIG_KEYFILE_KEY_MATCH_DEVICE,
|
||||
match_value);
|
||||
g_key_file_set_value(keyfile,
|
||||
by_mac ? group_by_mac : group_by_name,
|
||||
NM_CONFIG_KEYFILE_KEY_DEVICE_MANAGED,
|
||||
managed ? "1" : "0");
|
||||
changed = TRUE;
|
||||
|
||||
done:
|
||||
if (changed)
|
||||
nm_config_set_values(self, keyfile, TRUE, FALSE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* nm_config_set_values:
|
||||
* @self: the NMConfig instance
|
||||
|
|
|
|||
|
|
@ -142,6 +142,13 @@ gboolean nm_config_set_global_dns(NMConfig *self, NMGlobalDnsConfig *global_dns,
|
|||
|
||||
void nm_config_set_connectivity_check_enabled(NMConfig *self, gboolean enabled);
|
||||
|
||||
NMTernary nm_config_get_device_managed(NMConfig *self, const char *ifname);
|
||||
gboolean nm_config_set_device_managed(NMConfig *self,
|
||||
NMDevice *device,
|
||||
NMTernary managed,
|
||||
gboolean by_mac,
|
||||
GError **error);
|
||||
|
||||
/* internal defines ... */
|
||||
extern guint _nm_config_match_nm_version;
|
||||
extern char *_nm_config_match_env;
|
||||
|
|
|
|||
|
|
@ -90,4 +90,7 @@
|
|||
#define NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_GLOBAL_DNS_DOMAIN \
|
||||
NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN NM_CONFIG_KEYFILE_GROUPPREFIX_GLOBAL_DNS_DOMAIN
|
||||
|
||||
#define NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_DEVICE \
|
||||
NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE
|
||||
|
||||
#endif /* __NM_CONFIG_BASE_H__ */
|
||||
|
|
|
|||
|
|
@ -1251,13 +1251,24 @@ typedef enum /*< flags >*/ {
|
|||
/**
|
||||
* NMDeviceManagedFlags:
|
||||
* @NM_DEVICE_MANAGED_FLAGS_NONE: no flag set.
|
||||
* @NM_DEVICE_MANAGED_FLAGS_TO_DISK: to also persist the device managed state to disk.
|
||||
* @NM_DEVICE_MANAGED_FLAGS_BY_MAC: to match the device by MAC address, not by name.
|
||||
* This option only makes sense together with %NM_DEVICE_MANAGED_FLAGS_TO_DISK.
|
||||
* @NM_DEVICE_MANAGED_FLAGS_CLEAR_DISK: to clear the managed flag from disk.
|
||||
* If set, the other flags and the 'managed' argument are ignored.
|
||||
* @NM_DEVICE_MANAGED_FLAGS_SET_ADMIN_STATE: to set the administrative state of the
|
||||
* device to up if the managed state is TRUE, and down if the managed state is FALSE.
|
||||
* If the flag is not set, the administrative state is not changed.
|
||||
*
|
||||
* Flags for the SetManaged() D-Bus call of a device and nm_device_set_managed_async().
|
||||
*
|
||||
* Since: 1.58
|
||||
*/
|
||||
typedef enum /*< flags >*/ {
|
||||
NM_DEVICE_MANAGED_FLAGS_NONE = 0,
|
||||
NM_DEVICE_MANAGED_FLAGS_NONE = 0,
|
||||
NM_DEVICE_MANAGED_FLAGS_TO_DISK = 0x1,
|
||||
NM_DEVICE_MANAGED_FLAGS_BY_MAC = 0x2,
|
||||
NM_DEVICE_MANAGED_FLAGS_CLEAR_DISK = 0x4,
|
||||
} NMDeviceManagedFlags;
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue