core: indicate via a property when master connections are ready for slaves

Add a 'master-ready' property to NMActiveConnection that NMDevice can
watch for to indicate that the master connection/device is ready to accept
slaves.  Since the slave device's ActiveConnection is already tracking
its master connection, and since ActiveConnections don't enter the
ACTIVATING state until their device is ready for slaves, it's pretty
trivial to implement this property.
This commit is contained in:
Dan Williams
2013-09-27 17:13:43 -05:00
parent ae116d847e
commit 087e1dfbb9
2 changed files with 69 additions and 0 deletions

View File

@@ -52,6 +52,7 @@ typedef struct {
NMAuthSubject *subject;
NMActiveConnection *master;
gboolean master_ready;
NMAuthChain *chain;
const char *wifi_shared_permission;
@@ -76,10 +77,13 @@ enum {
PROP_INT_DEVICE,
PROP_INT_SUBJECT,
PROP_INT_MASTER,
PROP_INT_MASTER_READY,
LAST_PROP
};
static void check_master_ready (NMActiveConnection *self);
/****************************************************************/
NMActiveConnectionState
@@ -106,6 +110,8 @@ nm_active_connection_set_state (NMActiveConnection *self,
priv->state = new_state;
g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_STATE);
check_master_ready (self);
if ( new_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED
|| old_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
nm_settings_connection_update_timestamp (NM_SETTINGS_CONNECTION (priv->connection),
@@ -280,6 +286,53 @@ nm_active_connection_get_master (NMActiveConnection *self)
return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->master;
}
/**
* nm_active_connection_get_master_ready:
* @self: the #NMActiveConnection
*
* Returns: %TRUE if the connection has a master connection, and that
* master connection is ready to accept slaves. Otherwise %FALSE.
*/
gboolean
nm_active_connection_get_master_ready (NMActiveConnection *self)
{
g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), FALSE);
return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->master_ready;
}
static void
check_master_ready (NMActiveConnection *self)
{
NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
NMActiveConnectionState master_state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN;
if (priv->state != NM_ACTIVE_CONNECTION_STATE_ACTIVATING)
return;
if (!priv->master)
return;
if (priv->master_ready)
return;
/* ActiveConnetions don't enter the ACTIVATING state until they have a
* NMDevice in PREPARE or higher states, so the master active connection's
* device will be ready to accept slaves when the master is in ACTIVATING
* or higher states.
*/
master_state = nm_active_connection_get_state (priv->master);
if ( master_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATING
|| master_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
priv->master_ready = TRUE;
g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_INT_MASTER_READY);
/* Also notify clients to recheck the exported 'master' property to
* ensure that if the master connection was created without a device
* that we notify clients when the master device is known.
*/
g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_MASTER);
}
}
static void
master_state_cb (NMActiveConnection *master,
GParamSpec *pspec,
@@ -289,6 +342,8 @@ master_state_cb (NMActiveConnection *master,
NMActiveConnectionState self_state = nm_active_connection_get_state (self);
NMActiveConnectionState master_state = nm_active_connection_get_state (master);
check_master_ready (self);
/* Master is deactivating, so this active connection must also deactivate */
if (self_state < NM_ACTIVE_CONNECTION_STATE_DEACTIVATING &&
master_state >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) {
@@ -333,6 +388,8 @@ nm_active_connection_set_master (NMActiveConnection *self, NMActiveConnection *m
"notify::" NM_ACTIVE_CONNECTION_STATE,
(GCallback) master_state_cb,
self);
check_master_ready (self);
}
/****************************************************************/
@@ -546,6 +603,9 @@ get_property (GObject *object, guint prop_id,
case PROP_INT_SUBJECT:
g_value_set_object (value, priv->subject);
break;
case PROP_INT_MASTER_READY:
g_value_set_boolean (value, priv->master_ready);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -689,6 +749,12 @@ nm_active_connection_class_init (NMActiveConnectionClass *ac_class)
NM_TYPE_ACTIVE_CONNECTION,
G_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_INT_MASTER_READY,
g_param_spec_boolean (NM_ACTIVE_CONNECTION_INT_MASTER_READY,
"Internal master active connection ready for slaves",
"Internal active connection ready",
FALSE, G_PARAM_READABLE));
nm_dbus_manager_register_exported_type (nm_dbus_manager_get (),
G_TYPE_FROM_CLASS (ac_class),
&dbus_glib_nm_active_connection_object_info);

View File

@@ -49,6 +49,7 @@
#define NM_ACTIVE_CONNECTION_INT_DEVICE "int-device"
#define NM_ACTIVE_CONNECTION_INT_SUBJECT "int-subject"
#define NM_ACTIVE_CONNECTION_INT_MASTER "int-master"
#define NM_ACTIVE_CONNECTION_INT_MASTER_READY "int-master-ready"
typedef struct {
GObject parent;
@@ -114,6 +115,8 @@ gulong nm_active_connection_get_user_uid (NMActiveConnection *self);
NMActiveConnection *nm_active_connection_get_master (NMActiveConnection *self);
gboolean nm_active_connection_get_master_ready (NMActiveConnection *self);
void nm_active_connection_set_master (NMActiveConnection *self,
NMActiveConnection *master);