diff --git a/introspection/org.freedesktop.NetworkManager.Device.xml b/introspection/org.freedesktop.NetworkManager.Device.xml index 684134835a..802ee2fd68 100644 --- a/introspection/org.freedesktop.NetworkManager.Device.xml +++ b/introspection/org.freedesktop.NetworkManager.Device.xml @@ -397,10 +397,11 @@ diff --git a/po/POTFILES.in b/po/POTFILES.in index b66ca45263..605683df42 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.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 diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 22a9b55e3c..cf8a5d22f5 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -14943,12 +14943,72 @@ 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. It can affect the runtime managed state + * if the %NM_DEVICE_MANAGED_FLAGS_RUNTIME is set, and to the value stored on disk + * (persistent across reboots) state if the %NM_DEVICE_MANAGED_FLAGS_PERMANENT is set. + * + * Returns: %TRUE if the managed state was set successfully, %FALSE otherwise. + */ static gboolean set_managed(NMDevice *self, gboolean managed, NMDeviceManagedFlags flags, GError **error) { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMTernary old; + nm_assert((flags & ~NM_DEVICE_MANAGED_FLAGS_ALL) == 0); - g_object_set(self, NM_DEVICE_MANAGED, managed, NULL); + if (!NM_FLAGS_ANY(flags, NM_DEVICE_MANAGED_FLAGS_PERMANENT | NM_DEVICE_MANAGED_FLAGS_RUNTIME)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_ARGUMENT, + _("set managed: no permanent or runtime was selected")); + return FALSE; + } + + if (flags & NM_DEVICE_MANAGED_FLAGS_PERMANENT) { + if (!nm_config_get_device_managed(nm_manager_get_config(priv->manager), self, &old, error)) + return FALSE; + + if (!nm_config_set_device_managed(nm_manager_get_config(priv->manager), + self, + managed, + 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 (!!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, + old, + flags & NM_DEVICE_MANAGED_FLAGS_BY_MAC, + NULL); + 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; + } + } + + if (flags & NM_DEVICE_MANAGED_FLAGS_RUNTIME) { + g_object_set(self, NM_DEVICE_MANAGED, !!managed, NULL); + } return TRUE; } diff --git a/src/libnm-core-public/nm-dbus-interface.h b/src/libnm-core-public/nm-dbus-interface.h index 1ead6f4adc..d2ee1d86c6 100644 --- a/src/libnm-core-public/nm-dbus-interface.h +++ b/src/libnm-core-public/nm-dbus-interface.h @@ -1251,6 +1251,10 @@ typedef enum /*< flags >*/ { /** * NMDeviceManagedFlags: * @NM_DEVICE_MANAGED_FLAGS_NONE: no flag set. + * @NM_DEVICE_MANAGED_FLAGS_RUNTIME: to set the device managed state to the runtime value. + * @NM_DEVICE_MANAGED_FLAGS_PERMANENT: to set the device managed state to the permanent (on disk) value. + * @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_PERMANENT. * @NM_DEVICE_MANAGED_FLAGS_ALL: all flags. * * Flags for the SetManaged() D-Bus call of a device and nm_device_set_managed_async(). @@ -1258,9 +1262,12 @@ typedef enum /*< flags >*/ { * Since: 1.58 */ typedef enum /*< flags >*/ { - NM_DEVICE_MANAGED_FLAGS_NONE = 0, + NM_DEVICE_MANAGED_FLAGS_NONE = 0, + NM_DEVICE_MANAGED_FLAGS_RUNTIME = 0x1, + NM_DEVICE_MANAGED_FLAGS_PERMANENT = 0x2, + NM_DEVICE_MANAGED_FLAGS_BY_MAC = 0x4, - NM_DEVICE_MANAGED_FLAGS_ALL = 0, /* */ + NM_DEVICE_MANAGED_FLAGS_ALL = 0x7, /* */ } NMDeviceManagedFlags; /**