From 36dc5305d2cf2c0a9037f7dd5d6a452f85f3cbfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= Date: Mon, 23 Feb 2026 16:02:49 +0100 Subject: [PATCH] core: device: allow to reset the managed property Previous commits added the capability to persist to disk the value of 'managed' received via the D-Bus API. Users might need to clear the previous content, thus reseting it to its default. Although this is specially useful for the PERMANENT flag, we need to be consistent and reset the runtime state too. (cherry picked from commit f346fcf977c22f12b509fff3c674dbfb67490a38) (cherry picked from commit 82a586454bf5f4691969922b4fffb42f37cab527) --- .../org.freedesktop.NetworkManager.Device.xml | 4 +- src/core/devices/nm-device.c | 56 +++++++++++++------ src/libnm-client-impl/libnm.ver | 1 + src/libnm-client-impl/nm-device.c | 4 +- src/libnm-client-public/nm-device.h | 2 +- src/libnm-core-public/nm-dbus-interface.h | 16 ++++++ 6 files changed, 61 insertions(+), 22 deletions(-) diff --git a/introspection/org.freedesktop.NetworkManager.Device.xml b/introspection/org.freedesktop.NetworkManager.Device.xml index 0bc118b1ef..21b6711909 100644 --- a/introspection/org.freedesktop.NetworkManager.Device.xml +++ b/introspection/org.freedesktop.NetworkManager.Device.xml @@ -396,7 +396,7 @@ - + diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 8e0abf45ad..13b44a3816 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -14817,7 +14817,7 @@ impl_device_get_applied_connection(NMDBusObject *obj, /*****************************************************************************/ typedef struct { - gboolean managed_state; + NMDeviceManaged managed_state; NMDeviceManagedFlags managed_flags; } SetManagedData; @@ -14835,11 +14835,13 @@ typedef struct { * Returns: %TRUE if the managed state was set successfully, %FALSE otherwise. */ static gboolean -set_managed(NMDevice *self, gboolean managed, NMDeviceManagedFlags flags, GError **error) +set_managed(NMDevice *self, NMDeviceManaged managed, NMDeviceManagedFlags flags, GError **error) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - NMTernary old = NM_TERNARY_DEFAULT; + NMTernary managed_to_disk, old = NM_TERNARY_DEFAULT; + nm_assert( + NM_IN_SET(managed, NM_DEVICE_MANAGED_NO, NM_DEVICE_MANAGED_YES, NM_DEVICE_MANAGED_RESET)); nm_assert((flags & ~NM_DEVICE_MANAGED_FLAGS_ALL) == 0); if (!NM_FLAGS_ANY(flags, NM_DEVICE_MANAGED_FLAGS_PERMANENT | NM_DEVICE_MANAGED_FLAGS_RUNTIME)) { @@ -14851,11 +14853,12 @@ set_managed(NMDevice *self, gboolean managed, NMDeviceManagedFlags flags, GError } if (flags & NM_DEVICE_MANAGED_FLAGS_PERMANENT) { + managed_to_disk = managed == NM_DEVICE_MANAGED_RESET ? NM_TERNARY_DEFAULT : !!managed; nm_config_get_device_managed(nm_manager_get_config(priv->manager), self, &old, error); if (!nm_config_set_device_managed(nm_manager_get_config(priv->manager), self, - managed, + managed_to_disk, flags & NM_DEVICE_MANAGED_FLAGS_BY_MAC, error)) return FALSE; @@ -14863,7 +14866,8 @@ set_managed(NMDevice *self, gboolean managed, NMDeviceManagedFlags flags, GError /* 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) { + if (managed_to_disk != NM_TERNARY_DEFAULT + && managed_to_disk != !nm_device_get_unmanaged_flags(self, NM_UNMANAGED_USER_CONF)) { /* 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 @@ -14884,7 +14888,14 @@ set_managed(NMDevice *self, gboolean managed, NMDeviceManagedFlags flags, GError } if (flags & NM_DEVICE_MANAGED_FLAGS_RUNTIME) { - g_object_set(self, NM_DEVICE_MANAGED, !!managed, NULL); + if (managed == NM_DEVICE_MANAGED_RESET) { + nm_device_set_unmanaged_by_flags(self, + NM_UNMANAGED_USER_EXPLICIT, + NM_UNMAN_FLAG_OP_FORGET, + NM_DEVICE_STATE_REASON_UNMANAGED_USER_EXPLICIT); + } else { + g_object_set(self, NM_DEVICE_MANAGED, !!managed, NULL); + } } return TRUE; @@ -14898,7 +14909,7 @@ set_managed_cb(NMDevice *self, gpointer user_data) { SetManagedData *set_managed_data = user_data; - gboolean managed; + NMDeviceManaged managed; NMDeviceManagedFlags flags; GError *local = NULL; @@ -14906,11 +14917,20 @@ set_managed_cb(NMDevice *self, flags = set_managed_data->managed_flags; nm_g_slice_free(set_managed_data); - if (!error && (flags & ~NM_DEVICE_MANAGED_FLAGS_ALL) != 0) { - g_set_error_literal(&error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_ARGUMENT, - "Invalid flags"); + if (!error) { + if (!NM_IN_SET(managed, + NM_DEVICE_MANAGED_NO, + NM_DEVICE_MANAGED_YES, + NM_DEVICE_MANAGED_RESET)) + g_set_error_literal(&error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_ARGUMENT, + "Invalid managed value"); + else if ((flags & ~NM_DEVICE_MANAGED_FLAGS_ALL) != 0) + g_set_error_literal(&error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_ARGUMENT, + "Invalid flags"); } if (error) { @@ -14950,15 +14970,17 @@ impl_device_set_managed(NMDBusObject *obj, { NMDevice *self = NM_DEVICE(obj); gs_free_error GError *error = NULL; - gboolean managed; + guint32 managed_u; + NMDeviceManaged managed; guint32 flags_u; NMDeviceManagedFlags flags; SetManagedData *set_managed_data; - g_variant_get(parameters, "(bu)", &managed, &flags_u); + g_variant_get(parameters, "(uu)", &managed_u, &flags_u); - flags = flags_u; - nm_assert(flags == flags_u); + managed = managed_u; + flags = flags_u; + nm_assert(managed == managed_u && flags == flags_u); set_managed_data = g_slice_new(SetManagedData); *set_managed_data = (SetManagedData) { @@ -19994,7 +20016,7 @@ static const NMDBusInterfaceInfoExtended interface_info_device = { NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( NM_DEFINE_GDBUS_METHOD_INFO_INIT("SetManaged", .in_args = NM_DEFINE_GDBUS_ARG_INFOS( - NM_DEFINE_GDBUS_ARG_INFO("managed", "b"), + NM_DEFINE_GDBUS_ARG_INFO("managed", "u"), NM_DEFINE_GDBUS_ARG_INFO("flags", "u"), ), ), .handle = impl_device_set_managed, ), NM_DEFINE_DBUS_METHOD_INFO_EXTENDED(NM_DEFINE_GDBUS_METHOD_INFO_INIT("Disconnect", ), diff --git a/src/libnm-client-impl/libnm.ver b/src/libnm-client-impl/libnm.ver index 2a60cbfda1..4edf71b153 100644 --- a/src/libnm-client-impl/libnm.ver +++ b/src/libnm-client-impl/libnm.ver @@ -2106,6 +2106,7 @@ global: nm_device_geneve_get_ttl; nm_device_geneve_get_type; nm_device_managed_flags_get_type; + nm_device_managed_get_type; nm_device_set_managed_async; nm_device_set_managed_finish; nm_setting_geneve_df_get_type; diff --git a/src/libnm-client-impl/nm-device.c b/src/libnm-client-impl/nm-device.c index 4de2cda102..46440286f9 100644 --- a/src/libnm-client-impl/nm-device.c +++ b/src/libnm-client-impl/nm-device.c @@ -1485,7 +1485,7 @@ nm_device_set_managed(NMDevice *device, gboolean managed) **/ void nm_device_set_managed_async(NMDevice *device, - gboolean managed, + NMDeviceManaged managed, NMDeviceManagedFlags flags, GCancellable *cancellable, GAsyncReadyCallback callback, @@ -1503,7 +1503,7 @@ nm_device_set_managed_async(NMDevice *device, _nm_object_get_path(device), NM_DBUS_INTERFACE_DEVICE, "SetManaged", - g_variant_new("(bu)", managed, flags), + g_variant_new("(uu)", managed, flags), G_VARIANT_TYPE("()"), G_DBUS_CALL_FLAGS_NONE, NM_DBUS_DEFAULT_TIMEOUT_MSEC, diff --git a/src/libnm-client-public/nm-device.h b/src/libnm-client-public/nm-device.h index 253825d254..c7c2a6e38e 100644 --- a/src/libnm-client-public/nm-device.h +++ b/src/libnm-client-public/nm-device.h @@ -152,7 +152,7 @@ _NM_DEPRECATED_SYNC_METHOD void nm_device_set_managed(NMDevice *device, gboolean managed); NM_AVAILABLE_IN_1_54_4 void nm_device_set_managed_async(NMDevice *device, - gboolean managed, + NMDeviceManaged managed, NMDeviceManagedFlags flags, GCancellable *cancellable, GAsyncReadyCallback callback, diff --git a/src/libnm-core-public/nm-dbus-interface.h b/src/libnm-core-public/nm-dbus-interface.h index 3d9672ccdc..f258901073 100644 --- a/src/libnm-core-public/nm-dbus-interface.h +++ b/src/libnm-core-public/nm-dbus-interface.h @@ -1245,6 +1245,22 @@ typedef enum /*< flags >*/ { NM_DEVICE_REAPPLY_FLAGS_PRESERVE_EXTERNAL_IP = 0x1, } NMDeviceReapplyFlags; +/** + * NMDeviceManaged: + * @NM_DEVICE_MANAGED_NO: the device is not managed. + * @NM_DEVICE_MANAGED_YES: the device is managed. + * @NM_DEVICE_MANAGED_RESET: reset the device managed state to the default value. + * + * Values for the SetManaged() D-Bus call of a device and nm_device_set_managed_async(). + * + * Since: 1.56, 1.54.4 + */ +typedef enum { + NM_DEVICE_MANAGED_NO = 0, + NM_DEVICE_MANAGED_YES = 1, + NM_DEVICE_MANAGED_RESET = 2, +} NMDeviceManaged; + /** * NMDeviceManagedFlags: * @NM_DEVICE_MANAGED_FLAGS_NONE: no flag set.