2007-09-14 Dan Williams <dcbw@redhat.com>

Implement deferred activation support in the device class.

	* src/nm-device-interface.c
	  src/nm-device-interface.h
		- (nm_device_interface_activate): take more arguments to support
			deferred activation; callers must pass one of (connection) OR
			(service_name, connection_path)
		- (impl_device_activate): connection validation is punted to the device
			to be able to handle deferred activation.  Yes, this means errors
			don't get returned from the Activate() dbus call, and yes, that
			should be fixed somehow later.

	* src/nm-device.c
	  src/nm-device.h
		- (clear_act_request): clear additional deferred activation stuff too
		- (deferred_activation_timeout_cb): new function; clean up when
			deferred activation times out.
		- (deferred_activation_start_cb): new function; when the connection
			finally becomes available, start device activation
		- (nm_device_activate): attach to the right signals of the activation
			request if we need to defer activation until the connection is valid

	* src/NetworkManagerPolicy.c
		- (nm_policy_device_change_check): update for additional arguments
			required for nm_device_interface_activate().  Pass NULL for these
			though because this function already knows exactly which
			NMConnection to use



git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2812 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams
2007-09-14 19:51:04 +00:00
parent 92ee635c59
commit c766867b65
5 changed files with 208 additions and 63 deletions

View File

@@ -1,3 +1,33 @@
2007-09-14 Dan Williams <dcbw@redhat.com>
Implement deferred activation support in the device class.
* src/nm-device-interface.c
src/nm-device-interface.h
- (nm_device_interface_activate): take more arguments to support
deferred activation; callers must pass one of (connection) OR
(service_name, connection_path)
- (impl_device_activate): connection validation is punted to the device
to be able to handle deferred activation. Yes, this means errors
don't get returned from the Activate() dbus call, and yes, that
should be fixed somehow later.
* src/nm-device.c
src/nm-device.h
- (clear_act_request): clear additional deferred activation stuff too
- (deferred_activation_timeout_cb): new function; clean up when
deferred activation times out.
- (deferred_activation_start_cb): new function; when the connection
finally becomes available, start device activation
- (nm_device_activate): attach to the right signals of the activation
request if we need to defer activation until the connection is valid
* src/NetworkManagerPolicy.c
- (nm_policy_device_change_check): update for additional arguments
required for nm_device_interface_activate(). Pass NULL for these
though because this function already knows exactly which
NMConnection to use
2007-09-14 Dan Williams <dcbw@redhat.com>
Implement deferred activation handling in the NMActRequest class. When a

View File

@@ -338,7 +338,11 @@ nm_policy_device_change_check (gpointer user_data)
if (new_dev) {
nm_device_interface_activate (NM_DEVICE_INTERFACE (new_dev),
connection, specific_object, FALSE);
NULL,
NULL,
connection,
specific_object,
FALSE);
}
}

View File

@@ -177,16 +177,22 @@ nm_device_interface_get_type (void)
return device_interface_type;
}
/* Pass _either_ connection_path or connection. Passing 'connection' is
* meant for internal use only.
*/
void
nm_device_interface_activate (NMDeviceInterface *device,
const char *service_name,
const char *connection_path,
NMConnection *connection,
const char *specific_object,
gboolean user_requested)
{
g_return_if_fail (NM_IS_DEVICE_INTERFACE (device));
g_return_if_fail (connection != NULL);
NM_DEVICE_INTERFACE_GET_INTERFACE (device)->activate (device,
service_name,
connection_path,
connection,
specific_object,
user_requested);
@@ -199,36 +205,13 @@ impl_device_activate (NMDeviceInterface *device,
const char *specific_object,
GError **err)
{
NMManager *manager;
NMConnection *connection;
gboolean success = FALSE;
manager = nm_manager_get ();
if (!strcmp (service_name, NM_DBUS_SERVICE_USER_SETTINGS)) {
connection = nm_manager_get_connection_by_object_path (manager,
NM_CONNECTION_TYPE_USER,
connection_path);
} else if (!strcmp (service_name, NM_DBUS_SERVICE_USER_SETTINGS)) {
connection = nm_manager_get_connection_by_object_path (manager,
NM_CONNECTION_TYPE_SYSTEM,
connection_path);
}
if (connection == NULL) {
g_set_error (err,
NM_DEVICE_INTERFACE_ERROR,
NM_DEVICE_INTERFACE_ERROR_UNKNOWN_CONNECTION,
"%s",
"Connection object or service unknown");
goto out;
}
nm_connection_dump (connection);
nm_device_interface_activate (device, connection, specific_object, TRUE);
success = TRUE;
out:
return success;
nm_device_interface_activate (device,
service_name,
connection_path,
NULL,
specific_object,
TRUE);
return TRUE;
}
void

View File

@@ -51,6 +51,8 @@ struct _NMDeviceInterface {
/* Methods */
void (*activate) (NMDeviceInterface *device,
const char *service_name,
const char *connection_path,
NMConnection *connection,
const char *specific_object,
gboolean user_requested);
@@ -67,6 +69,8 @@ GType nm_device_interface_error_get_type (void);
GType nm_device_interface_get_type (void);
void nm_device_interface_activate (NMDeviceInterface *device,
const char *service_name,
const char *connection_path,
NMConnection *connection,
const char *specific_object,
gboolean user_requested);

View File

@@ -69,6 +69,8 @@ struct _NMDevicePrivate
struct in6_addr ip6_address;
NMActRequest * act_request;
gulong act_deferred_timeout_id;
gulong act_deferred_start_id;
guint act_source_id;
gulong secrets_updated_id;
@@ -81,6 +83,8 @@ struct _NMDevicePrivate
};
static void nm_device_activate (NMDeviceInterface *device,
const char *service_name,
const char *connection_path,
NMConnection *connection,
const char *specific_object,
gboolean user_requested);
@@ -121,6 +125,8 @@ nm_device_init (NMDevice * self)
self->priv->ip4_address = 0;
memset (&self->priv->ip6_address, 0, sizeof (struct in6_addr));
self->priv->act_deferred_timeout_id = 0;
self->priv->act_deferred_start_id = 0;
self->priv->act_source_id = 0;
self->priv->system_config_data = NULL;
@@ -952,9 +958,23 @@ clear_act_request (NMDevice *self)
if (!priv->act_request)
return;
if (priv->act_deferred_timeout_id) {
g_signal_handler_disconnect (priv->act_request,
priv->act_deferred_timeout_id);
priv->act_deferred_timeout_id = 0;
}
if (priv->act_deferred_start_id) {
g_signal_handler_disconnect (priv->act_request,
priv->act_deferred_start_id);
priv->act_deferred_start_id = 0;
}
if (priv->secrets_updated_id) {
g_signal_handler_disconnect (priv->act_request,
priv->secrets_updated_id);
priv->secrets_updated_id = 0;
}
g_object_unref (priv->act_request);
priv->act_request = NULL;
@@ -1096,33 +1116,53 @@ connection_secrets_updated_cb (NMActRequest *req,
}
static void
nm_device_activate (NMDeviceInterface *device,
NMConnection *connection,
const char *specific_object,
gboolean user_requested)
deferred_activation_timeout_cb (NMActRequest *req, gpointer user_data)
{
NMDevice *self = NM_DEVICE (device);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
gulong id;
NMDevice *self = NM_DEVICE (user_data);
if (nm_device_get_act_request (self) != req)
return;
nm_info ("%s: didn't receive connection details soon enough for activation.",
nm_device_get_iface (self));
clear_act_request (self);
nm_device_state_changed (self, NM_DEVICE_STATE_DISCONNECTED);
}
static gboolean
device_activation_precheck (NMDevice *self, NMConnection *connection)
{
NMConnection *current_connection;
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
if (!NM_DEVICE_GET_CLASS (self)->check_connection (self, connection))
/* connection is invalid */
return;
return FALSE;
if (nm_device_get_state (self) == NM_DEVICE_STATE_ACTIVATED || nm_device_is_activating (self)) {
NMConnection *current_connection;
if (nm_device_get_state (self) != NM_DEVICE_STATE_ACTIVATED)
return TRUE;
if (!nm_device_is_activating (self))
return TRUE;
current_connection = nm_act_request_get_connection (nm_device_get_act_request (self));
if (nm_connection_compare (connection, current_connection))
/* Already activating or activated with the same connection */
return;
return FALSE;
nm_device_deactivate (device);
}
return TRUE;
}
nm_info ("Activating device %s", nm_device_get_iface (self));
priv->act_request = nm_act_request_new (connection, specific_object, user_requested);
static void
device_activation_go (NMDevice *self)
{
NMDevicePrivate * priv;
gulong id;
priv = NM_DEVICE_GET_PRIVATE (self);
id = g_signal_connect (priv->act_request,
"connection-secrets-updated",
G_CALLBACK (connection_secrets_updated_cb),
@@ -1132,6 +1172,90 @@ nm_device_activate (NMDeviceInterface *device,
nm_device_activate_schedule_stage1_device_prepare (self);
}
static void
deferred_activation_start_cb (NMActRequest *req, gpointer user_data)
{
NMDevice *self = NM_DEVICE (user_data);
NMDevicePrivate * priv;
NMConnection *connection;
if (nm_device_get_act_request (self) != req)
return;
priv = NM_DEVICE_GET_PRIVATE (self);
g_signal_handler_disconnect (priv->act_request,
priv->act_deferred_start_id);
priv->act_deferred_start_id = 0;
connection = nm_act_request_get_connection (req);
if (device_activation_precheck (self, connection) == FALSE)
return;
nm_info ("%s: connection details received, will start activation.",
nm_device_get_iface (self));
device_activation_go (self);
}
static void
nm_device_activate (NMDeviceInterface *device,
const char *service_name,
const char *connection_path,
NMConnection *connection,
const char *specific_object,
gboolean user_requested)
{
NMDevice *self = NM_DEVICE (device);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
/* Only one of:
* - connection
* - service_name AND connection_path
* is valid.
*/
if (!connection) {
g_return_if_fail (service_name != NULL);
g_return_if_fail (connection_path != NULL);
} else if (connection) {
g_return_if_fail (service_name == NULL);
g_return_if_fail (connection_path == NULL);
}
nm_info ("Activating device %s", nm_device_get_iface (self));
if (connection) {
if (device_activation_precheck (self, connection) == FALSE)
return;
priv->act_request = nm_act_request_new (connection,
specific_object,
user_requested);
device_activation_go (self);
} else {
gulong id;
/* Don't have the connection quite yet, probably created by
* the client on-the-fly. Defer the activation until we have it
*/
priv->act_request = nm_act_request_new_deferred (service_name,
connection_path,
specific_object,
user_requested);
id = g_signal_connect (priv->act_request, "deferred-activation-timeout",
G_CALLBACK (deferred_activation_timeout_cb),
self);
priv->act_deferred_timeout_id = id;
id = g_signal_connect (priv->act_request, "deferred-activation-start",
G_CALLBACK (deferred_activation_start_cb),
self);
priv->act_deferred_start_id = id;
nm_info ("%s: Deferring activation until connection information is "
"received.", nm_device_get_iface (self));
}
}
/*
* nm_device_is_activating
*