device: add O.FD.NM.Device.Reapply() call

The introspection data and daemon stub. There's no settings that can be
reapplied at the moment.
This commit is contained in:
Lubomir Rintel 2015-11-02 15:32:38 +01:00
parent 21fa044df0
commit 1490c36bb9
2 changed files with 191 additions and 0 deletions

View file

@ -169,6 +169,27 @@
</tp:docstring>
</property>
<method name="Reapply">
<arg name="connection" type="a{sa{sv}}" direction="in">
<tp:docstring>
The effective connection settings and properties to use. If empty, the connection
settings from the connection that is active on the device will be used.
</tp:docstring>
</arg>
<arg name="flags" type="u" direction="in">
<tp:docstring>
Flags which would modify the behavior of the Reapply call.
There are no flags defined currently and the users should use the value of 0.
</tp:docstring>
</arg>
<tp:docstring>
Attempts to update the configuration of a device without deactivating it.
You can either modify the configuration by passing the desired setup via "connection"
argument or just omit the argument to bring it in sync with the connection that
has been activated but could have been modified since.
</tp:docstring>
</method>
<method name="Disconnect">
<tp:docstring>
Disconnects a device and prevents the device from automatically activating further connections without user intervention.

View file

@ -6829,6 +6829,175 @@ _cleanup_ip6_pre (NMDevice *self, CleanupType cleanup_type)
addrconf6_cleanup (self);
}
/* reapply_connection:
* @connection: the new connection settings to be applied
* @flags: always zero
* @reconfigure: %FALSE if this is a dry-run, %TRUE for an actual action
* @error: the error if %FALSE is returned
*
* Change configuration of an already configured device if possible.
* Updates the device's applied connection upon success.
*
* Return: %FALSE if the new configuration can not be reapplied.
*/
static gboolean
reapply_connection (NMDevice *self,
NMConnection *connection,
guint flags,
gboolean reconfigure,
GError **error)
{
NMConnection *applied = nm_device_get_applied_connection (self);
NMConnection *old;
GHashTable *diffs = NULL;
GHashTableIter iter;
const char *setting;
/* No flags supported as of now. */
if (flags != 0) {
g_set_error (error,
NM_DEVICE_ERROR,
NM_DEVICE_ERROR_FAILED,
"Invalid flags specified");
return FALSE;
}
nm_connection_diff (connection,
applied,
NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP |
NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS,
&diffs);
/* Everything set. */
if (!diffs)
return TRUE;
old = nm_simple_connection_new_clone (applied);
if (reconfigure)
nm_connection_replace_settings_from_connection (applied, connection);
g_hash_table_iter_init (&iter, diffs);
while (g_hash_table_iter_next (&iter, (gpointer *)&setting, NULL)) {
g_set_error (error,
NM_DEVICE_ERROR,
NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
"Can't reapply changes to '%s' settings",
setting);
return FALSE;
}
if (reconfigure)
nm_connection_replace_settings_from_connection (applied, NM_CONNECTION (connection));
return TRUE;
}
typedef struct {
NMConnection *connection;
guint flags;
} ReapplyInfo;
static void
reapply_cb (NMDevice *self,
GDBusMethodInvocation *context,
NMAuthSubject *subject,
GError *error,
gpointer user_data)
{
ReapplyInfo *info = (ReapplyInfo *)user_data;
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
GError *local = NULL;
if (error) {
g_dbus_method_invocation_return_gerror (context, error);
goto out;
}
/* Authorized */
if (priv->state != NM_DEVICE_STATE_ACTIVATED) {
local = g_error_new_literal (NM_DEVICE_ERROR,
NM_DEVICE_ERROR_NOT_ACTIVE,
"Device is not activated");
g_dbus_method_invocation_return_gerror (context, local);
g_error_free (local);
goto out;
}
if (!reapply_connection (self,
info->connection,
info->flags,
FALSE,
&local)) {
/* The dry-run check failed, pityfully. */
g_dbus_method_invocation_return_gerror (context, local);
g_error_free (local);
goto out;
}
reapply_connection (self,
info->connection,
info->flags,
TRUE,
&local);
g_dbus_method_invocation_return_value (context, NULL);
out:
g_object_unref (info->connection);
g_slice_free (ReapplyInfo, info);
}
static void
impl_device_reapply (NMDevice *self,
GDBusMethodInvocation *context,
GVariant *settings,
guint flags)
{
NMSettingsConnection *settings_connection;
NMConnection *connection;
GError *error = NULL;
ReapplyInfo *info;
if (NM_DEVICE_GET_PRIVATE (self)->act_request == NULL) {
error = g_error_new_literal (NM_DEVICE_ERROR,
NM_DEVICE_ERROR_NOT_ACTIVE,
"This device is not active");
g_dbus_method_invocation_return_gerror (context, error);
g_error_free (error);
return;
}
settings_connection = nm_device_get_settings_connection (self);
g_return_if_fail (settings_connection);
if (settings && g_variant_n_children (settings)) {
/* New settings specified inline. */
connection = nm_simple_connection_new_from_dbus (settings, &error);
if (!connection) {
g_prefix_error (&error, "The settings specified are invalid: ");
g_dbus_method_invocation_return_gerror (context, error);
g_error_free (error);
return;
}
nm_connection_clear_secrets (connection);
} else {
/* Just reuse whatever is active already. */
connection = NM_CONNECTION (g_object_ref (settings_connection));
}
info = g_slice_new0 (ReapplyInfo);
info->connection = connection;
info->flags = flags;
/* Ask the manager to authenticate this request for us */
g_signal_emit (self, signals[AUTH_REQUEST], 0,
context,
nm_device_get_applied_connection (self),
NM_AUTH_PERMISSION_NETWORK_CONTROL,
TRUE,
reapply_cb,
info);
}
static void
disconnect_cb (NMDevice *self,
GDBusMethodInvocation *context,
@ -10924,6 +11093,7 @@ nm_device_class_init (NMDeviceClass *klass)
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass),
NMDBUS_TYPE_DEVICE_SKELETON,
"Reapply", impl_device_reapply,
"Disconnect", impl_device_disconnect,
"Delete", impl_device_delete,
NULL);