summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-01-14 11:57:37 +0100
committerThomas Haller <thaller@redhat.com>2019-01-14 11:57:37 +0100
commitcf30c9f07fb490b5f1833de52636e215be2dd57c (patch)
treee21dbecc633aee31ca5f44e94d31bca5756a6503
parent240e2bd9f8b40b4c58538c6979ac4a4194cd3bad (diff)
parentfbb038af5e5d675c994de26da676edfd8e73ffbe (diff)
downloadNetworkManager-cf30c9f07fb490b5f1833de52636e215be2dd57c.tar.gz
libnm: merge branch 'th/add-and-activate2-api'
https://github.com/NetworkManager/NetworkManager/pull/275
-rw-r--r--introspection/org.freedesktop.NetworkManager.xml3
-rw-r--r--libnm/libnm.ver4
-rw-r--r--libnm/nm-client.c83
-rw-r--r--libnm/nm-client.h23
-rw-r--r--libnm/nm-manager.c146
-rw-r--r--libnm/nm-manager.h16
-rw-r--r--shared/nm-utils/nm-macros-internal.h17
-rw-r--r--src/nm-manager.c89
-rwxr-xr-xtools/test-networkmanager-service.py9
9 files changed, 283 insertions, 107 deletions
diff --git a/introspection/org.freedesktop.NetworkManager.xml b/introspection/org.freedesktop.NetworkManager.xml
index b8d0b5c125..efd866db47 100644
--- a/introspection/org.freedesktop.NetworkManager.xml
+++ b/introspection/org.freedesktop.NetworkManager.xml
@@ -119,6 +119,8 @@
@options: Further options for the method call.
@path: Object path of the new connection that was just added.
@active_connection: The path of the active connection object representing this active connection.
+ @result: a dictionary of additional output arguments for future extension. Currently not additional
+ output arguments are supported.
Adds a new connection using the given details (if any) as a template
(automatically filling in missing settings with the capabilities of the
@@ -138,6 +140,7 @@
<arg name="options" type="a{sv}" direction="in"/>
<arg name="path" type="o" direction="out"/>
<arg name="active_connection" type="o" direction="out"/>
+ <arg name="result" type="a{sv}" direction="out"/>
</method>
<!--
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index f1f6954e53..652e01eb68 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -1447,8 +1447,8 @@ global:
libnm_1_16_0 {
global:
- nm_client_add_and_activate_connection_options;
- nm_client_add_and_activate_connection_options_finish;
+ nm_client_add_and_activate_connection2;
+ nm_client_add_and_activate_connection2_finish;
nm_device_get_connectivity;
nm_team_link_watcher_get_vlanid;
nm_team_link_watcher_new_arp_ping2;
diff --git a/libnm/nm-client.c b/libnm/nm-client.c
index 50307486bc..e2522229bc 100644
--- a/libnm/nm-client.c
+++ b/libnm/nm-client.c
@@ -1163,18 +1163,20 @@ add_activate_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
- GSimpleAsyncResult *simple = user_data;
+ gs_unref_object GSimpleAsyncResult *simple = user_data;
+ gs_unref_variant GVariant *result_data = NULL;
NMActiveConnection *ac;
GError *error = NULL;
- ac = nm_manager_add_and_activate_connection_finish (NM_MANAGER (object), result, &error);
- if (ac)
- g_simple_async_result_set_op_res_gpointer (simple, ac, g_object_unref);
- else
+ ac = nm_manager_add_and_activate_connection_finish (NM_MANAGER (object), result, &result_data, &error);
+ if (ac) {
+ g_simple_async_result_set_op_res_gpointer (simple,
+ _nm_activate_result_new (ac, result_data),
+ (GDestroyNotify) _nm_activate_result_free);
+ } else
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
- g_object_unref (simple);
}
/**
@@ -1233,8 +1235,14 @@ nm_client_add_and_activate_connection_async (NMClient *client,
if (cancellable)
g_simple_async_result_set_check_cancellable (simple, cancellable);
nm_manager_add_and_activate_connection_async (NM_CLIENT_GET_PRIVATE (client)->manager,
- partial, device, specific_object, NULL,
- cancellable, add_activate_cb, simple);
+ partial,
+ device,
+ specific_object,
+ NULL,
+ FALSE,
+ cancellable,
+ add_activate_cb,
+ simple);
}
/**
@@ -1257,6 +1265,7 @@ nm_client_add_and_activate_connection_finish (NMClient *client,
GError **error)
{
GSimpleAsyncResult *simple;
+ _NMActivateResult *r;
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
@@ -1264,12 +1273,12 @@ nm_client_add_and_activate_connection_finish (NMClient *client,
simple = G_SIMPLE_ASYNC_RESULT (result);
if (g_simple_async_result_propagate_error (simple, error))
return NULL;
- else
- return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
+ r = g_simple_async_result_get_op_res_gpointer (simple);
+ return g_object_ref (r->active);
}
/**
- * nm_client_add_and_activate_connection_options:
+ * nm_client_add_and_activate_connection2:
* @client: a #NMClient
* @partial: (allow-none): an #NMConnection to add; the connection may be
* partially filled (or even %NULL) and will be completed by NetworkManager
@@ -1312,14 +1321,14 @@ nm_client_add_and_activate_connection_finish (NMClient *client,
* Since: 1.16
**/
void
-nm_client_add_and_activate_connection_options (NMClient *client,
- NMConnection *partial,
- NMDevice *device,
- const char *specific_object,
- GVariant *options,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+nm_client_add_and_activate_connection2 (NMClient *client,
+ NMConnection *partial,
+ NMDevice *device,
+ const char *specific_object,
+ GVariant *options,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
GSimpleAsyncResult *simple;
GError *error = NULL;
@@ -1335,21 +1344,30 @@ nm_client_add_and_activate_connection_options (NMClient *client,
}
simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data,
- nm_client_add_and_activate_connection_options);
+ nm_client_add_and_activate_connection2);
if (cancellable)
g_simple_async_result_set_check_cancellable (simple, cancellable);
nm_manager_add_and_activate_connection_async (NM_CLIENT_GET_PRIVATE (client)->manager,
- partial, device, specific_object, options,
- cancellable, add_activate_cb, simple);
+ partial,
+ device,
+ specific_object,
+ options,
+ TRUE,
+ cancellable,
+ add_activate_cb,
+ simple);
}
/**
- * nm_client_add_and_activate_connection_options_finish:
+ * nm_client_add_and_activate_connection2_finish:
* @client: an #NMClient
* @result: the result passed to the #GAsyncReadyCallback
* @error: location for a #GError, or %NULL
+ * @out_result: (allow-none): (transfer full): the output result
+ * of type "a{sv}" returned by D-Bus' AddAndActivate2 call. Currently no
+ * output is implemented yet.
*
- * Gets the result of a call to nm_client_add_and_activate_connection_options().
+ * Gets the result of a call to nm_client_add_and_activate_connection2().
*
* You can call nm_active_connection_get_connection() on the returned
* #NMActiveConnection to find the path of the created #NMConnection.
@@ -1358,20 +1376,25 @@ nm_client_add_and_activate_connection_options (NMClient *client,
* failure, in which case @error will be set.
**/
NMActiveConnection *
-nm_client_add_and_activate_connection_options_finish (NMClient *client,
- GAsyncResult *result,
- GError **error)
+nm_client_add_and_activate_connection2_finish (NMClient *client,
+ GAsyncResult *result,
+ GVariant **out_result,
+ GError **error)
{
GSimpleAsyncResult *simple;
+ _NMActivateResult *r;
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
simple = G_SIMPLE_ASYNC_RESULT (result);
- if (g_simple_async_result_propagate_error (simple, error))
+ if (g_simple_async_result_propagate_error (simple, error)) {
+ NM_SET_OUT (out_result, NULL);
return NULL;
- else
- return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
+ }
+ r = g_simple_async_result_get_op_res_gpointer (simple);
+ NM_SET_OUT (out_result, nm_g_variant_ref (r->add_and_activate_output));
+ return g_object_ref (r->active);
}
/**
diff --git a/libnm/nm-client.h b/libnm/nm-client.h
index 59567c1737..97363ef759 100644
--- a/libnm/nm-client.h
+++ b/libnm/nm-client.h
@@ -340,18 +340,19 @@ NMActiveConnection *nm_client_add_and_activate_connection_finish (NMClient *clie
GError **error);
NM_AVAILABLE_IN_1_16
-void nm_client_add_and_activate_connection_options (NMClient *client,
- NMConnection *partial,
- NMDevice *device,
- const char *specific_object,
- GVariant *options,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
+void nm_client_add_and_activate_connection2 (NMClient *client,
+ NMConnection *partial,
+ NMDevice *device,
+ const char *specific_object,
+ GVariant *options,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
NM_AVAILABLE_IN_1_16
-NMActiveConnection *nm_client_add_and_activate_connection_options_finish (NMClient *client,
- GAsyncResult *result,
- GError **error);
+NMActiveConnection *nm_client_add_and_activate_connection2_finish (NMClient *client,
+ GAsyncResult *result,
+ GVariant **out_result,
+ GError **error);
gboolean nm_client_deactivate_connection (NMClient *client,
NMActiveConnection *active,
diff --git a/libnm/nm-manager.c b/libnm/nm-manager.c
index 235dc4aed1..6a32f51a2b 100644
--- a/libnm/nm-manager.c
+++ b/libnm/nm-manager.c
@@ -870,16 +870,49 @@ nm_manager_get_activating_connection (NMManager *manager)
return NM_MANAGER_GET_PRIVATE (manager)->activating_connection;
}
+typedef enum {
+ ACTIVATE_TYPE_ACTIVATE_CONNECTION,
+ ACTIVATE_TYPE_ADD_AND_ACTIVATE_CONNECTION,
+ ACTIVATE_TYPE_ADD_AND_ACTIVATE_CONNECTION2,
+} ActivateType;
+
typedef struct {
CList lst;
NMManager *manager;
GSimpleAsyncResult *simple;
GCancellable *cancellable;
- gulong cancelled_id;
char *active_path;
char *new_connection_path;
+ GVariant *add_and_activate_output;
+ gulong cancelled_id;
+ ActivateType activate_type;
} ActivateInfo;
+_NMActivateResult *
+_nm_activate_result_new (NMActiveConnection *active,
+ GVariant *add_and_activate_output)
+{
+ _NMActivateResult *r;
+
+ nm_assert (!add_and_activate_output || g_variant_is_of_type (add_and_activate_output, G_VARIANT_TYPE ("a{sv}")));
+ nm_assert (!add_and_activate_output || !g_variant_is_floating (add_and_activate_output));
+
+ r = g_slice_new (_NMActivateResult);
+ *r = (_NMActivateResult) {
+ .active = g_object_ref (active),
+ .add_and_activate_output = nm_g_variant_ref (add_and_activate_output),
+ };
+ return r;
+}
+
+void
+_nm_activate_result_free (_NMActivateResult *result)
+{
+ g_object_unref (result->active);
+ nm_g_variant_unref (result->add_and_activate_output);
+ g_slice_free (_NMActivateResult, result);
+}
+
static void
activate_info_complete (ActivateInfo *info,
NMActiveConnection *active,
@@ -889,12 +922,17 @@ activate_info_complete (ActivateInfo *info,
c_list_unlink_stale (&info->lst);
- if (active)
- g_simple_async_result_set_op_res_gpointer (info->simple, g_object_ref (active), g_object_unref);
- else
+ if (active) {
+ g_simple_async_result_set_op_res_gpointer (info->simple,
+ _nm_activate_result_new (active,
+ info->add_and_activate_output),
+ (GDestroyNotify) _nm_activate_result_free);
+ } else
g_simple_async_result_set_from_error (info->simple, error);
+
g_simple_async_result_complete (info->simple);
+ nm_g_variant_unref (info->add_and_activate_output);
g_free (info->active_path);
g_free (info->new_connection_path);
g_object_unref (info->simple);
@@ -1035,6 +1073,7 @@ nm_manager_activate_connection_async (NMManager *manager,
priv = NM_MANAGER_GET_PRIVATE (manager);
info = g_slice_new0 (ActivateInfo);
+ info->activate_type = ACTIVATE_TYPE_ACTIVATE_CONNECTION;
info->manager = manager;
info->simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data,
nm_manager_activate_connection_async);
@@ -1058,14 +1097,16 @@ nm_manager_activate_connection_finish (NMManager *manager,
GError **error)
{
GSimpleAsyncResult *simple;
+ _NMActivateResult *r;
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (manager), nm_manager_activate_connection_async), NULL);
simple = G_SIMPLE_ASYNC_RESULT (result);
if (g_simple_async_result_propagate_error (simple, error))
return NULL;
- else
- return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
+
+ r = g_simple_async_result_get_op_res_gpointer (simple);
+ return g_object_ref (r->active);
}
static void
@@ -1074,23 +1115,35 @@ add_activate_cb (GObject *object,
gpointer user_data)
{
ActivateInfo *info = user_data;
- GError *error = NULL;
-
- if (nmdbus_manager_call_add_and_activate_connection_finish (NMDBUS_MANAGER (object),
- NULL,
- &info->active_path,
- result, &error)) {
- if (info->cancellable) {
- info->cancelled_id = g_signal_connect (info->cancellable, "cancelled",
- G_CALLBACK (activation_cancelled), info);
- }
-
- recheck_pending_activations (info->manager);
+ gs_free GError *error = NULL;
+ gboolean success;
+
+ if (info->activate_type == ACTIVATE_TYPE_ADD_AND_ACTIVATE_CONNECTION) {
+ success = nmdbus_manager_call_add_and_activate_connection_finish (NMDBUS_MANAGER (object),
+ NULL,
+ &info->active_path,
+ result,
+ &error);
} else {
+ success = nmdbus_manager_call_add_and_activate_connection2_finish (NMDBUS_MANAGER (object),
+ NULL,
+ &info->active_path,
+ &info->add_and_activate_output,
+ result,
+ &error);
+ }
+ if (!success) {
g_dbus_error_strip_remote_error (error);
activate_info_complete (info, NULL, error);
- g_clear_error (&error);
+ return;
+ }
+
+ if (info->cancellable) {
+ info->cancelled_id = g_signal_connect (info->cancellable, "cancelled",
+ G_CALLBACK (activation_cancelled), info);
}
+
+ recheck_pending_activations (info->manager);
}
void
@@ -1099,6 +1152,7 @@ nm_manager_add_and_activate_connection_async (NMManager *manager,
NMDevice *device,
const char *specific_object,
GVariant *options,
+ gboolean force_v2,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
@@ -1106,6 +1160,7 @@ nm_manager_add_and_activate_connection_async (NMManager *manager,
NMManagerPrivate *priv;
GVariant *dict = NULL;
ActivateInfo *info;
+ ActivateType activate_type = ACTIVATE_TYPE_ADD_AND_ACTIVATE_CONNECTION;
g_return_if_fail (NM_IS_MANAGER (manager));
g_return_if_fail (NM_IS_DEVICE (device));
@@ -1128,32 +1183,61 @@ nm_manager_add_and_activate_connection_async (NMManager *manager,
dict = nm_connection_to_dbus (partial, NM_CONNECTION_SERIALIZE_ALL);
if (!dict)
dict = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0);
- if (!options)
- options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
+ if (force_v2) {
+ if (!options)
+ options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
+ activate_type = ACTIVATE_TYPE_ADD_AND_ACTIVATE_CONNECTION2;
+ } else {
+ if (options) {
+ if (g_variant_n_children (options) > 0)
+ activate_type = ACTIVATE_TYPE_ADD_AND_ACTIVATE_CONNECTION2;
+ else
+ nm_g_variant_unref_floating (options);
+ }
+ }
- nmdbus_manager_call_add_and_activate_connection2 (priv->proxy,
- dict,
- nm_object_get_path (NM_OBJECT (device)),
- specific_object ?: "/",
- options,
- cancellable,
- add_activate_cb, info);
+ info->activate_type = activate_type;
+
+ if (activate_type == ACTIVATE_TYPE_ADD_AND_ACTIVATE_CONNECTION2) {
+ nmdbus_manager_call_add_and_activate_connection2 (priv->proxy,
+ dict,
+ nm_object_get_path (NM_OBJECT (device)),
+ specific_object ?: "/",
+ options,
+ cancellable,
+ add_activate_cb,
+ info);
+ } else {
+ nmdbus_manager_call_add_and_activate_connection (priv->proxy,
+ dict,
+ nm_object_get_path (NM_OBJECT (device)),
+ specific_object ?: "/",
+ cancellable,
+ add_activate_cb,
+ info);
+ }
}
NMActiveConnection *
nm_manager_add_and_activate_connection_finish (NMManager *manager,
GAsyncResult *result,
+ GVariant **out_result,
GError **error)
{
GSimpleAsyncResult *simple;
+ _NMActivateResult *r;
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (manager), nm_manager_add_and_activate_connection_async), NULL);
simple = G_SIMPLE_ASYNC_RESULT (result);
- if (g_simple_async_result_propagate_error (simple, error))
+ if (g_simple_async_result_propagate_error (simple, error)) {
+ NM_SET_OUT (out_result, NULL);
return NULL;
- else
- return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
+ }
+
+ r = g_simple_async_result_get_op_res_gpointer (simple);
+ NM_SET_OUT (out_result, nm_g_variant_ref (r->add_and_activate_output));
+ return g_object_ref (r->active);
}
static void
diff --git a/libnm/nm-manager.h b/libnm/nm-manager.h
index 26b7ef412a..04e12eb3fa 100644
--- a/libnm/nm-manager.h
+++ b/libnm/nm-manager.h
@@ -164,11 +164,13 @@ void nm_manager_add_and_activate_connection_async (NMManager *ma
NMDevice *device,
const char *specific_object,
GVariant *options,
+ gboolean force_v2,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
NMActiveConnection *nm_manager_add_and_activate_connection_finish (NMManager *manager,
GAsyncResult *result,
+ GVariant **out_result,
GError **error);
gboolean nm_manager_deactivate_connection (NMManager *manager,
@@ -221,4 +223,18 @@ gboolean nm_manager_checkpoint_adjust_rollback_timeout_finish (NMManager *manage
GAsyncResult *result,
GError **error);
+/*****************************************************************************/
+
+typedef struct {
+ NMActiveConnection *active;
+ GVariant *add_and_activate_output;
+} _NMActivateResult;
+
+_NMActivateResult *_nm_activate_result_new (NMActiveConnection *active,
+ GVariant *add_and_activate_output);
+
+void _nm_activate_result_free (_NMActivateResult *result);
+
+/*****************************************************************************/
+
#endif /* __NM_MANAGER_H__ */
diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h
index 3578a55291..b993b3840c 100644
--- a/shared/nm-utils/nm-macros-internal.h
+++ b/shared/nm-utils/nm-macros-internal.h
@@ -1129,6 +1129,23 @@ nm_clear_g_cancellable (GCancellable **cancellable)
/*****************************************************************************/
+static inline GVariant *
+nm_g_variant_ref (GVariant *v)
+{
+ if (v)
+ g_variant_ref (v);
+ return v;
+}
+
+static inline void
+nm_g_variant_unref (GVariant *v)
+{
+ if (v)
+ g_variant_unref (v);
+}
+
+/*****************************************************************************/
+
/* Determine whether @x is a power of two (@x being an integer type).
* Basically, this returns TRUE, if @x has exactly one bit set.
* For negative values and zero, this always returns FALSE. */
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 2b14918683..127d47a33d 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -80,6 +80,7 @@ typedef enum {
ASYNC_OP_TYPE_AC_AUTH_ACTIVATE_INTERNAL,
ASYNC_OP_TYPE_AC_AUTH_ACTIVATE_USER,
ASYNC_OP_TYPE_AC_AUTH_ADD_AND_ACTIVATE,
+ ASYNC_OP_TYPE_AC_AUTH_ADD_AND_ACTIVATE2,
} AsyncOpType;
typedef struct {
@@ -370,6 +371,7 @@ static void _internal_activation_auth_done (NMManager *self,
gboolean success,
const char *error_desc);
static void _add_and_activate_auth_done (NMManager *self,
+ AsyncOpType async_op_type,
NMActiveConnection *active,
NMConnection *connection,
GDBusMethodInvocation *invocation,
@@ -486,6 +488,7 @@ _async_op_data_new_ac_auth_activate_user (NMManager *self,
static AsyncOpData *
_async_op_data_new_ac_auth_add_and_activate (NMManager *self,
+ AsyncOpType async_op_type,
NMActiveConnection *active_take,
GDBusMethodInvocation *invocation_take,
NMConnection *connection_take,
@@ -493,8 +496,11 @@ _async_op_data_new_ac_auth_add_and_activate (NMManager *self,
{
AsyncOpData *async_op_data;
+ nm_assert (NM_IN_SET (async_op_type, ASYNC_OP_TYPE_AC_AUTH_ADD_AND_ACTIVATE,
+ ASYNC_OP_TYPE_AC_AUTH_ADD_AND_ACTIVATE2));
+
async_op_data = g_slice_new0 (AsyncOpData);
- async_op_data->async_op_type = ASYNC_OP_TYPE_AC_AUTH_ADD_AND_ACTIVATE;
+ async_op_data->async_op_type = async_op_type;
async_op_data->self = g_object_ref (self);
async_op_data->ac_auth.active = active_take;
async_op_data->ac_auth.add_and_activate.invocation = invocation_take;
@@ -535,7 +541,9 @@ _async_op_complete_ac_auth_cb (NMActiveConnection *active,
error_desc);
break;
case ASYNC_OP_TYPE_AC_AUTH_ADD_AND_ACTIVATE:
+ case ASYNC_OP_TYPE_AC_AUTH_ADD_AND_ACTIVATE2:
_add_and_activate_auth_done (async_op_data->self,
+ async_op_data->async_op_type,
async_op_data->ac_auth.active,
async_op_data->ac_auth.add_and_activate.connection,
async_op_data->ac_auth.add_and_activate.invocation,
@@ -5274,36 +5282,52 @@ activation_add_done (NMSettings *settings,
gs_free_error GError *local = NULL;
gpointer persist_ptr;
NMSettingsConnectionPersistMode persist;
+ gpointer async_op_type_ptr;
+ AsyncOpType async_op_type;
+ GVariant *result_floating;
- nm_utils_user_data_unpack (user_data, &self, &active, &persist_ptr);
+ nm_utils_user_data_unpack (user_data, &self, &active, &persist_ptr, &async_op_type_ptr);
persist = GPOINTER_TO_INT (persist_ptr);
+ async_op_type = GPOINTER_TO_INT (async_op_type_ptr);
- if (!error) {
- nm_active_connection_set_settings_connection (active, new_connection);
-
- if (_internal_activate_generic (self, active, &local)) {
- nm_settings_connection_update (new_connection,
- NULL,
- persist,
- NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION | NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED,
- "add-and-activate",
- NULL);
- g_dbus_method_invocation_return_value (
- context,
- g_variant_new ("(oo)",
- nm_dbus_object_get_path (NM_DBUS_OBJECT (new_connection)),
- nm_dbus_object_get_path (NM_DBUS_OBJECT (active))));
- nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE,
- nm_active_connection_get_settings_connection (active),
- TRUE,
- NULL,
- nm_active_connection_get_subject (active),
- NULL);
- return;
- }
+ if (error)
+ goto fail;
+
+ nm_active_connection_set_settings_connection (active, new_connection);
+
+ if (!_internal_activate_generic (self, active, &local)) {
error = local;
+ goto fail;
}
+ nm_settings_connection_update (new_connection,
+ NULL,
+ persist,
+ NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION | NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED,
+ "add-and-activate",
+ NULL);
+
+ if (async_op_type == ASYNC_OP_TYPE_AC_AUTH_ADD_AND_ACTIVATE) {
+ result_floating = g_variant_new ("(oo)",
+ nm_dbus_object_get_path (NM_DBUS_OBJECT (new_connection)),
+ nm_dbus_object_get_path (NM_DBUS_OBJECT (active)));
+ } else {
+ result_floating = g_variant_new ("(ooa{sv})",
+ nm_dbus_object_get_path (NM_DBUS_OBJECT (new_connection)),
+ nm_dbus_object_get_path (NM_DBUS_OBJECT (active)),
+ g_variant_new_array (G_VARIANT_TYPE ("a{sv}"), NULL, 0));
+ }
+ g_dbus_method_invocation_return_value (context, result_floating);
+
+ nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE,
+ nm_active_connection_get_settings_connection (active),
+ TRUE,
+ NULL,
+ nm_active_connection_get_subject (active),
+ NULL);
+ return;
+
+fail:
nm_assert (error);
nm_active_connection_set_state_fail (active,
@@ -5322,6 +5346,7 @@ activation_add_done (NMSettings *settings,
static void
_add_and_activate_auth_done (NMManager *self,
+ AsyncOpType async_op_type,
NMActiveConnection *active,
NMConnection *connection,
GDBusMethodInvocation *invocation,
@@ -5359,7 +5384,8 @@ _add_and_activate_auth_done (NMManager *self,
activation_add_done,
nm_utils_user_data_pack (self,
g_object_ref (active),
- GINT_TO_POINTER (persist)));
+ GINT_TO_POINTER (persist),
+ GINT_TO_POINTER (async_op_type)));
}
static void
@@ -5386,11 +5412,16 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj,
gs_free NMConnection **conns = NULL;
NMSettingsConnectionPersistMode persist = NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK;
gboolean bind_dbus_client = FALSE;
+ AsyncOpType async_op_type;
- if (g_strcmp0 (method_info->parent.name, "AddAndActivateConnection2") == 0)
+ if (nm_streq (method_info->parent.name, "AddAndActivateConnection2")) {
+ async_op_type = ASYNC_OP_TYPE_AC_AUTH_ADD_AND_ACTIVATE2;
g_variant_get (parameters, "(@a{sa{sv}}&o&o@a{sv})", &settings, &device_path, &specific_object_path, &options);
- else
+ } else {
+ nm_assert (nm_streq (method_info->parent.name, "AddAndActivateConnection"));
+ async_op_type = ASYNC_OP_TYPE_AC_AUTH_ADD_AND_ACTIVATE;
g_variant_get (parameters, "(@a{sa{sv}}&o&o)", &settings, &device_path, &specific_object_path);
+ }
if (options) {
GVariantIter iter;
@@ -5526,6 +5557,7 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj,
incompl_conn,
_async_op_complete_ac_auth_cb,
_async_op_data_new_ac_auth_add_and_activate (self,
+ async_op_type,
active,
invocation,
incompl_conn,
@@ -7887,6 +7919,7 @@ static const NMDBusInterfaceInfoExtended interface_info_manager = {
.out_args = NM_DEFINE_GDBUS_ARG_INFOS (
NM_DEFINE_GDBUS_ARG_INFO ("path", "o"),
NM_DEFINE_GDBUS_ARG_INFO ("active_connection", "o"),
+ NM_DEFINE_GDBUS_ARG_INFO ("result", "a{sv}"),
),
),
.handle = impl_manager_add_and_activate_connection,
diff --git a/tools/test-networkmanager-service.py b/tools/test-networkmanager-service.py
index 76601d0172..7d9eceb848 100755
--- a/tools/test-networkmanager-service.py
+++ b/tools/test-networkmanager-service.py
@@ -1341,15 +1341,14 @@ class NetworkManager(ExportedObj):
@dbus.service.method(dbus_interface=IFACE_NM, in_signature='a{sa{sv}}oo', out_signature='oo')
def AddAndActivateConnection(self, con_hash, devpath, specific_object):
- return self.AddAndActivateConnection2(con_hash, devpath, specific_object, dict())
+ conpath, acpath, result = self.AddAndActivateConnection2(con_hash, devpath, specific_object, dict())
+ return (conpath, acpath)
- @dbus.service.method(dbus_interface=IFACE_NM, in_signature='a{sa{sv}}ooa{sv}', out_signature='oo')
+ @dbus.service.method(dbus_interface=IFACE_NM, in_signature='a{sa{sv}}ooa{sv}', out_signature='ooa{sv}')
def AddAndActivateConnection2(self, con_hash, devpath, specific_object, options):
- # TODO: Do some processing of the "options" parameter.
-
device = self.find_device_first(path = devpath, require = BusErr.UnknownDeviceException)
conpath = gl.settings.AddConnection(con_hash)
- return (conpath, self.ActivateConnection(conpath, devpath, specific_object))
+ return (conpath, self.ActivateConnection(conpath, devpath, specific_object), [])
@dbus.service.method(dbus_interface=IFACE_NM, in_signature='o', out_signature='')
def DeactivateConnection(self, active_connection):