diff --git a/introspection/org.freedesktop.NetworkManager.Device.xml b/introspection/org.freedesktop.NetworkManager.Device.xml index fe30fb884c..ce2fa2cc71 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 20bd8f253a..1474ae715e 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 6d7b38fc3f..41b31af07e 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -14942,16 +14942,67 @@ 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) { - gboolean old; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + gboolean managed_old; + NMTernary managed_to_disk_old; - g_object_get(self, NM_DEVICE_MANAGED, &old, NULL); - g_object_set(self, NM_DEVICE_MANAGED, managed, NULL); - g_object_get(self, NM_DEVICE_MANAGED, &managed, NULL); - if (old != managed) - _notify(self, PROP_MANAGED); + if (flags & NM_DEVICE_MANAGED_FLAGS_PERMANENT) { + 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, + 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, + 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; + } + } + + if (flags & NM_DEVICE_MANAGED_FLAGS_RUNTIME) { + 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 (managed_old != managed) + _notify(self, PROP_MANAGED); + } return TRUE; } diff --git a/src/libnm-core-public/nm-dbus-interface.h b/src/libnm-core-public/nm-dbus-interface.h index 475b2f7dc1..f9992cf297 100644 --- a/src/libnm-core-public/nm-dbus-interface.h +++ b/src/libnm-core-public/nm-dbus-interface.h @@ -1248,13 +1248,20 @@ 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. * * 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_RUNTIME = 0x1, + NM_DEVICE_MANAGED_FLAGS_PERMANENT = 0x2, + NM_DEVICE_MANAGED_FLAGS_BY_MAC = 0x4, } NMDeviceManagedFlags; /**