summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nm-active-connection.c66
-rw-r--r--src/nm-active-connection.h3
2 files changed, 69 insertions, 0 deletions
diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c
index 2eb88fb35c..3de997b9a9 100644
--- a/src/nm-active-connection.c
+++ b/src/nm-active-connection.c
@@ -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);
diff --git a/src/nm-active-connection.h b/src/nm-active-connection.h
index a86e171a55..835266b3f1 100644
--- a/src/nm-active-connection.h
+++ b/src/nm-active-connection.h
@@ -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);