activation: Allow changing controller of exposed active connection

When activating a port with its controller deactivating by new
activation, NM will register `state-change` signal waiting controller to
have new active connections. Once controller got new active connection,
the port will invoke `nm_active_connection_set_controller()` which lead
to assert error on
    g_return_if_fail(!nm_dbus_object_is_exported(NM_DBUS_OBJECT(self)))

because this active connection is already exposed as DBUS object.

To fix the problem, we remove the restriction on controller been
write-only and notify DBUS object changes for controller property.

Signed-off-by: Gris Ge <fge@redhat.com>
(cherry picked from commit 83a2595970)
(cherry picked from commit 3f3d1a4f54)
This commit is contained in:
Gris Ge 2024-07-12 16:58:20 +08:00 committed by Fernando Fernandez Mancera
parent c11e1738ab
commit 79c81fc06a
2 changed files with 35 additions and 16 deletions

View file

@ -870,20 +870,28 @@ nm_active_connection_set_master(NMActiveConnection *self, NMActiveConnection *ma
priv = NM_ACTIVE_CONNECTION_GET_PRIVATE(self);
/* Master is write-once, and must be set before exporting the object */
g_return_if_fail(priv->master == NULL);
g_return_if_fail(!nm_dbus_object_is_exported(NM_DBUS_OBJECT(self)));
if (priv->master != NULL) {
_LOGD("releasing previous controller " NM_HASH_OBFUSCATE_PTR_FMT " %s, state %s",
NM_HASH_OBFUSCATE_PTR(priv->master),
nm_active_connection_get_settings_connection_id(priv->master),
state_to_string_a(nm_active_connection_get_state(priv->master)));
g_clear_object(&priv->master);
}
if (priv->device) {
/* Note, the master ActiveConnection may not yet have a device */
g_return_if_fail(priv->device != nm_active_connection_get_device(master));
}
_LOGD("set master %p, %s, state %s",
master,
_LOGD("set master " NM_HASH_OBFUSCATE_PTR_FMT ", %s, state %s",
NM_HASH_OBFUSCATE_PTR(master),
nm_active_connection_get_settings_connection_id(master),
state_to_string_a(nm_active_connection_get_state(master)));
priv->master = g_object_ref(master);
_notify(self, PROP_MASTER);
g_signal_connect(priv->master,
"notify::" NM_ACTIVE_CONNECTION_STATE,
G_CALLBACK(master_state_cb),
@ -902,15 +910,20 @@ nm_active_connection_set_controller_dev(NMActiveConnection *self, NMDevice *cont
priv = NM_ACTIVE_CONNECTION_GET_PRIVATE(self);
/* Controller device is write-once, and must be set before exporting the object */
g_return_if_fail(priv->controller_dev == NULL);
g_return_if_fail(!nm_dbus_object_is_exported(NM_DBUS_OBJECT(self)));
if (priv->controller_dev != NULL) {
_LOGD("releasing previous controller device " NM_HASH_OBFUSCATE_PTR_FMT " %s(%s), state %s",
NM_HASH_OBFUSCATE_PTR(priv->controller_dev),
nm_device_get_iface(priv->controller_dev),
nm_device_get_type_desc(priv->controller_dev),
nm_device_state_to_string(nm_device_get_state(priv->controller_dev)));
g_clear_object(&priv->controller_dev);
}
if (priv->device) {
g_return_if_fail(priv->device != controller_dev);
}
_LOGD("set controller device %p, %s(%s), state %s",
controller_dev,
_LOGD("set controller device " NM_HASH_OBFUSCATE_PTR_FMT ", %s(%s), state %s",
NM_HASH_OBFUSCATE_PTR(controller_dev),
nm_device_get_iface(controller_dev),
nm_device_get_type_desc(controller_dev),
nm_device_state_to_string(nm_device_get_state(controller_dev)));

View file

@ -5953,15 +5953,21 @@ _internal_activate_device(NMManager *self, NMActiveConnection *active, GError **
&& (nm_device_get_state_reason(master_device)
== NM_DEVICE_STATE_REASON_NEW_ACTIVATION)) {
nm_active_connection_set_controller_dev(active, master_device);
_LOGD(LOGD_CORE,
"Activation of '%s'(%s) depends on controller device %p %s",
nm_settings_connection_get_id(sett_conn),
nm_settings_connection_get_connection_type(sett_conn),
master_device,
nm_dbus_object_get_path(NM_DBUS_OBJECT(master_device)) ?: "");
} else {
nm_active_connection_set_master(active, master_ac);
_LOGD(LOGD_CORE,
"Activation of '%s'(%s) depends on active connection %p %s",
nm_settings_connection_get_id(sett_conn),
nm_settings_connection_get_connection_type(sett_conn),
master_ac,
nm_dbus_object_get_path(NM_DBUS_OBJECT(master_ac)) ?: "");
}
_LOGD(LOGD_CORE,
"Activation of '%s' depends on active connection %p %s",
nm_settings_connection_get_id(sett_conn),
master_ac,
nm_dbus_object_get_path(NM_DBUS_OBJECT(master_ac)) ?: "");
}
/* Check slaves for master connection and possibly activate them */