dbus: device: add SetManaged method

The 'Managed' property only sets the managed state in runtime, but it is
not possible to persist it to disk. Add a SetManaged method that will be
able to persist it to disk. In this commit, it just modify the runtime
state, so it actually only does the same than setting the property.
Storing to disk will be added in next commits.

	src/libnm-client-impl/libnm.ver
This commit is contained in:
Íñigo Huguet 2026-02-11 09:11:46 +01:00 committed by Rahul Rajesh
parent 128b49fe21
commit 9f256c3e86
6 changed files with 213 additions and 3 deletions

View file

@ -175,6 +175,9 @@
property has a similar effect to configuring the device as unmanaged via
the keyfile.unmanaged-devices setting in NetworkManager.conf. Changes to
this value are not persistent and lost after NetworkManager restart.
DEPRECATED: 1.58: Use the SetManaged method instead. It supports the same
than this property, and more, like persisting the state to disk.
-->
<property name="Managed" type="b" access="readwrite"/>
@ -391,6 +394,19 @@
-->
<method name="Delete"/>
<!--
SetManaged:
@managed: Whether the device is managed.
@flags: Flags which would modify the behavior of the SetManaged call. Invalid flags are rejected.
@since: 1.58
Set the managed state of the device.
-->
<method name="SetManaged">
<arg name="managed" type="b" direction="in"/>
<arg name="flags" type="u" direction="in"/>
</method>
<!--
StateChanged:
@new_state: (<link linkend="NMDeviceState">NMDeviceState</link>) The new state of the device.

View file

@ -14938,6 +14938,106 @@ impl_device_get_applied_connection(NMDBusObject *obj,
/*****************************************************************************/
typedef struct {
gboolean managed_state;
NMDeviceManagedFlags managed_flags;
} SetManagedData;
static gboolean
set_managed(NMDevice *self, gboolean managed, NMDeviceManagedFlags flags, GError **error)
{
gboolean 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);
return TRUE;
}
static void
set_managed_cb(NMDevice *self,
GDBusMethodInvocation *context,
NMAuthSubject *subject,
GError *error,
gpointer user_data)
{
SetManagedData *set_managed_data = user_data;
gboolean managed;
NMDeviceManagedFlags flags;
GError *local = NULL;
managed = set_managed_data->managed_state;
flags = set_managed_data->managed_flags;
nm_g_slice_free(set_managed_data);
if (error) {
nm_audit_log_device_op(NM_AUDIT_OP_DEVICE_MANAGED,
self,
FALSE,
NULL,
subject,
error->message);
g_dbus_method_invocation_return_gerror(context, error);
return;
}
if (!set_managed(self, managed, flags, &local)) {
nm_audit_log_device_op(NM_AUDIT_OP_DEVICE_MANAGED,
self,
FALSE,
NULL,
subject,
local->message);
g_dbus_method_invocation_take_error(context, g_steal_pointer(&local));
return;
}
nm_audit_log_device_op(NM_AUDIT_OP_DEVICE_MANAGED, self, TRUE, NULL, subject, NULL);
g_dbus_method_invocation_return_value(context, NULL);
}
static void
impl_device_set_managed(NMDBusObject *obj,
const NMDBusInterfaceInfoExtended *interface_info,
const NMDBusMethodInfoExtended *method_info,
GDBusConnection *connection,
const char *sender,
GDBusMethodInvocation *invocation,
GVariant *parameters)
{
NMDevice *self = NM_DEVICE(obj);
gs_free_error GError *error = NULL;
gboolean managed;
guint32 flags_u;
NMDeviceManagedFlags flags;
SetManagedData *set_managed_data;
g_variant_get(parameters, "(bu)", &managed, &flags_u);
flags = flags_u;
nm_assert(flags == flags_u);
set_managed_data = g_slice_new(SetManagedData);
*set_managed_data = (SetManagedData) {
.managed_state = managed,
.managed_flags = flags,
};
nm_device_auth_request(self,
invocation,
nm_device_get_applied_connection(self),
NM_AUTH_PERMISSION_NETWORK_CONTROL,
TRUE,
NULL,
set_managed_cb,
set_managed_data);
}
/*****************************************************************************/
static void
disconnect_cb(NMDevice *self,
GDBusMethodInvocation *context,
@ -19899,6 +19999,12 @@ static const NMDBusInterfaceInfoExtended interface_info_device = {
NM_DEFINE_GDBUS_ARG_INFO("connection", "a{sa{sv}}"),
NM_DEFINE_GDBUS_ARG_INFO("version_id", "t"), ), ),
.handle = impl_device_get_applied_connection, ),
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("flags", "u"), ), ),
.handle = impl_device_set_managed, ),
NM_DEFINE_DBUS_METHOD_INFO_EXTENDED(NM_DEFINE_GDBUS_METHOD_INFO_INIT("Disconnect", ),
.handle = impl_device_disconnect, ),
NM_DEFINE_DBUS_METHOD_INFO_EXTENDED(NM_DEFINE_GDBUS_METHOD_INFO_INIT("Delete", ),

View file

@ -2114,6 +2114,9 @@ global:
nm_device_geneve_get_tos;
nm_device_geneve_get_ttl;
nm_device_geneve_get_type;
nm_device_managed_flags_get_type;
nm_device_set_managed_async;
nm_device_set_managed_finish;
nm_ip_config_get_clat_address;
nm_ip_config_get_clat_pref64;
nm_setting_geneve_df_get_type;

View file

@ -1446,9 +1446,7 @@ nm_device_get_managed(NMDevice *device)
*
* Since: 1.2
*
* Deprecated: 1.22: Use the async command nm_client_dbus_set_property() on
* nm_object_get_path(), interface %NM_DBUS_INTERFACE_DEVICE to set the
* "Managed" property to a "(b)" boolean value.
* Deprecated: 1.22: Use nm_device_set_managed_async() instead.
* This function is deprecated because it calls a synchronous D-Bus method
* and modifies the content of the NMClient cache client side. Also, it does
* not emit a property changed signal.
@ -1470,6 +1468,72 @@ nm_device_set_managed(NMDevice *device, gboolean managed)
managed);
}
/**
* nm_device_set_managed_async:
* @device: a #NMDevice
* @managed: the managed state
* @flags: the flags argument. See #NMDeviceManagedFlags.
* @cancellable: a #GCancellable, or %NULL
* @callback: callback to be called when the set_managed operation completes
* @user_data: caller-specific data passed to @callback
*
* Asynchronously begins setting the managed state of the device. With the flags
* argument different behaviors can be achieved, such as persisting the state to
* disk or matching the device by MAC address.
*
* Since: 1.58
**/
void
nm_device_set_managed_async(NMDevice *device,
gboolean managed,
NMDeviceManagedFlags flags,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_return_if_fail(NM_IS_DEVICE(device));
g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable));
_nm_client_dbus_call(_nm_object_get_client(device),
device,
nm_device_set_managed_async,
cancellable,
callback,
user_data,
_nm_object_get_path(device),
NM_DBUS_INTERFACE_DEVICE,
"SetManaged",
g_variant_new("(bu)", managed, flags),
G_VARIANT_TYPE("()"),
G_DBUS_CALL_FLAGS_NONE,
NM_DBUS_DEFAULT_TIMEOUT_MSEC,
nm_dbus_connection_call_finish_void_strip_dbus_error_cb);
}
/**
* nm_device_set_managed_finish:
* @device: a #NMDevice
* @result: the result passed to the #GAsyncReadyCallback
* @error: location for a #GError, or %NULL
*
* Gets the result of a call to nm_device_set_managed_async().
*
* Returns: %TRUE on success, %FALSE on error, in which case @error
* will be set.
*
* Since: 1.58
**/
gboolean
nm_device_set_managed_finish(NMDevice *device, GAsyncResult *result, GError **error)
{
g_return_val_if_fail(NM_IS_DEVICE(device), FALSE);
g_return_val_if_fail(nm_g_task_is_valid(result, device, nm_device_set_managed_async), FALSE);
return g_task_propagate_boolean(G_TASK(result), error);
}
/*****************************************************************************/
/**
* nm_device_get_autoconnect:
* @device: a #NMDevice

View file

@ -150,6 +150,15 @@ NM_AVAILABLE_IN_1_2
NM_DEPRECATED_IN_1_22
_NM_DEPRECATED_SYNC_METHOD
void nm_device_set_managed(NMDevice *device, gboolean managed);
NM_AVAILABLE_IN_1_58
void nm_device_set_managed_async(NMDevice *device,
gboolean managed,
NMDeviceManagedFlags flags,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
NM_AVAILABLE_IN_1_58
gboolean nm_device_set_managed_finish(NMDevice *device, GAsyncResult *result, GError **error);
gboolean nm_device_get_autoconnect(NMDevice *device);

View file

@ -1248,6 +1248,18 @@ typedef enum /*< flags >*/ {
NM_DEVICE_REAPPLY_FLAGS_PRESERVE_EXTERNAL_IP = 0x1,
} NMDeviceReapplyFlags;
/**
* NMDeviceManagedFlags:
* @NM_DEVICE_MANAGED_FLAGS_NONE: no flag set.
*
* 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,
} NMDeviceManagedFlags;
/**
* NMTernary:
* @NM_TERNARY_DEFAULT: use the globally-configured default value.