summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-12-05 21:07:31 +0100
committerThomas Haller <thaller@redhat.com>2017-12-05 21:07:31 +0100
commit632e693251715526817b6fb27872df66b23595a4 (patch)
treeb2d8c5946633f9da0cc2ef37326fc9208d8c4fe4
parent9b23f972900acb0734f27564c9edefaf8f2a4245 (diff)
parent35dc6421de78cffd1761cfb6edf9e94233f99966 (diff)
downloadNetworkManager-632e693251715526817b6fb27872df66b23595a4.tar.gz
core: merge branch 'th/user-block-autoconnect-rh1401515'
https://bugzilla.redhat.com/show_bug.cgi?id=1401515
-rw-r--r--Makefile.am4
-rw-r--r--Makefile.examples1
-rwxr-xr-xexamples/python/gi/nm-connection-update-stable-id.py116
-rw-r--r--introspection/org.freedesktop.NetworkManager.Settings.Connection.xml38
-rw-r--r--libnm-core/nm-dbus-interface.h44
-rw-r--r--libnm-core/nm-errors.h2
-rw-r--r--libnm/libnm.ver3
-rw-r--r--libnm/nm-remote-connection.c170
-rw-r--r--libnm/nm-remote-connection.h13
-rw-r--r--shared/nm-utils/nm-macros-internal.h2
-rw-r--r--src/devices/bluetooth/nm-bluez-device.c3
-rw-r--r--src/devices/nm-device.c6
-rw-r--r--src/nm-active-connection.c3
-rw-r--r--src/nm-checkpoint.c12
-rw-r--r--src/nm-manager.c308
-rw-r--r--src/nm-policy.c25
-rw-r--r--src/settings/nm-settings-connection.c653
-rw-r--r--src/settings/nm-settings-connection.h64
-rw-r--r--src/settings/nm-settings.c29
-rw-r--r--src/settings/nm-settings.h2
-rw-r--r--src/settings/plugins/ibft/nms-ibft-connection.c11
-rw-r--r--src/settings/plugins/ifcfg-rh/nm-inotify-helper.c (renamed from src/settings/nm-inotify-helper.c)0
-rw-r--r--src/settings/plugins/ifcfg-rh/nm-inotify-helper.h (renamed from src/settings/nm-inotify-helper.h)13
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c71
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c11
-rw-r--r--src/settings/plugins/ifnet/nms-ifnet-connection.c17
-rw-r--r--src/settings/plugins/ifnet/nms-ifnet-plugin.c11
-rw-r--r--src/settings/plugins/ifupdown/nms-ifupdown-plugin.c10
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-connection.c15
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-plugin.c11
30 files changed, 1082 insertions, 586 deletions
diff --git a/Makefile.am b/Makefile.am
index 3f60ea5b3f..1a3d8b134b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1503,8 +1503,6 @@ src_libNetworkManager_la_SOURCES = \
\
src/settings/nm-agent-manager.c \
src/settings/nm-agent-manager.h \
- src/settings/nm-inotify-helper.c \
- src/settings/nm-inotify-helper.h \
src/settings/nm-secret-agent.c \
src/settings/nm-secret-agent.h \
src/settings/nm-settings-connection.c \
@@ -2021,6 +2019,8 @@ src_settings_plugins_ifcfg_rh_libnms_ifcfg_rh_core_la_SOURCES = \
src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-common.h \
src/settings/plugins/ifcfg-rh/shvar.c \
src/settings/plugins/ifcfg-rh/shvar.h \
+ src/settings/plugins/ifcfg-rh/nm-inotify-helper.c \
+ src/plugins/ifcfg-rh/settings/nm-inotify-helper.h \
src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c \
src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h \
src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c \
diff --git a/Makefile.examples b/Makefile.examples
index fc08851ca6..79f2482d9f 100644
--- a/Makefile.examples
+++ b/Makefile.examples
@@ -173,6 +173,7 @@ EXTRA_DIST += \
examples/python/gi/get-active-connections.py \
examples/python/gi/get_ips.py \
examples/python/gi/list-connections.py \
+ examples/python/gi/nm-connection-update-stable-id.py \
examples/python/gi/setting-user-data.py \
examples/python/gi/show-wifi-networks.py \
examples/python/gi/update-ip4-method.py \
diff --git a/examples/python/gi/nm-connection-update-stable-id.py b/examples/python/gi/nm-connection-update-stable-id.py
new file mode 100755
index 0000000000..ad852f7712
--- /dev/null
+++ b/examples/python/gi/nm-connection-update-stable-id.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python
+# -*- Mode: Python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+# vim: ft=python ts=4 sts=4 sw=4 et ai
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright 2017 Red Hat, Inc.
+#
+
+#
+# This example updates a connection's stable-id by appending -#number.
+
+import sys
+import re
+
+import gi
+gi.require_version('NM', '1.0')
+from gi.repository import GLib, NM
+
+def usage():
+ print('Usage: %s [[id] <id>]' % (sys.argv[0]))
+ print(' %s [[uuid] <uuid>]' % (sys.argv[0]))
+ return 1
+
+def find_connection(nm_client, arg_type, arg_id):
+ for c in nm_client.get_connections():
+ if arg_type in [None, 'id'] and c.get_id() == arg_id:
+ return c
+ if arg_type in [None, 'uuid'] and c.get_uuid() == arg_id:
+ return c
+
+def main():
+ if len(sys.argv) < 2 or len(sys.argv) > 3:
+ return usage()
+ if len(sys.argv) == 3:
+ arg_type = sys.argv[1]
+ arg_id = sys.argv[2]
+ if arg_type not in ['id', 'uuid']:
+ return usage()
+ else:
+ arg_type = None
+ arg_id = sys.argv[1]
+ arg_log = '%s"%s"' % ((' with %s ' % (arg_type)) if arg_type else '', arg_id)
+
+ main_loop = GLib.MainLoop()
+
+ nm_client = NM.Client.new(None)
+
+ con = find_connection(nm_client, arg_type, arg_id)
+ if con is None:
+ print('could not find a connection %s' % (arg_log))
+ return 1
+
+ s_con = con.get_setting_connection()
+ if s_con is None:
+ print('connection %s has no [connection] setting' % (arg_log))
+ return 1
+
+ arg_log = '"%s" (%s)' % (s_con.get_id(), s_con.get_uuid())
+
+ stable_id = s_con.get_stable_id()
+ if not stable_id:
+ print('connection %s has no stable-id set' % (arg_log))
+ return 1
+
+ re_match = re.search('\A(.*)-([0-9]+)\Z', stable_id)
+ if not re_match:
+ stable_id = stable_id + '-1'
+ else:
+ stable_id = re_match.group(1) + '-' + str(int(re_match.group(2)) + 1)
+
+ con2 = NM.SimpleConnection.new_clone(con)
+ s_con = con2.get_setting_connection()
+ s_con.set_property(NM.SETTING_CONNECTION_STABLE_ID, stable_id)
+
+ result = {}
+ def _update2_cb(con, async_result, user_data):
+ try:
+ r = con.update2_finish(async_result)
+ except Exception as e:
+ result['error'] = e
+ else:
+ result['result'] = r
+ main_loop.quit()
+
+ con.update2(con2.to_dbus(NM.ConnectionSerializationFlags.ALL),
+ NM.SettingsUpdate2Flags.BLOCK_AUTOCONNECT,
+ None,
+ None,
+ _update2_cb,
+ None)
+
+ main_loop.run()
+
+ if 'error' in result:
+ print('update connection %s failed: %s' % (arg_log, result['error']))
+ return 1
+
+ print('update connection %s succeeded: %s' % (arg_log, result['result']))
+ print('set stable-id to "%s"' % (stable_id))
+ return 0
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/introspection/org.freedesktop.NetworkManager.Settings.Connection.xml b/introspection/org.freedesktop.NetworkManager.Settings.Connection.xml
index 61bd26ddc6..ec596fd1e9 100644
--- a/introspection/org.freedesktop.NetworkManager.Settings.Connection.xml
+++ b/introspection/org.freedesktop.NetworkManager.Settings.Connection.xml
@@ -102,6 +102,44 @@
<signal name="Updated"/>
<!--
+ Update2:
+ @settings: New connection settings, properties, and (optionally) secrets.
+ Provide an empty array, to use the current settings.
+ @flags: optional flags argument. Currently supported flags are:
+ "0x1" (to-disk),
+ "0x2" (in-memory),
+ "0x4" (in-memory-detached),
+ "0x8" (in-memory-only),
+ "0x10" (volatile),
+ "0x20" (block-autoconnect).
+ Unknown flags cause the call to fail.
+ @args: optional arguments dictionary, for extensibility. Currently no
+ arguments are accepted. Specifying unknown keys causes the call
+ to fail.
+ @result: output argument, currently no results are returned.
+
+ Update the connection with new settings and properties (replacing all
+ previous settings and properties). If the flag 0x1 is present,
+ the connection is persisted to disk. If the flag 0x2 is present,
+ the change is only made in memory (without touching an eventual
+ profile on disk). If neither 0x1 nor 0x2 is set, the change is made
+ in memory only, if the connection is already in memory only.
+ Secrets may be part of the update request, and will be either stored in persistent
+ storage or sent to a Secret Agent for storage, depending on the flags
+ associated with each secret.
+
+ Update2 is a extensible alternative to Update, UpdateUnsaved and Save.
+
+ Since: 1.12
+ -->
+ <method name="Update2">
+ <arg name="settings" type="a{sa{sv}}" direction="in"/>
+ <arg name="flags" type="u" direction="in"/>
+ <arg name="args" type="a{sv}" direction="in"/>
+ <arg name="result" type="a{sv}" direction="out"/>
+ </method>
+
+ <!--
Removed:
Emitted when this connection is no longer available. This happens when the
diff --git a/libnm-core/nm-dbus-interface.h b/libnm-core/nm-dbus-interface.h
index 6a0d3def2a..4c586d5d8d 100644
--- a/libnm-core/nm-dbus-interface.h
+++ b/libnm-core/nm-dbus-interface.h
@@ -896,4 +896,48 @@ typedef enum { /*< flags >*/
NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES = (1LL << 5),
} NMActivationStateFlags;
+/**
+ * NMSettingsUpdate2Flags:
+ * @NM_SETTINGS_UPDATE2_FLAG_NONE: an alias for numeric zero, no flags set.
+ * @NM_SETTINGS_UPDATE2_FLAG_TO_DISK: to persist the connection to disk.
+ * @NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY: to make the connection in-memory only.
+ * If the connection was previously persistent, the corresponding file on disk
+ * is not deleted but merely the connection is decoupled from the file
+ * on disk. If you later delete an in-memory connection, the connection
+ * on disk will be deleted as well.
+ * @NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED: this is like @NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY,
+ * but if the connection has a corresponding file on disk, the association between
+ * the connection and the file is forgotten but the file is not modified.
+ * The difference to %NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY is if you later
+ * save the connection again to disk, a new file name will be chosen without
+ * overwriting the remaining file on disk. Also, if you delete the connection
+ * later, the file on disk will not be deleted.
+ * @NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY: this is like @NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY,
+ * but if the connection has a corresponding file on disk, the file on
+ * disk will be deleted.
+ * @NM_SETTINGS_UPDATE2_FLAG_VOLATILE: This can be specified with either
+ * %NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED or %NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY.
+ * After making the connection in-memory only, the connection is marked
+ * as volatile. That means, if the connection is currently not active
+ * it will be deleted right away. Otherwise, it is marked to for deletion
+ * once the connection deactivates. A volatile connection cannot autoactivate
+ * again (because it's about to be deleted), but a manual activation will
+ * clear the volatile flag.
+ * @NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT: usually, when the connection
+ * has autoconnect enabled and is modified, it becomes elegible to autoconnect
+ * right away. Setting this flag, disables autoconnect until the connection
+ * is manually activated.
+ *
+ * Since: 1.12
+ */
+typedef enum { /*< flags >*/
+ NM_SETTINGS_UPDATE2_FLAG_NONE = 0,
+ NM_SETTINGS_UPDATE2_FLAG_TO_DISK = (1LL << 0),
+ NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY = (1LL << 1),
+ NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED = (1LL << 2),
+ NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY = (1LL << 3),
+ NM_SETTINGS_UPDATE2_FLAG_VOLATILE = (1LL << 4),
+ NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT = (1LL << 5),
+} NMSettingsUpdate2Flags;
+
#endif /* __NM_DBUS_INTERFACE_H__ */
diff --git a/libnm-core/nm-errors.h b/libnm-core/nm-errors.h
index 6bacc8da56..bdd6c2234f 100644
--- a/libnm-core/nm-errors.h
+++ b/libnm-core/nm-errors.h
@@ -261,6 +261,7 @@ GQuark nm_secret_agent_error_quark (void);
* @NM_SETTINGS_ERROR_READ_ONLY_CONNECTION: attempted to modify a read-only connection
* @NM_SETTINGS_ERROR_UUID_EXISTS: a connection with that UUID already exists
* @NM_SETTINGS_ERROR_INVALID_HOSTNAME: attempted to set an invalid hostname
+ * @NM_SETTINGS_ERROR_INVALID_ARGUMENTS: invalid arguments
*
* Errors related to the settings/persistent configuration interface of
* NetworkManager.
@@ -277,6 +278,7 @@ typedef enum {
NM_SETTINGS_ERROR_READ_ONLY_CONNECTION, /*< nick=ReadOnlyConnection >*/
NM_SETTINGS_ERROR_UUID_EXISTS, /*< nick=UuidExists >*/
NM_SETTINGS_ERROR_INVALID_HOSTNAME, /*< nick=InvalidHostname >*/
+ NM_SETTINGS_ERROR_INVALID_ARGUMENTS, /*< nick=InvalidArguments >*/
} NMSettingsError;
GQuark nm_settings_error_quark (void);
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index aad581698b..06e5e4c8d7 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -1235,6 +1235,8 @@ global:
nm_client_checkpoint_rollback_async;
nm_client_checkpoint_rollback_finish;
nm_client_get_checkpoints;
+ nm_remote_connection_update2;
+ nm_remote_connection_update2_finish;
nm_setting_team_add_runner_tx_hash;
nm_setting_team_get_mcast_rejoin_count;
nm_setting_team_get_mcast_rejoin_interval;
@@ -1260,4 +1262,5 @@ global:
nm_setting_team_remove_runner_tx_hash_by_value;
nm_setting_vpn_get_data_keys;
nm_setting_vpn_get_secret_keys;
+ nm_settings_update2_flags_get_type;
} libnm_1_10_0;
diff --git a/libnm/nm-remote-connection.c b/libnm/nm-remote-connection.c
index 5cd42555f5..3f6ebb3b20 100644
--- a/libnm/nm-remote-connection.c
+++ b/libnm/nm-remote-connection.c
@@ -67,6 +67,111 @@ typedef struct {
/*****************************************************************************/
+static void
+update2_cb (GObject *proxy, GAsyncResult *result, gpointer user_data)
+{
+ GSimpleAsyncResult *simple = user_data;
+ GError *error = NULL;
+ GVariant *v;
+
+ if (nmdbus_settings_connection_call_update2_finish (NMDBUS_SETTINGS_CONNECTION (proxy),
+ &v,
+ result,
+ &error))
+ g_simple_async_result_set_op_res_gpointer (simple,
+ v,
+ (GDestroyNotify) g_variant_unref);
+ else {
+ g_dbus_error_strip_remote_error (error);
+ g_simple_async_result_take_error (simple, error);
+ }
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+}
+
+/**
+ * nm_remote_connection_update2:
+ * @connection: the #NMRemoteConnection
+ * @settings: (allow-none): optional connection to update the settings.
+ * @flags: update-flags
+ * @args: (allow-none): optional arguments.
+ * @cancellable: a #GCancellable, or %NULL
+ * @callback: callback to be called when the commit operation completes
+ * @user_data: caller-specific data passed to @callback
+ *
+ * Asynchronously calls the Update2() D-Bus method.
+ *
+ * Since: 1.12
+ **/
+void
+nm_remote_connection_update2 (NMRemoteConnection *connection,
+ GVariant *settings,
+ NMSettingsUpdate2Flags flags,
+ GVariant *args,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ NMRemoteConnectionPrivate *priv;
+ GSimpleAsyncResult *simple;
+ GVariantBuilder builder;
+
+ g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection));
+ g_return_if_fail (!settings || g_variant_is_of_type (settings, NM_VARIANT_TYPE_CONNECTION));
+ g_return_if_fail (!args || g_variant_is_of_type (args, G_VARIANT_TYPE ("a{sv}")));
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection);
+
+ simple = g_simple_async_result_new (G_OBJECT (connection), callback, user_data,
+ nm_remote_connection_update2);
+
+ if (!settings) {
+ g_variant_builder_init (&builder, NM_VARIANT_TYPE_CONNECTION);
+ settings = g_variant_builder_end (&builder);
+ }
+ if (!args) {
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
+ args = g_variant_builder_end (&builder);
+ }
+ nmdbus_settings_connection_call_update2 (priv->proxy,
+ settings,
+ flags,
+ args,
+ cancellable,
+ update2_cb,
+ simple);
+}
+
+/**
+ * nm_remote_connection_update2_finish:
+ * @connection: the #NMRemoteConnection
+ * @result: the result passed to the #GAsyncReadyCallback
+ * @error: location for a #GError, or %NULL
+ *
+ * Gets the result of a call to nm_remote_connection_commit_changes_async().
+ *
+ * Returns: on success, a #GVariant of type "a{sv}" with the result. On failure,
+ * %NULL.
+ **/
+GVariant *
+nm_remote_connection_update2_finish (NMRemoteConnection *connection,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (connection), nm_remote_connection_update2), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ if (g_simple_async_result_propagate_error (simple, error))
+ return NULL;
+ else
+ return g_variant_ref (g_simple_async_result_get_op_res_gpointer (simple));
+}
+
+/*****************************************************************************/
+
/**
* nm_remote_connection_commit_changes:
* @connection: the #NMRemoteConnection
@@ -87,23 +192,25 @@ nm_remote_connection_commit_changes (NMRemoteConnection *connection,
GError **error)
{
NMRemoteConnectionPrivate *priv;
- GVariant *settings;
+ gs_unref_variant GVariant *result = NULL;
gboolean ret;
+ GVariantBuilder args;
g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), FALSE);
priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection);
- settings = nm_connection_to_dbus (NM_CONNECTION (connection), NM_CONNECTION_SERIALIZE_ALL);
- if (save_to_disk) {
- ret = nmdbus_settings_connection_call_update_sync (priv->proxy,
- settings,
- cancellable, error);
- } else {
- ret = nmdbus_settings_connection_call_update_unsaved_sync (priv->proxy,
- settings,
- cancellable, error);
- }
+ g_variant_builder_init (&args, G_VARIANT_TYPE ("a{sv}"));
+ ret = nmdbus_settings_connection_call_update2_sync (priv->proxy,
+ nm_connection_to_dbus (NM_CONNECTION (connection),
+ NM_CONNECTION_SERIALIZE_ALL),
+ save_to_disk
+ ? NM_SETTINGS_UPDATE2_FLAG_TO_DISK
+ : NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY,
+ g_variant_builder_end (&args),
+ &result,
+ cancellable,
+ error);
if (error && *error)
g_dbus_error_strip_remote_error (*error);
return ret;
@@ -113,11 +220,13 @@ static void
update_cb (GObject *proxy, GAsyncResult *result, gpointer user_data)
{
GSimpleAsyncResult *simple = user_data;
- gboolean (*finish_func) (NMDBusSettingsConnection *, GAsyncResult *, GError **);
GError *error = NULL;
+ gs_unref_variant GVariant *v = NULL;
- finish_func = g_object_get_data (G_OBJECT (simple), "finish_func");
- if (finish_func (NMDBUS_SETTINGS_CONNECTION (proxy), result, &error))
+ if (nmdbus_settings_connection_call_update2_finish (NMDBUS_SETTINGS_CONNECTION (proxy),
+ &v,
+ result,
+ &error))
g_simple_async_result_set_op_res_gboolean (simple, TRUE);
else {
g_dbus_error_strip_remote_error (error);
@@ -149,7 +258,7 @@ nm_remote_connection_commit_changes_async (NMRemoteConnection *connection,
{
NMRemoteConnectionPrivate *priv;
GSimpleAsyncResult *simple;
- GVariant *settings;
+ GVariantBuilder args;
g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection));
@@ -158,22 +267,17 @@ nm_remote_connection_commit_changes_async (NMRemoteConnection *connection,
simple = g_simple_async_result_new (G_OBJECT (connection), callback, user_data,
nm_remote_connection_commit_changes_async);
- settings = nm_connection_to_dbus (NM_CONNECTION (connection), NM_CONNECTION_SERIALIZE_ALL);
- if (save_to_disk) {
- g_object_set_data (G_OBJECT (simple), "finish_func",
- nmdbus_settings_connection_call_update_finish);
- nmdbus_settings_connection_call_update (priv->proxy,
- settings,
- cancellable,
- update_cb, simple);
- } else {
- g_object_set_data (G_OBJECT (simple), "finish_func",
- nmdbus_settings_connection_call_update_unsaved_finish);
- nmdbus_settings_connection_call_update_unsaved (priv->proxy,
- settings,
- cancellable,
- update_cb, simple);
- }
+ g_variant_builder_init (&args, G_VARIANT_TYPE ("a{sv}"));
+ nmdbus_settings_connection_call_update2 (priv->proxy,
+ nm_connection_to_dbus (NM_CONNECTION (connection),
+ NM_CONNECTION_SERIALIZE_ALL),
+ save_to_disk
+ ? NM_SETTINGS_UPDATE2_FLAG_TO_DISK
+ : NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY,
+ g_variant_builder_end (&args),
+ cancellable,
+ update_cb,
+ simple);
}
/**
@@ -202,6 +306,8 @@ nm_remote_connection_commit_changes_finish (NMRemoteConnection *connection,
return g_simple_async_result_get_op_res_gboolean (simple);
}
+/*****************************************************************************/
+
/**
* nm_remote_connection_save:
* @connection: the #NMRemoteConnection
@@ -302,6 +408,8 @@ nm_remote_connection_save_finish (NMRemoteConnection *connection,
return g_simple_async_result_get_op_res_gboolean (simple);
}
+/*****************************************************************************/
+
/**
* nm_remote_connection_delete:
* @connection: the #NMRemoteConnection
diff --git a/libnm/nm-remote-connection.h b/libnm/nm-remote-connection.h
index c04ae36779..1e7d7618b5 100644
--- a/libnm/nm-remote-connection.h
+++ b/libnm/nm-remote-connection.h
@@ -60,6 +60,19 @@ typedef struct {
GType nm_remote_connection_get_type (void);
+NM_AVAILABLE_IN_1_12
+void nm_remote_connection_update2 (NMRemoteConnection *connection,
+ GVariant *settings,
+ NMSettingsUpdate2Flags flags,
+ GVariant *args,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+NM_AVAILABLE_IN_1_12
+GVariant *nm_remote_connection_update2_finish (NMRemoteConnection *connection,
+ GAsyncResult *result,
+ GError **error);
+
gboolean nm_remote_connection_commit_changes (NMRemoteConnection *connection,
gboolean save_to_disk,
GCancellable *cancellable,
diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h
index cf9142fe99..8005375c9d 100644
--- a/shared/nm-utils/nm-macros-internal.h
+++ b/shared/nm-utils/nm-macros-internal.h
@@ -577,7 +577,7 @@ _NM_IN_STRSET_streq (const char *x, const char *s)
/* NM_CACHED_QUARK_FCN() is essentially the same as G_DEFINE_QUARK
* with two differences:
- * - @string must be a quited string-literal
+ * - @string must be a quoted string-literal
* - @fcn must be the full function name, while G_DEFINE_QUARK() appends
* "_quark" to the function name.
* Both properties of G_DEFINE_QUARK() are non favorable, because you can no
diff --git a/src/devices/bluetooth/nm-bluez-device.c b/src/devices/bluetooth/nm-bluez-device.c
index 182527d9f5..bd3cf18a67 100644
--- a/src/devices/bluetooth/nm-bluez-device.c
+++ b/src/devices/bluetooth/nm-bluez-device.c
@@ -1185,7 +1185,8 @@ dispose (GObject *object)
if (priv->pan_connection) {
/* Check whether we want to remove the created connection. If so, we take a reference
* and delete it at the end of dispose(). */
- if (nm_settings_connection_get_nm_generated (NM_SETTINGS_CONNECTION (priv->pan_connection)))
+ if (NM_FLAGS_HAS (nm_settings_connection_get_flags (NM_SETTINGS_CONNECTION (priv->pan_connection)),
+ NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED))
to_delete = g_object_ref (priv->pan_connection);
priv->pan_connection = NULL;
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 2e034cc47a..f79b85e8c2 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -10174,7 +10174,8 @@ nm_device_set_ip4_config (NMDevice *self,
if ( nm_device_sys_iface_state_is_external (self)
&& (settings_connection = nm_device_get_settings_connection (self))
- && nm_settings_connection_get_nm_generated (settings_connection)
+ && NM_FLAGS_HAS (nm_settings_connection_get_flags (settings_connection),
+ NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED)
&& nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (priv->act_request)) == NM_ACTIVATION_TYPE_EXTERNAL) {
NMSetting *s_ip4;
@@ -10345,7 +10346,8 @@ nm_device_set_ip6_config (NMDevice *self,
if ( nm_device_sys_iface_state_is_external (self)
&& (settings_connection = nm_device_get_settings_connection (self))
- && nm_settings_connection_get_nm_generated (settings_connection)
+ && NM_FLAGS_HAS (nm_settings_connection_get_flags (settings_connection),
+ NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED)
&& nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (priv->act_request)) == NM_ACTIVATION_TYPE_EXTERNAL) {
NMSetting *s_ip6;
diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c
index c27f6548eb..2286a74b4f 100644
--- a/src/nm-active-connection.c
+++ b/src/nm-active-connection.c
@@ -866,7 +866,8 @@ _settings_connection_notify_flags (NMSettingsConnection *settings_connection,
nm_assert (nm_active_connection_get_activation_type (self) == NM_ACTIVATION_TYPE_EXTERNAL);
nm_assert (NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->settings_connection == settings_connection);
- if (nm_settings_connection_get_nm_generated (settings_connection))
+ if (NM_FLAGS_HAS (nm_settings_connection_get_flags (settings_connection),
+ NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED))
return;
_set_activation_type_managed (self);
diff --git a/src/nm-checkpoint.c b/src/nm-checkpoint.c
index af56bf26e6..5bde924c27 100644
--- a/src/nm-checkpoint.c
+++ b/src/nm-checkpoint.c
@@ -254,12 +254,12 @@ activate:
if (need_update) {
_LOGD ("rollback: updating connection %s",
nm_settings_connection_get_uuid (connection));
- nm_connection_replace_settings_from_connection (NM_CONNECTION (connection),
- dev_checkpoint->settings_connection);
- nm_settings_connection_commit_changes (connection,
- NULL,
- NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
- NULL);
+ nm_settings_connection_update (connection,
+ dev_checkpoint->settings_connection,
+ NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK,
+ NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
+ "checkpoint-rollback",
+ NULL);
}
} else {
/* The connection was deleted, recreate it */
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 871ed310f1..04d17f9b23 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -62,41 +62,7 @@
#include "introspection/org.freedesktop.NetworkManager.h"
#include "introspection/org.freedesktop.NetworkManager.Device.h"
-static gboolean add_device (NMManager *self, NMDevice *device, GError **error);
-
-static NMActiveConnection *_new_active_connection (NMManager *self,
- NMConnection *connection,
- NMConnection *applied,
- const char *specific_object,
- NMDevice *device,
- NMAuthSubject *subject,
- NMActivationType activation_type,
- GError **error);
-
-static void policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data);
-
-static gboolean find_master (NMManager *self,
- NMConnection *connection,
- NMDevice *device,
- NMSettingsConnection **out_master_connection,
- NMDevice **out_master_device,
- NMActiveConnection **out_master_ac,
- GError **error);
-
-static void nm_manager_update_state (NMManager *manager);
-
-static void connection_changed (NMManager *self, NMConnection *connection);
-static void device_sleep_cb (NMDevice *device,
- GParamSpec *pspec,
- NMManager *self);
-
-static void settings_startup_complete_changed (NMSettings *settings,
- GParamSpec *pspec,
- NMManager *self);
-
-static void retry_connections_for_parent_device (NMManager *self, NMDevice *device);
-
-static NM_CACHED_QUARK_FCN ("active-connection-add-and-activate", active_connection_add_and_activate_quark)
+/*****************************************************************************/
typedef struct {
gboolean user_enabled;
@@ -109,6 +75,51 @@ typedef struct {
const char *hw_prop;
} RadioState;
+enum {
+ DEVICE_ADDED,
+ INTERNAL_DEVICE_ADDED,
+ DEVICE_REMOVED,
+ INTERNAL_DEVICE_REMOVED,
+ STATE_CHANGED,
+ CHECK_PERMISSIONS,
+ ACTIVE_CONNECTION_ADDED,
+ ACTIVE_CONNECTION_REMOVED,
+ CONFIGURE_QUIT,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+NM_GOBJECT_PROPERTIES_DEFINE (NMManager,
+ PROP_VERSION,
+ PROP_CAPABILITIES,
+ PROP_STATE,
+ PROP_STARTUP,
+ PROP_NETWORKING_ENABLED,
+ PROP_WIRELESS_ENABLED,
+ PROP_WIRELESS_HARDWARE_ENABLED,
+ PROP_WWAN_ENABLED,
+ PROP_WWAN_HARDWARE_ENABLED,
+ PROP_WIMAX_ENABLED,
+ PROP_WIMAX_HARDWARE_ENABLED,
+ PROP_ACTIVE_CONNECTIONS,
+ PROP_CONNECTIVITY,
+ PROP_CONNECTIVITY_CHECK_AVAILABLE,
+ PROP_CONNECTIVITY_CHECK_ENABLED,
+ PROP_PRIMARY_CONNECTION,
+ PROP_PRIMARY_CONNECTION_TYPE,
+ PROP_ACTIVATING_CONNECTION,
+ PROP_DEVICES,
+ PROP_METERED,
+ PROP_GLOBAL_DNS_CONFIGURATION,
+ PROP_ALL_DEVICES,
+ PROP_CHECKPOINTS,
+
+ /* Not exported */
+ PROP_SLEEPING,
+);
+
typedef struct {
NMPlatform *platform;
@@ -166,6 +177,9 @@ typedef struct {
bool sleeping:1;
bool net_enabled:1;
+
+ guint delete_volatile_connection_idle_id;
+ CList delete_volatile_connection_lst_head;
} NMManagerPrivate;
struct _NMManager {
@@ -181,50 +195,7 @@ G_DEFINE_TYPE (NMManager, nm_manager, NM_TYPE_EXPORTED_OBJECT)
#define NM_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMManager, NM_IS_MANAGER)
-enum {
- DEVICE_ADDED,
- INTERNAL_DEVICE_ADDED,
- DEVICE_REMOVED,
- INTERNAL_DEVICE_REMOVED,
- STATE_CHANGED,
- CHECK_PERMISSIONS,
- ACTIVE_CONNECTION_ADDED,
- ACTIVE_CONNECTION_REMOVED,
- CONFIGURE_QUIT,
-
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-NM_GOBJECT_PROPERTIES_DEFINE (NMManager,
- PROP_VERSION,
- PROP_CAPABILITIES,
- PROP_STATE,
- PROP_STARTUP,
- PROP_NETWORKING_ENABLED,
- PROP_WIRELESS_ENABLED,
- PROP_WIRELESS_HARDWARE_ENABLED,
- PROP_WWAN_ENABLED,
- PROP_WWAN_HARDWARE_ENABLED,
- PROP_WIMAX_ENABLED,
- PROP_WIMAX_HARDWARE_ENABLED,
- PROP_ACTIVE_CONNECTIONS,
- PROP_CONNECTIVITY,
- PROP_CONNECTIVITY_CHECK_AVAILABLE,
- PROP_CONNECTIVITY_CHECK_ENABLED,
- PROP_PRIMARY_CONNECTION,
- PROP_PRIMARY_CONNECTION_TYPE,
- PROP_ACTIVATING_CONNECTION,
- PROP_DEVICES,
- PROP_METERED,
- PROP_GLOBAL_DNS_CONFIGURATION,
- PROP_ALL_DEVICES,
- PROP_CHECKPOINTS,
-
- /* Not exported */
- PROP_SLEEPING,
-);
+/*****************************************************************************/
NM_DEFINE_SINGLETON_INSTANCE (NMManager);
@@ -297,7 +268,39 @@ NM_DEFINE_SINGLETON_INSTANCE (NMManager);
/*****************************************************************************/
-static NM_CACHED_QUARK_FCN ("autoconnect-root", autoconnect_root_quark)
+static gboolean add_device (NMManager *self, NMDevice *device, GError **error);
+
+static NMActiveConnection *_new_active_connection (NMManager *self,
+ NMConnection *connection,
+ NMConnection *applied,
+ const char *specific_object,
+ NMDevice *device,
+ NMAuthSubject *subject,
+ NMActivationType activation_type,
+ GError **error);
+
+static void policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data);
+
+static gboolean find_master (NMManager *self,
+ NMConnection *connection,
+ NMDevice *device,
+ NMSettingsConnection **out_master_connection,
+ NMDevice **out_master_device,
+ NMActiveConnection **out_master_ac,
+ GError **error);
+
+static void nm_manager_update_state (NMManager *manager);
+
+static void connection_changed (NMManager *self, NMConnection *connection);
+static void device_sleep_cb (NMDevice *device,
+ GParamSpec *pspec,
+ NMManager *self);
+
+static void settings_startup_complete_changed (NMSettings *settings,
+ GParamSpec *pspec,
+ NMManager *self);
+
+static void retry_connections_for_parent_device (NMManager *self, NMDevice *device);
static void active_connection_state_changed (NMActiveConnection *active,
GParamSpec *pspec,
@@ -309,12 +312,47 @@ static void active_connection_parent_active (NMActiveConnection *active,
NMActiveConnection *parent_ac,
NMManager *self);
+static NMActiveConnection *active_connection_find_first (NMManager *self,
+ NMSettingsConnection *settings_connection,
+ const char *uuid,
+ NMActiveConnectionState max_state);
+
+/*****************************************************************************/
+
+static NM_CACHED_QUARK_FCN ("active-connection-add-and-activate", active_connection_add_and_activate_quark)
+
+static NM_CACHED_QUARK_FCN ("autoconnect-root", autoconnect_root_quark)
+
+/*****************************************************************************/
+
+static void
+_delete_volatile_connection_do (NMManager *self,
+ NMSettingsConnection *connection)
+{
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
+
+ if (!NM_FLAGS_HAS (nm_settings_connection_get_flags (connection),
+ NM_SETTINGS_CONNECTION_FLAGS_VOLATILE))
+ return;
+ if (active_connection_find_first (self,
+ connection,
+ NULL,
+ NM_ACTIVE_CONNECTION_STATE_DEACTIVATED))
+ return;
+ if (!nm_settings_has_connection (priv->settings, connection))
+ return;
+
+ _LOGD (LOGD_DEVICE, "volatile connection disconnected. Deleting connection '%s' (%s)",
+ nm_settings_connection_get_id (connection), nm_settings_connection_get_uuid (connection));
+ nm_settings_connection_delete (connection, NULL);
+}
+
/* Returns: whether to notify D-Bus of the removal or not */
static gboolean
active_connection_remove (NMManager *self, NMActiveConnection *active)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- NMSettingsConnection *connection;
+ gs_unref_object NMSettingsConnection *connection = NULL;
gboolean notify;
nm_assert (NM_IS_ACTIVE_CONNECTION (active));
@@ -328,22 +366,12 @@ active_connection_remove (NMManager *self, NMActiveConnection *active)
g_signal_handlers_disconnect_by_func (active, active_connection_default_changed, self);
g_signal_handlers_disconnect_by_func (active, active_connection_parent_active, self);
- if ( (connection = nm_active_connection_get_settings_connection (active))
- && nm_settings_connection_get_volatile (connection))
- g_object_ref (connection);
- else
- connection = NULL;
+ connection = nm_g_object_ref (nm_active_connection_get_settings_connection (active));
nm_exported_object_clear_and_unexport (&active);
- if (connection) {
- if (nm_settings_has_connection (priv->settings, connection)) {
- _LOGD (LOGD_DEVICE, "assumed connection disconnected. Deleting generated connection '%s' (%s)",
- nm_settings_connection_get_id (connection), nm_settings_connection_get_uuid (connection));
- nm_settings_connection_delete (connection, NULL);
- }
- g_object_unref (connection);
- }
+ if (connection)
+ _delete_volatile_connection_do (self, connection);
return notify;
}
@@ -498,7 +526,8 @@ _get_activatable_connections_filter (NMSettings *settings,
NMSettingsConnection *connection,
gpointer user_data)
{
- if (nm_settings_connection_get_volatile (connection))
+ if (NM_FLAGS_HAS (nm_settings_connection_get_flags (connection),
+ NM_SETTINGS_CONNECTION_FLAGS_VOLATILE))
return FALSE;
return !active_connection_find_first (user_data, connection, NULL, NM_ACTIVE_CONNECTION_STATE_DEACTIVATING);
}
@@ -1473,6 +1502,74 @@ connection_updated_cb (NMSettings *settings,
connection_changed (self, connection);
}
+/*****************************************************************************/
+
+typedef struct {
+ CList delete_volatile_connection_lst;
+ NMSettingsConnection *connection;
+} DeleteVolatileConnectionData;
+
+static void
+_delete_volatile_connection_all (NMManager *self, gboolean do_delete)
+{
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
+ CList *lst;
+ DeleteVolatileConnectionData *data;
+
+ while ((lst = c_list_first (&priv->delete_volatile_connection_lst_head))) {
+ gs_unref_object NMSettingsConnection *connection = NULL;
+
+ data = c_list_entry (lst,
+ DeleteVolatileConnectionData,
+ delete_volatile_connection_lst);
+ connection = data->connection;
+ c_list_unlink_stale (&data->delete_volatile_connection_lst);
+ g_slice_free (DeleteVolatileConnectionData, data);
+
+ if (do_delete)
+ _delete_volatile_connection_do (self, connection);
+ }
+}
+
+static gboolean
+_delete_volatile_connection_cb (gpointer user_data)
+{
+ NMManager *self = user_data;
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
+
+ priv->delete_volatile_connection_idle_id = 0;
+ _delete_volatile_connection_all (self, TRUE);
+ return G_SOURCE_REMOVE;
+}
+
+static void
+connection_flags_changed (NMSettings *settings,
+ NMSettingsConnection *connection,
+ gpointer user_data)
+{
+ NMManager *self = user_data;
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
+ DeleteVolatileConnectionData *data;
+
+ if (!NM_FLAGS_HAS (nm_settings_connection_get_flags (connection),
+ NM_SETTINGS_CONNECTION_FLAGS_VOLATILE))
+ return;
+
+ if (active_connection_find_first (self, connection, NULL, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED)) {
+ /* the connection still have an active-connection. It will be purged
+ * when the active connection(s) get(s) removed. */
+ return;
+ }
+
+ data = g_slice_new (DeleteVolatileConnectionData);
+ data->connection = g_object_ref (connection);
+ c_list_link_tail (&priv->delete_volatile_connection_lst_head, &data->delete_volatile_connection_lst);
+ if (!priv->delete_volatile_connection_idle_id)
+ priv->delete_volatile_connection_idle_id = g_idle_add (_delete_volatile_connection_cb, self);
+}
+
+/*****************************************************************************/
+
static void
system_unmanaged_devices_changed_cb (NMSettings *settings,
GParamSpec *pspec,
@@ -3876,6 +3973,9 @@ _activation_auth_done (NMActiveConnection *active,
if (success) {
if (_internal_activate_generic (self, active, &error)) {
+ nm_settings_connection_autoconnect_blocked_reason_set (connection,
+ NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST,
+ FALSE);
g_dbus_method_invocation_return_value (context,
g_variant_new ("(o)",
nm_exported_object_get_path (NM_EXPORTED_OBJECT (active))));
@@ -4019,10 +4119,12 @@ activation_add_done (NMSettings *settings,
nm_active_connection_set_settings_connection (active, new_connection);
if (_internal_activate_generic (self, active, &local)) {
- nm_settings_connection_commit_changes (new_connection,
- NULL,
- NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION | NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED,
- NULL);
+ nm_settings_connection_update (new_connection,
+ NULL,
+ NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK,
+ 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)",
@@ -6087,6 +6189,7 @@ constructed (GObject *object)
G_CALLBACK (connection_added_cb), self);
g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED,
G_CALLBACK (connection_updated_cb), self);
+ g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_FLAGS_CHANGED, G_CALLBACK (connection_flags_changed), self);
priv->hostname_manager = g_object_ref (nm_hostname_manager_get ());
g_signal_connect (priv->hostname_manager, "notify::" NM_HOSTNAME_MANAGER_HOSTNAME,
@@ -6145,6 +6248,7 @@ nm_manager_init (NMManager *self)
c_list_init (&priv->link_cb_lst);
c_list_init (&priv->active_connections_lst_head);
+ c_list_init (&priv->delete_volatile_connection_lst_head);
priv->platform = g_object_ref (NM_PLATFORM_GET);
@@ -6405,6 +6509,11 @@ dispose (GObject *object)
CList *iter, *iter_safe;
NMActiveConnection *ac, *ac_safe;
+ nm_clear_g_source (&priv->delete_volatile_connection_idle_id);
+ _delete_volatile_connection_all (self, FALSE);
+ nm_assert (!priv->delete_volatile_connection_idle_id);
+ nm_assert (c_list_is_empty (&priv->delete_volatile_connection_lst_head));
+
g_signal_handlers_disconnect_by_func (priv->platform,
G_CALLBACK (platform_link_cb),
self);
@@ -6459,6 +6568,7 @@ dispose (GObject *object)
g_signal_handlers_disconnect_by_func (priv->settings, system_unmanaged_devices_changed_cb, self);
g_signal_handlers_disconnect_by_func (priv->settings, connection_added_cb, self);
g_signal_handlers_disconnect_by_func (priv->settings, connection_updated_cb, self);
+ g_signal_handlers_disconnect_by_func (priv->settings, connection_flags_changed, self);
g_clear_object (&priv->settings);
}
diff --git a/src/nm-policy.c b/src/nm-policy.c
index 5a0b148cd5..81a19feee7 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -1224,8 +1224,7 @@ auto_activate_device (NMPolicy *self,
NMSettingConnection *s_con;
const char *permission;
- if ( !nm_settings_connection_is_visible (candidate)
- || nm_settings_connection_autoconnect_is_blocked (candidate))
+ if (nm_settings_connection_autoconnect_is_blocked (candidate))
continue;
s_con = nm_connection_get_setting_connection (NM_CONNECTION (candidate));
@@ -2375,16 +2374,18 @@ connection_removed (NMSettings *settings,
}
static void
-connection_visibility_changed (NMSettings *settings,
- NMSettingsConnection *connection,
- gpointer user_data)
+connection_flags_changed (NMSettings *settings,
+ NMSettingsConnection *connection,
+ gpointer user_data)
{
NMPolicyPrivate *priv = user_data;
NMPolicy *self = _PRIV_TO_SELF (priv);
- if (nm_settings_connection_is_visible (connection))
- schedule_activate_all (self);
- else
+ if (NM_FLAGS_HAS (nm_settings_connection_get_flags (connection),
+ NM_SETTINGS_CONNECTION_FLAGS_VISIBLE)) {
+ if (!nm_settings_connection_autoconnect_is_blocked (connection))
+ schedule_activate_all (self);
+ } else
_deactivate_if_active (self, connection);
}
@@ -2560,10 +2561,10 @@ constructed (GObject *object)
g_signal_connect (priv->manager, NM_MANAGER_ACTIVE_CONNECTION_ADDED, (GCallback) active_connection_added, priv);
g_signal_connect (priv->manager, NM_MANAGER_ACTIVE_CONNECTION_REMOVED, (GCallback) active_connection_removed, priv);
- g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_ADDED, (GCallback) connection_added, priv);
- g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, (GCallback) connection_updated, priv);
- g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, (GCallback) connection_removed, priv);
- g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED, (GCallback) connection_visibility_changed, priv);
+ g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_ADDED, (GCallback) connection_added, priv);
+ g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, (GCallback) connection_updated, priv);
+ g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, (GCallback) connection_removed, priv);
+ g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_FLAGS_CHANGED, (GCallback) connection_flags_changed, priv);
g_signal_connect (priv->agent_mgr, NM_AGENT_MANAGER_AGENT_REGISTERED, G_CALLBACK (secret_agent_registered), self);
diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c
index 9b289f9f21..3afe7de820 100644
--- a/src/settings/nm-settings-connection.c
+++ b/src/settings/nm-settings-connection.c
@@ -53,7 +53,6 @@
static void nm_settings_connection_connection_interface_init (NMConnectionInterface *iface);
NM_GOBJECT_PROPERTIES_DEFINE (NMSettingsConnection,
- PROP_VISIBLE,
PROP_UNSAVED,
PROP_READY,
PROP_FLAGS,
@@ -75,14 +74,11 @@ typedef struct _NMSettingsConnectionPrivate {
NMSessionMonitor *session_monitor;
gulong session_changed_id;
- NMSettingsConnectionFlags flags;
+ NMSettingsConnectionFlags flags:5;
bool removed:1;
bool ready:1;
- /* Is this connection visible by some session? */
- bool visible:1;
-
bool timestamp_set:1;
NMSettingsAutoconnectBlockedReason autoconnect_blocked_reason:4;
@@ -323,20 +319,9 @@ find_secret (NMConnection *self,
static void
set_visible (NMSettingsConnection *self, gboolean new_visible)
{
- NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
-
- if (new_visible == priv->visible)
- return;
- priv->visible = new_visible;
- _notify (self, PROP_VISIBLE);
-}
-
-gboolean
-nm_settings_connection_is_visible (NMSettingsConnection *self)
-{
- g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE);
-
- return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->visible;
+ nm_settings_connection_set_flags (self,
+ NM_SETTINGS_CONNECTION_FLAGS_VISIBLE,
+ new_visible);
}
void
@@ -404,7 +389,8 @@ nm_settings_connection_check_permission (NMSettingsConnection *self,
priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
- if (priv->visible == FALSE)
+ if (!NM_FLAGS_HAS (nm_settings_connection_get_flags (self),
+ NM_SETTINGS_CONNECTION_FLAGS_VISIBLE))
return FALSE;
s_con = nm_connection_get_setting_connection (NM_CONNECTION (self));
@@ -502,33 +488,82 @@ secrets_cleared_cb (NMSettingsConnection *self)
}
static void
-set_unsaved (NMSettingsConnection *self, gboolean now_unsaved)
+set_persist_mode (NMSettingsConnection *self, NMSettingsConnectionPersistMode persist_mode)
{
- NMSettingsConnectionFlags flags = nm_settings_connection_get_flags (self);
+ NMSettingsConnectionFlags flags = NM_SETTINGS_CONNECTION_FLAGS_NONE;
+ const NMSettingsConnectionFlags ALL = NM_SETTINGS_CONNECTION_FLAGS_UNSAVED
+ | NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED
+ | NM_SETTINGS_CONNECTION_FLAGS_VOLATILE;
- if (NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_FLAGS_UNSAVED) != !!now_unsaved) {
- if (now_unsaved)
- flags |= NM_SETTINGS_CONNECTION_FLAGS_UNSAVED;
- else {
- flags &= ~(NM_SETTINGS_CONNECTION_FLAGS_UNSAVED |
- NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED |
- NM_SETTINGS_CONNECTION_FLAGS_VOLATILE);
- }
- nm_settings_connection_set_flags_all (self, flags);
+ if (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP)
+ return;
+
+ switch (persist_mode) {
+ case NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK:
+ flags = NM_SETTINGS_CONNECTION_FLAGS_NONE;
+ break;
+ case NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY:
+ case NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED:
+ case NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY:
+ flags = NM_SETTINGS_CONNECTION_FLAGS_UNSAVED;
+ break;
+ case NM_SETTINGS_CONNECTION_PERSIST_MODE_VOLATILE_DETACHED:
+ case NM_SETTINGS_CONNECTION_PERSIST_MODE_VOLATILE_ONLY:
+ flags = NM_SETTINGS_CONNECTION_FLAGS_UNSAVED |
+ NM_SETTINGS_CONNECTION_FLAGS_VOLATILE;
+ break;
+ case NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP:
+ g_return_if_reached ();
}
+
+ nm_settings_connection_set_flags_full (self, ALL, flags);
}
static void
connection_changed_cb (NMSettingsConnection *self, gpointer unused)
{
- set_unsaved (self, TRUE);
+ set_persist_mode (self, NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY);
_emit_updated (self, FALSE);
}
-gboolean
-nm_settings_connection_replace_settings_prepare (NMSettingsConnection *self,
- NMConnection *new_connection,
- GError **error)
+static gboolean
+_delete (NMSettingsConnection *self, GError **error)
+{
+ NMSettingsConnectionClass *klass;
+ GError *local = NULL;
+ const char *filename;
+
+ nm_assert (NM_IS_SETTINGS_CONNECTION (self));
+
+ klass = NM_SETTINGS_CONNECTION_GET_CLASS (self);
+ if (!klass->delete) {
+ g_set_error (&local,
+ NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_FAILED,
+ "delete not supported");
+ goto fail;
+ }
+ if (!klass->delete (self,
+ &local))
+ goto fail;
+
+ filename = nm_settings_connection_get_filename (self);
+ if (filename) {
+ _LOGD ("delete: success deleting connection (\"%s\")", filename);
+ nm_settings_connection_set_filename (self, NULL);
+ } else
+ _LOGT ("delete: success deleting connection (no-file)");
+ return TRUE;
+fail:
+ _LOGD ("delete: failure deleting connection: %s", local->message);
+ g_propagate_error (error, local);
+ return FALSE;
+}
+
+static gboolean
+_update_prepare (NMSettingsConnection *self,
+ NMConnection *new_connection,
+ GError **error)
{
NMSettingsConnectionPrivate *priv;
@@ -553,173 +588,137 @@ nm_settings_connection_replace_settings_prepare (NMSettingsConnection *self,
}
gboolean
-nm_settings_connection_replace_settings_full (NMSettingsConnection *self,
- NMConnection *new_connection,
- gboolean prepare_new_connection,
- gboolean update_unsaved,
- const char *log_diff_name,
- GError **error)
+nm_settings_connection_update (NMSettingsConnection *self,
+ NMConnection *new_connection,
+ NMSettingsConnectionPersistMode persist_mode,
+ NMSettingsConnectionCommitReason commit_reason,
+ const char *log_diff_name,
+ GError **error)
{
NMSettingsConnectionPrivate *priv;
+ NMSettingsConnectionClass *klass = NULL;
+ gs_unref_object NMConnection *reread_connection = NULL;
+ NMConnection *replace_connection;
+ gboolean replaced = FALSE;
+ gs_free char *logmsg_change = NULL;
+ GError *local = NULL;
+ gboolean save_to_disk;
g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE);
- g_return_val_if_fail (NM_IS_CONNECTION (new_connection), FALSE);
priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
- if ( prepare_new_connection
- && !nm_settings_connection_replace_settings_prepare (self,
- new_connection,
- error))
- return FALSE;
+ save_to_disk = (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK)
+ || ( persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP
+ && !nm_settings_connection_get_unsaved (self));
+
+ if (save_to_disk) {
+ klass = NM_SETTINGS_CONNECTION_GET_CLASS (self);
+ if (!klass->commit_changes) {
+ g_set_error (&local,
+ NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_FAILED,
+ "writing settings not supported");
+ goto out;
+ }
+ }
- /* Do nothing if there's nothing to update */
- if (nm_connection_compare (NM_CONNECTION (self),
- new_connection,
- NM_SETTING_COMPARE_FLAG_EXACT)) {
- return TRUE;
+ if ( new_connection
+ && !_update_prepare (self,
+ new_connection,
+ &local))
+ goto out;
+
+ if (save_to_disk) {
+ if (!klass->commit_changes (self,
+ new_connection ?: NM_CONNECTION (self),
+ commit_reason,
+ &reread_connection,
+ &logmsg_change,
+ &local))
+ goto out;
+
+ if ( reread_connection
+ && !_update_prepare (self,
+ reread_connection,
+ &local))
+ goto out;
}
+ replace_connection = reread_connection ?: new_connection;
+
/* Disconnect the changed signal to ensure we don't set Unsaved when
* it's not required.
*/
g_signal_handlers_block_by_func (self, G_CALLBACK (connection_changed_cb), NULL);
- if (log_diff_name)
- nm_utils_log_connection_diff (new_connection, NM_CONNECTION (self), LOGL_DEBUG, LOGD_CORE, log_diff_name, "++ ");
+ /* Do nothing if there's nothing to update */
+ if ( replace_connection
+ && !nm_connection_compare (NM_CONNECTION (self),
+ replace_connection,
+ NM_SETTING_COMPARE_FLAG_EXACT)) {
+ if (log_diff_name)
+ nm_utils_log_connection_diff (replace_connection, NM_CONNECTION (self), LOGL_DEBUG, LOGD_CORE, log_diff_name, "++ ");
- nm_connection_replace_settings_from_connection (NM_CONNECTION (self), new_connection);
+ nm_connection_replace_settings_from_connection (NM_CONNECTION (self), replace_connection);
- _LOGD ("replace settings from connection %p (%s)", new_connection, nm_connection_get_id (NM_CONNECTION (self)));
+ replaced = TRUE;
+ }
nm_settings_connection_set_flags (self,
NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED | NM_SETTINGS_CONNECTION_FLAGS_VOLATILE,
FALSE);
- /* Cache the just-updated system secrets in case something calls
- * nm_connection_clear_secrets() and clears them.
- */
- update_system_secrets_cache (self);
+ if (replaced) {
+ /* Cache the just-updated system secrets in case something calls
+ * nm_connection_clear_secrets() and clears them.
+ */
+ update_system_secrets_cache (self);
- /* Add agent and always-ask secrets back; they won't necessarily be
- * in the replacement connection data if it was eg reread from disk.
- */
- if (priv->agent_secrets) {
- GVariant *dict;
+ /* Add agent and always-ask secrets back; they won't necessarily be
+ * in the replacement connection data if it was eg reread from disk.
+ */
+ if (priv->agent_secrets) {
+ GVariant *dict;
- dict = nm_connection_to_dbus (priv->agent_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS);
- if (dict) {
- (void) nm_connection_update_secrets (NM_CONNECTION (self), NULL, dict, NULL);
- g_variant_unref (dict);
+ dict = nm_connection_to_dbus (priv->agent_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS);
+ if (dict) {
+ (void) nm_connection_update_secrets (NM_CONNECTION (self), NULL, dict, NULL);
+ g_variant_unref (dict);
+ }
}
}
nm_settings_connection_recheck_visibility (self);
- /* Manually emit changed signal since we disconnected the handler, but
- * only update Unsaved if the caller wanted us to.
- */
- if (update_unsaved)
- set_unsaved (self, TRUE);
+ set_persist_mode (self, persist_mode);
+
+ if (NM_IN_SET (persist_mode, NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY,
+ NM_SETTINGS_CONNECTION_PERSIST_MODE_VOLATILE_ONLY))
+ _delete (self, NULL);
+ else if (NM_IN_SET (persist_mode, NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED,
+ NM_SETTINGS_CONNECTION_PERSIST_MODE_VOLATILE_DETACHED))
+ nm_settings_connection_set_filename (self, NULL);
g_signal_handlers_unblock_by_func (self, G_CALLBACK (connection_changed_cb), NULL);
_emit_updated (self, TRUE);
- return TRUE;
-}
-
-/* Update the settings of this connection to match that of 'new_connection',
- * taking care to make a private copy of secrets.
- */
-gboolean
-nm_settings_connection_replace_settings (NMSettingsConnection *self,
- NMConnection *new_connection,
- gboolean update_unsaved,
- const char *log_diff_name,
- GError **error)
-{
- return nm_settings_connection_replace_settings_full (self,
- new_connection,
- TRUE,
- update_unsaved,
- log_diff_name,
- error);
-}
-
-gboolean
-nm_settings_connection_commit_changes (NMSettingsConnection *self,
- NMConnection *new_connection,
- NMSettingsConnectionCommitReason commit_reason,
- GError **error)
-{
- NMSettingsConnectionClass *klass;
- gs_free_error GError *local = NULL;
- gs_unref_object NMConnection *reread_connection = NULL;
- gs_free char *logmsg_change = NULL;
-
- g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE);
-
- klass = NM_SETTINGS_CONNECTION_GET_CLASS (self);
- if (!klass->commit_changes) {
- _LOGW ("write: setting plugin %s does not support to write connection",
- G_OBJECT_TYPE_NAME (self));
- g_set_error (error,
- NM_SETTINGS_ERROR,
- NM_SETTINGS_ERROR_FAILED,
- "writing settings not supported");
- return FALSE;
- }
-
- if ( new_connection
- && !nm_settings_connection_replace_settings_prepare (self,
- new_connection,
- &local)) {
- _LOGW ("write: failed to prepare connection for writing: %s",
- local->message);
- g_propagate_error (error, g_steal_pointer (&local));
+out:
+ if (local) {
+ _LOGI ("write: failure to update connection: %s", local->message);
+ g_propagate_error (error, local);
return FALSE;
}
- if (!klass->commit_changes (self,
- new_connection,
- commit_reason,
- &reread_connection,
- &logmsg_change,
- &local)) {
- _LOGW ("write: failure to write setting: %s",
- local->message);
- g_propagate_error (error, g_steal_pointer (&local));
- return FALSE;
+ if (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK) {
+ if (reread_connection)
+ _LOGI ("write: successfully updated (%s), connection was modified in the process", logmsg_change);
+ else if (new_connection)
+ _LOGI ("write: successfully updated (%s)", logmsg_change);
+ else
+ _LOGI ("write: successfully commited (%s)", logmsg_change);
}
-
- if (reread_connection || new_connection) {
- if (!nm_settings_connection_replace_settings_full (self,
- reread_connection ?: new_connection,
- !reread_connection,
- FALSE,
- new_connection
- ? "update-during-write"
- : "replace-and-commit-disk",
- &local)) {
- /* this can't really happen, because at this point replace-settings
- * is no longer supposed to fail. It's a bug. */
- _LOGE ("write: replacing setting failed: %s",
- local->message);
- g_propagate_error (error, g_steal_pointer (&local));
- g_return_val_if_reached (FALSE);
- }
- }
-
- set_unsaved (self, FALSE);
-
- if (reread_connection)
- _LOGI ("write: successfully updated (%s), connection was modified in the process", logmsg_change);
- else if (new_connection)
- _LOGI ("write: successfully updated (%s)", logmsg_change);
- else
- _LOGI ("write: successfully commited (%s)", logmsg_change);
-
return TRUE;
}
@@ -764,25 +763,14 @@ nm_settings_connection_delete (NMSettingsConnection *self,
GError **error)
{
gs_unref_object NMSettingsConnection *self_keep_alive = NULL;
- NMSettingsConnectionClass *klass;
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
NMConnection *for_agents;
g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE);
- klass = NM_SETTINGS_CONNECTION_GET_CLASS (self);
-
self_keep_alive = g_object_ref (self);
- if (!klass->delete) {
- g_set_error (error,
- NM_SETTINGS_ERROR,
- NM_SETTINGS_ERROR_FAILED,
- "delete not supported");
- return FALSE;
- }
- if (!klass->delete (self,
- error))
+ if (!_delete (self, error))
return FALSE;
set_visible (self, FALSE);
@@ -997,10 +985,12 @@ nm_settings_connection_new_secrets (NMSettingsConnection *self,
update_system_secrets_cache (self);
update_agent_secrets_cache (self, NULL);
- nm_settings_connection_commit_changes (self,
- NULL,
- NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
- NULL);
+ nm_settings_connection_update (self,
+ NULL,
+ NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK,
+ NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
+ "new-secrets",
+ NULL);
return TRUE;
}
@@ -1114,10 +1104,12 @@ get_secrets_done_cb (NMAgentManager *manager,
setting_name,
call_id);
- nm_settings_connection_commit_changes (self,
- NULL,
- NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
- NULL);
+ nm_settings_connection_update (self,
+ NULL,
+ NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK,
+ NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
+ "get-new-secrets",
+ NULL);
} else {
_LOGD ("(%s:%p) new agent secrets processed",
setting_name,
@@ -1585,8 +1577,9 @@ typedef struct {
NMAgentManager *agent_mgr;
NMAuthSubject *subject;
NMConnection *new_settings;
- gboolean save_to_disk;
+ NMSettingsUpdate2Flags flags;
char *audit_args;
+ bool is_update2:1;
} UpdateInfo;
static void
@@ -1650,7 +1643,13 @@ update_complete (NMSettingsConnection *self,
{
if (error)
g_dbus_method_invocation_return_gerror (info->context, error);
- else
+ else if (info->is_update2) {
+ GVariantBuilder result;
+
+ g_variant_builder_init (&result, G_VARIANT_TYPE ("a{sv}"));
+ g_dbus_method_invocation_return_value (info->context,
+ g_variant_new ("(@a{sv})", g_variant_builder_end (&result)));
+ } else
g_dbus_method_invocation_return_value (info->context, NULL);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_UPDATE, self, !error, info->audit_args,
@@ -1673,6 +1672,8 @@ update_auth_cb (NMSettingsConnection *self,
UpdateInfo *info = data;
NMSettingsConnectionCommitReason commit_reason;
gs_free_error GError *local = NULL;
+ NMSettingsConnectionPersistMode persist_mode;
+ const char *log_diff_name;
if (error) {
update_complete (self, info, error);
@@ -1693,7 +1694,9 @@ update_auth_cb (NMSettingsConnection *self,
*/
update_agent_secrets_cache (self, info->new_settings);
}
+ }
+ if (info->new_settings) {
if (nm_audit_manager_audit_enabled (nm_audit_manager_get ())) {
gs_unref_hashtable GHashTable *diff = NULL;
gboolean same;
@@ -1707,36 +1710,47 @@ update_auth_cb (NMSettingsConnection *self,
}
}
- if (!info->save_to_disk) {
- if (info->new_settings) {
- nm_settings_connection_replace_settings (self,
- info->new_settings,
- TRUE,
- "replace-unsaved",
- &local);
- }
- goto out;
- }
-
- if (info->new_settings) {
- if (!nm_settings_connection_replace_settings_prepare (self,
- info->new_settings,
- &local))
- goto out;
- }
-
commit_reason = NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION;
if ( info->new_settings
&& !nm_streq0 (nm_connection_get_id (NM_CONNECTION (self)),
nm_connection_get_id (info->new_settings)))
commit_reason |= NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED;
- nm_settings_connection_commit_changes (self,
- info->new_settings,
- commit_reason,
- &local);
+ if (NM_FLAGS_HAS (info->flags, NM_SETTINGS_UPDATE2_FLAG_TO_DISK))
+ persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK;
+ else if (NM_FLAGS_HAS (info->flags, NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY))
+ persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY;
+ else if (NM_FLAGS_HAS (info->flags, NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED)) {
+ persist_mode = NM_FLAGS_HAS (info->flags, NM_SETTINGS_UPDATE2_FLAG_VOLATILE)
+ ? NM_SETTINGS_CONNECTION_PERSIST_MODE_VOLATILE_DETACHED
+ : NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED;
+ } else if (NM_FLAGS_HAS (info->flags, NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY)) {
+ persist_mode = NM_FLAGS_HAS (info->flags, NM_SETTINGS_UPDATE2_FLAG_VOLATILE)
+ ? NM_SETTINGS_CONNECTION_PERSIST_MODE_VOLATILE_ONLY
+ : NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY;
+ } else
+ persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP;
+
+ if ( persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK
+ || ( persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP
+ && !nm_settings_connection_get_unsaved (self)))
+ log_diff_name = info->new_settings ? "update-settings" : "write-out-to-disk";
+ else
+ log_diff_name = info->new_settings ? "update-unsaved" : "make-unsaved";
+
+ if (NM_FLAGS_HAS (info->flags, NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT)) {
+ nm_settings_connection_autoconnect_blocked_reason_set (self,
+ NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST,
+ TRUE);
+ }
+
+ nm_settings_connection_update (self,
+ info->new_settings,
+ persist_mode,
+ commit_reason,
+ log_diff_name,
+ &local);
-out:
if (!local) {
gs_unref_object NMConnection *for_agent = NULL;
@@ -1785,10 +1799,11 @@ get_update_modify_permission (NMConnection *old, NMConnection *new)
}
static void
-settings_connection_update_helper (NMSettingsConnection *self,
- GDBusMethodInvocation *context,
- GVariant *new_settings,
- gboolean save_to_disk)
+settings_connection_update (NMSettingsConnection *self,
+ gboolean is_update2,
+ GDBusMethodInvocation *context,
+ GVariant *new_settings,
+ NMSettingsUpdate2Flags flags)
{
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
NMAuthSubject *subject = NULL;
@@ -1798,8 +1813,6 @@ settings_connection_update_helper (NMSettingsConnection *self,
const char *permission;
char *error_desc = NULL;
- g_assert (new_settings != NULL || save_to_disk == TRUE);
-
/* If the connection is read-only, that has to be changed at the source of
* the problem (ex a system settings plugin that can't write connections out)
* instead of over D-Bus.
@@ -1809,12 +1822,22 @@ settings_connection_update_helper (NMSettingsConnection *self,
/* Check if the settings are valid first */
if (new_settings) {
- tmp = _nm_simple_connection_new_from_dbus (new_settings,
- NM_SETTING_PARSE_FLAGS_STRICT
- | NM_SETTING_PARSE_FLAGS_NORMALIZE,
- &error);
- if (!tmp)
+ if (!g_variant_is_of_type (new_settings, NM_VARIANT_TYPE_CONNECTION)) {
+ g_set_error_literal (&error,
+ NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_INVALID_ARGUMENTS,
+ "settings is of invalid type");
goto error;
+ }
+
+ if (g_variant_n_children (new_settings) > 0) {
+ tmp = _nm_simple_connection_new_from_dbus (new_settings,
+ NM_SETTING_PARSE_FLAGS_STRICT
+ | NM_SETTING_PARSE_FLAGS_NORMALIZE,
+ &error);
+ if (!tmp)
+ goto error;
+ }
}
subject = _new_auth_subject (context, &error);
@@ -1836,10 +1859,11 @@ settings_connection_update_helper (NMSettingsConnection *self,
}
info = g_slice_new0 (UpdateInfo);
+ info->is_update2 = is_update2;
info->context = context;
info->agent_mgr = g_object_ref (priv->agent_mgr);
info->subject = subject;
- info->save_to_disk = save_to_disk;
+ info->flags = flags;
info->new_settings = tmp;
permission = get_update_modify_permission (NM_CONNECTION (self),
@@ -1862,7 +1886,7 @@ impl_settings_connection_update (NMSettingsConnection *self,
GDBusMethodInvocation *context,
GVariant *new_settings)
{
- settings_connection_update_helper (self, context, new_settings, TRUE);
+ settings_connection_update (self, FALSE, context, new_settings, NM_SETTINGS_UPDATE2_FLAG_TO_DISK);
}
static void
@@ -1870,14 +1894,76 @@ impl_settings_connection_update_unsaved (NMSettingsConnection *self,
GDBusMethodInvocation *context,
GVariant *new_settings)
{
- settings_connection_update_helper (self, context, new_settings, FALSE);
+ settings_connection_update (self, FALSE, context, new_settings, NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY);
}
static void
impl_settings_connection_save (NMSettingsConnection *self,
GDBusMethodInvocation *context)
{
- settings_connection_update_helper (self, context, NULL, TRUE);
+ settings_connection_update (self, FALSE, context, NULL, NM_SETTINGS_UPDATE2_FLAG_TO_DISK);
+}
+
+static void
+impl_settings_connection_update2 (NMSettingsConnection *self,
+ GDBusMethodInvocation *context,
+ GVariant *settings,
+ guint32 flags_u,
+ GVariant *args)
+{
+ GError *error = NULL;
+ GVariantIter iter;
+ const char *args_name;
+ const NMSettingsUpdate2Flags flags = (NMSettingsUpdate2Flags) flags_u;
+ const NMSettingsUpdate2Flags ALL_PERSIST_MODES = NM_SETTINGS_UPDATE2_FLAG_TO_DISK
+ | NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY
+ | NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED
+ | NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY;
+
+ if (NM_FLAGS_ANY (flags_u, ~((guint32) (ALL_PERSIST_MODES |
+ NM_SETTINGS_UPDATE2_FLAG_VOLATILE |
+ NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT)))) {
+ error = g_error_new_literal (NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_INVALID_ARGUMENTS,
+ "Unknown flags");
+ g_dbus_method_invocation_take_error (context, error);
+ return;
+ }
+
+ if ( ( NM_FLAGS_ANY (flags, ALL_PERSIST_MODES)
+ && !nm_utils_is_power_of_two (flags & ALL_PERSIST_MODES))
+ || ( NM_FLAGS_HAS (flags, NM_SETTINGS_UPDATE2_FLAG_VOLATILE)
+ && !NM_FLAGS_ANY (flags, NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED |
+ NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY))) {
+ error = g_error_new_literal (NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_INVALID_ARGUMENTS,
+ "Conflicting flags");
+ g_dbus_method_invocation_take_error (context, error);
+ return;
+ }
+
+ if (!g_variant_is_of_type (args, G_VARIANT_TYPE ("a{sv}"))) {
+ error = g_error_new_literal (NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_INVALID_ARGUMENTS,
+ "args is of invalid type");
+ g_dbus_method_invocation_take_error (context, error);
+ return;
+ }
+
+ g_variant_iter_init (&iter, args);
+ while (g_variant_iter_next (&iter, "{&sv}", &args_name, NULL)) {
+ error = g_error_new (NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_INVALID_ARGUMENTS,
+ "Unsupported argument '%s'", args_name);
+ g_dbus_method_invocation_take_error (context, error);
+ return;
+ }
+
+ settings_connection_update (self,
+ TRUE,
+ context,
+ settings,
+ flags);
}
static void
@@ -2055,10 +2141,12 @@ dbus_clear_secrets_auth_cb (NMSettingsConnection *self,
nm_connection_get_path (NM_CONNECTION (self)),
NM_CONNECTION (self));
- nm_settings_connection_commit_changes (self,
- NULL,
- NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
- &local);
+ nm_settings_connection_update (self,
+ NULL,
+ NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK,
+ NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
+ "clear-secrets",
+ &local);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, self,
!local, NULL, subject, local ? local->message : NULL);
@@ -2115,6 +2203,14 @@ nm_settings_connection_get_unsaved (NMSettingsConnection *self)
/*****************************************************************************/
+NM_UTILS_FLAGS2STR_DEFINE_STATIC (_settings_connection_flags_to_string, NMSettingsConnectionFlags,
+ NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_FLAGS_NONE, "none"),
+ NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_FLAGS_UNSAVED, "unsaved"),
+ NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED, "nm-generatd"),
+ NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_FLAGS_VOLATILE, "volatile"),
+ NM_UTILS_FLAGS2STR (NM_SETTINGS_CONNECTION_FLAGS_VISIBLE, "visible"),
+);
+
NMSettingsConnectionFlags
nm_settings_connection_get_flags (NMSettingsConnection *self)
{
@@ -2126,35 +2222,38 @@ nm_settings_connection_get_flags (NMSettingsConnection *self)
NMSettingsConnectionFlags
nm_settings_connection_set_flags (NMSettingsConnection *self, NMSettingsConnectionFlags flags, gboolean set)
{
- NMSettingsConnectionFlags new_flags;
-
- g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NM_SETTINGS_CONNECTION_FLAGS_NONE);
- g_return_val_if_fail ((flags & ~NM_SETTINGS_CONNECTION_FLAGS_ALL) == 0, NM_SETTINGS_CONNECTION_FLAGS_NONE);
-
- new_flags = NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->flags;
- if (set)
- new_flags |= flags;
- else
- new_flags &= ~flags;
- return nm_settings_connection_set_flags_all (self, new_flags);
+ return nm_settings_connection_set_flags_full (self,
+ flags,
+ set ? flags : NM_SETTINGS_CONNECTION_FLAGS_NONE);
}
NMSettingsConnectionFlags
-nm_settings_connection_set_flags_all (NMSettingsConnection *self, NMSettingsConnectionFlags flags)
+nm_settings_connection_set_flags_full (NMSettingsConnection *self,
+ NMSettingsConnectionFlags mask,
+ NMSettingsConnectionFlags value)
{
NMSettingsConnectionPrivate *priv;
NMSettingsConnectionFlags old_flags;
g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NM_SETTINGS_CONNECTION_FLAGS_NONE);
- g_return_val_if_fail ((flags & ~NM_SETTINGS_CONNECTION_FLAGS_ALL) == 0, NM_SETTINGS_CONNECTION_FLAGS_NONE);
+ nm_assert (mask && !NM_FLAGS_ANY (mask, ~NM_SETTINGS_CONNECTION_FLAGS_ALL));
+ nm_assert (!NM_FLAGS_ANY (value, ~mask));
+
priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
+ value = (priv->flags & ~mask) | value;
+
old_flags = priv->flags;
- if (old_flags != flags) {
- _LOGT ("update settings-connection flags to 0x%x (was 0x%x)", (guint) flags, (guint) priv->flags);
- priv->flags = flags;
+ if (old_flags != value) {
+ char buf1[255], buf2[255];
+
+ _LOGT ("update settings-connection flags to %s (was %s)",
+ _settings_connection_flags_to_string (value, buf1, sizeof (buf1)),
+ _settings_connection_flags_to_string (priv->flags, buf2, sizeof (buf2)));
+ priv->flags = value;
+ nm_assert (priv->flags == value);
_notify (self, PROP_FLAGS);
- if (NM_FLAGS_HAS (old_flags, NM_SETTINGS_CONNECTION_FLAGS_UNSAVED) != NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_FLAGS_UNSAVED))
+ if (NM_FLAGS_HAS (old_flags, NM_SETTINGS_CONNECTION_FLAGS_UNSAVED) != NM_FLAGS_HAS (value, NM_SETTINGS_CONNECTION_FLAGS_UNSAVED))
_notify (self, PROP_UNSAVED);
}
return old_flags;
@@ -2670,45 +2769,29 @@ nm_settings_connection_autoconnect_blocked_reason_set_full (NMSettingsConnection
gboolean
nm_settings_connection_autoconnect_is_blocked (NMSettingsConnection *self)
{
- NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
+ NMSettingsConnectionPrivate *priv;
+ NMSettingsConnectionFlags flags;
- return priv->autoconnect_blocked_reason != NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE
- || priv->autoconnect_retries == 0;
-}
+ g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), TRUE);
-/*****************************************************************************/
+ priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
-/**
- * nm_settings_connection_get_nm_generated:
- * @self: an #NMSettingsConnection
- *
- * Gets the "nm-generated" flag on @self.
- *
- * A connection is "nm-generated" if it was generated by
- * nm_device_generate_connection() and has not been modified or
- * saved by the user since then.
- */
-gboolean
-nm_settings_connection_get_nm_generated (NMSettingsConnection *self)
-{
- return NM_FLAGS_HAS (nm_settings_connection_get_flags (self), NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED);
-}
+ if (priv->autoconnect_blocked_reason != NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE)
+ return TRUE;
+ if (priv->autoconnect_retries == 0)
+ return TRUE;
-/**
- * nm_settings_connection_get_volatile:
- * @self: an #NMSettingsConnection
- *
- * Gets the "volatile" flag on @self.
- *
- * The connection is marked as volatile and will be removed when
- * it disconnects.
- */
-gboolean
-nm_settings_connection_get_volatile (NMSettingsConnection *self)
-{
- return NM_FLAGS_HAS (nm_settings_connection_get_flags (self), NM_SETTINGS_CONNECTION_FLAGS_VOLATILE);
+ flags = priv->flags;
+ if (NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_FLAGS_VOLATILE))
+ return TRUE;
+ if (!NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_FLAGS_VISIBLE))
+ return TRUE;
+
+ return FALSE;
}
+/*****************************************************************************/
+
gboolean
nm_settings_connection_get_ready (NMSettingsConnection *self)
{
@@ -2789,7 +2872,6 @@ nm_settings_connection_init (NMSettingsConnection *self)
priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnectionPrivate);
self->_priv = priv;
- priv->visible = FALSE;
priv->ready = TRUE;
c_list_init (&priv->call_ids_lst_head);
@@ -2867,12 +2949,8 @@ get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
NMSettingsConnection *self = NM_SETTINGS_CONNECTION (object);
- NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
switch (prop_id) {
- case PROP_VISIBLE:
- g_value_set_boolean (value, priv->visible);
- break;
case PROP_UNSAVED:
g_value_set_boolean (value, nm_settings_connection_get_unsaved (self));
break;
@@ -2925,12 +3003,6 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class)
class->supports_secrets = supports_secrets;
- obj_properties[PROP_VISIBLE] =
- g_param_spec_boolean (NM_SETTINGS_CONNECTION_VISIBLE, "", "",
- FALSE,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
-
obj_properties[PROP_UNSAVED] =
g_param_spec_boolean (NM_SETTINGS_CONNECTION_UNSAVED, "", "",
FALSE,
@@ -2997,6 +3069,7 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class)
"GetSecrets", impl_settings_connection_get_secrets,
"ClearSecrets", impl_settings_connection_clear_secrets,
"Save", impl_settings_connection_save,
+ "Update2", impl_settings_connection_update2,
NULL);
}
diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h
index 3672bc08c1..051fcf7ff9 100644
--- a/src/settings/nm-settings-connection.h
+++ b/src/settings/nm-settings-connection.h
@@ -44,8 +44,9 @@
#define NM_SETTINGS_CONNECTION_UPDATED_INTERNAL "updated-internal"
/* Properties */
-#define NM_SETTINGS_CONNECTION_VISIBLE "visible"
#define NM_SETTINGS_CONNECTION_UNSAVED "unsaved"
+
+/* Internal properties */
#define NM_SETTINGS_CONNECTION_READY "ready"
#define NM_SETTINGS_CONNECTION_FLAGS "flags"
#define NM_SETTINGS_CONNECTION_FILENAME "filename"
@@ -61,22 +62,25 @@
* @NM_SETTINGS_CONNECTION_FLAGS_VOLATILE: The connection will be deleted
* when it disconnects. That is for in-memory connections (unsaved), which are
* currently active but cleanup on disconnect.
+ * @NM_SETTINGS_CONNECTION_FLAGS_VISIBLE: The connection is visible
* @NM_SETTINGS_CONNECTION_FLAGS_ALL: special mask, for all known flags
*
* #NMSettingsConnection flags.
**/
-typedef enum
-{
- NM_SETTINGS_CONNECTION_FLAGS_NONE = 0x00,
- NM_SETTINGS_CONNECTION_FLAGS_UNSAVED = 0x01,
- NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED = 0x02,
- NM_SETTINGS_CONNECTION_FLAGS_VOLATILE = 0x04,
+typedef enum {
+ NM_SETTINGS_CONNECTION_FLAGS_NONE = 0,
+
+ NM_SETTINGS_CONNECTION_FLAGS_UNSAVED = (1LL << 0),
+ NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED = (1LL << 1),
+ NM_SETTINGS_CONNECTION_FLAGS_VOLATILE = (1LL << 2),
+
+ NM_SETTINGS_CONNECTION_FLAGS_VISIBLE = (1LL << 3),
__NM_SETTINGS_CONNECTION_FLAGS_LAST,
NM_SETTINGS_CONNECTION_FLAGS_ALL = ((__NM_SETTINGS_CONNECTION_FLAGS_LAST - 1) << 1) - 1,
} NMSettingsConnectionFlags;
-typedef enum { /*< skip >*/
+typedef enum {
NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE = 0,
NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION = (1LL << 0),
NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED = (1LL << 1),
@@ -131,27 +135,22 @@ gboolean nm_settings_connection_has_unmodified_applied_connection (NMSettingsCon
NMConnection *applied_connection,
NMSettingCompareFlags compare_flage);
-gboolean nm_settings_connection_commit_changes (NMSettingsConnection *self,
- NMConnection *new_connection,
- NMSettingsConnectionCommitReason commit_reason,
- GError **error);
-
-gboolean nm_settings_connection_replace_settings_prepare (NMSettingsConnection *self,
- NMConnection *new_connection,
- GError **error);
-
-gboolean nm_settings_connection_replace_settings (NMSettingsConnection *self,
- NMConnection *new_connection,
- gboolean update_unsaved,
- const char *log_diff_name,
- GError **error);
-
-gboolean nm_settings_connection_replace_settings_full (NMSettingsConnection *self,
- NMConnection *new_connection,
- gboolean prepare_new_connection,
- gboolean update_unsaved,
- const char *log_diff_name,
- GError **error);
+typedef enum {
+ NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP,
+ NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK,
+ NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY,
+ NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED,
+ NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY,
+ NM_SETTINGS_CONNECTION_PERSIST_MODE_VOLATILE_DETACHED,
+ NM_SETTINGS_CONNECTION_PERSIST_MODE_VOLATILE_ONLY,
+} NMSettingsConnectionPersistMode;
+
+gboolean nm_settings_connection_update (NMSettingsConnection *self,
+ NMConnection *new_connection,
+ NMSettingsConnectionPersistMode persist_mode,
+ NMSettingsConnectionCommitReason commit_reason,
+ const char *log_diff_name,
+ GError **error);
gboolean nm_settings_connection_delete (NMSettingsConnection *self,
GError **error);
@@ -181,8 +180,6 @@ NMSettingsConnectionCallId *nm_settings_connection_get_secrets (NMSettingsConnec
void nm_settings_connection_cancel_secrets (NMSettingsConnection *self,
NMSettingsConnectionCallId *call_id);
-gboolean nm_settings_connection_is_visible (NMSettingsConnection *self);
-
void nm_settings_connection_recheck_visibility (NMSettingsConnection *self);
gboolean nm_settings_connection_check_permission (NMSettingsConnection *self,
@@ -194,7 +191,7 @@ gboolean nm_settings_connection_get_unsaved (NMSettingsConnection *self);
NMSettingsConnectionFlags nm_settings_connection_get_flags (NMSettingsConnection *self);
NMSettingsConnectionFlags nm_settings_connection_set_flags (NMSettingsConnection *self, NMSettingsConnectionFlags flags, gboolean set);
-NMSettingsConnectionFlags nm_settings_connection_set_flags_all (NMSettingsConnection *self, NMSettingsConnectionFlags flags);
+NMSettingsConnectionFlags nm_settings_connection_set_flags_full (NMSettingsConnection *self, NMSettingsConnectionFlags mask, NMSettingsConnectionFlags value);
int nm_settings_connection_cmp_timestamp (NMSettingsConnection *ac, NMSettingsConnection *ab);
int nm_settings_connection_cmp_timestamp_p_with_data (gconstpointer pa, gconstpointer pb, gpointer user_data);
@@ -243,9 +240,6 @@ nm_settings_connection_autoconnect_blocked_reason_set (NMSettingsConnection *sel
gboolean nm_settings_connection_autoconnect_is_blocked (NMSettingsConnection *self);
-gboolean nm_settings_connection_get_nm_generated (NMSettingsConnection *self);
-gboolean nm_settings_connection_get_volatile (NMSettingsConnection *self);
-
gboolean nm_settings_connection_get_ready (NMSettingsConnection *self);
void nm_settings_connection_set_ready (NMSettingsConnection *self,
gboolean ready);
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c
index 081997058f..21fdf9e067 100644
--- a/src/settings/nm-settings.c
+++ b/src/settings/nm-settings.c
@@ -75,7 +75,6 @@
#include "nm-audit-manager.h"
#include "NetworkManagerUtils.h"
#include "nm-dispatcher.h"
-#include "nm-inotify-helper.h"
#include "nm-hostname-manager.h"
#include "introspection/org.freedesktop.NetworkManager.Settings.h"
@@ -84,13 +83,8 @@
#define EXPORT(sym) void * __export_##sym = &sym;
-EXPORT(nm_inotify_helper_get_type)
-EXPORT(nm_inotify_helper_get)
-EXPORT(nm_inotify_helper_add_watch)
-EXPORT(nm_inotify_helper_remove_watch)
-
EXPORT(nm_settings_connection_get_type)
-EXPORT(nm_settings_connection_replace_settings)
+EXPORT(nm_settings_connection_update)
/*****************************************************************************/
@@ -127,7 +121,7 @@ enum {
CONNECTION_ADDED,
CONNECTION_UPDATED,
CONNECTION_REMOVED,
- CONNECTION_VISIBILITY_CHANGED,
+ CONNECTION_FLAGS_CHANGED,
NEW_CONNECTION, /* exported, not used internally */
LAST_SIGNAL
};
@@ -826,13 +820,12 @@ connection_updated (NMSettingsConnection *connection, gboolean by_user, gpointer
}
static void
-connection_visibility_changed (NMSettingsConnection *connection,
- GParamSpec *pspec,
- gpointer user_data)
+connection_flags_changed (NMSettingsConnection *connection,
+ GParamSpec *pspec,
+ gpointer user_data)
{
- /* Re-emit for listeners like NMPolicy */
g_signal_emit (NM_SETTINGS (user_data),
- signals[CONNECTION_VISIBILITY_CHANGED],
+ signals[CONNECTION_FLAGS_CHANGED],
0,
connection);
}
@@ -855,7 +848,7 @@ connection_removed (NMSettingsConnection *connection, gpointer user_data)
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_removed), self);
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_updated), self);
- g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_visibility_changed), self);
+ g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_flags_changed), self);
if (!priv->startup_complete)
g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_ready_changed), self);
g_object_unref (self);
@@ -979,8 +972,8 @@ claim_connection (NMSettings *self, NMSettingsConnection *connection)
G_CALLBACK (connection_removed), self);
g_signal_connect (connection, NM_SETTINGS_CONNECTION_UPDATED_INTERNAL,
G_CALLBACK (connection_updated), self);
- g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_VISIBLE,
- G_CALLBACK (connection_visibility_changed),
+ g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_FLAGS,
+ G_CALLBACK (connection_flags_changed),
self);
if (!priv->startup_complete) {
g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_READY,
@@ -1993,8 +1986,8 @@ nm_settings_class_init (NMSettingsClass *class)
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION);
- signals[CONNECTION_VISIBILITY_CHANGED] =
- g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED,
+ signals[CONNECTION_FLAGS_CHANGED] =
+ g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_FLAGS_CHANGED,
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
0, NULL, NULL,
diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h
index cbd8afa9c3..0ecffb708a 100644
--- a/src/settings/nm-settings.h
+++ b/src/settings/nm-settings.h
@@ -46,7 +46,7 @@
#define NM_SETTINGS_SIGNAL_CONNECTION_ADDED "connection-added"
#define NM_SETTINGS_SIGNAL_CONNECTION_UPDATED "connection-updated"
#define NM_SETTINGS_SIGNAL_CONNECTION_REMOVED "connection-removed"
-#define NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED "connection-visibility-changed"
+#define NM_SETTINGS_SIGNAL_CONNECTION_FLAGS_CHANGED "connection-flags-changed"
/**
* NMConnectionFilterFunc:
diff --git a/src/settings/plugins/ibft/nms-ibft-connection.c b/src/settings/plugins/ibft/nms-ibft-connection.c
index 834ba83408..2a7c5f4a02 100644
--- a/src/settings/plugins/ibft/nms-ibft-connection.c
+++ b/src/settings/plugins/ibft/nms-ibft-connection.c
@@ -60,11 +60,12 @@ nms_ibft_connection_new (const GPtrArray *block, GError **error)
object = g_object_new (NMS_TYPE_IBFT_CONNECTION, NULL);
/* Update settings with what was read from iscsiadm */
- if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object),
- source,
- FALSE,
- NULL,
- error))
+ if (!nm_settings_connection_update (NM_SETTINGS_CONNECTION (object),
+ source,
+ NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP,
+ NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
+ NULL,
+ error))
g_clear_object (&object);
return (NMSIbftConnection *) object;
diff --git a/src/settings/nm-inotify-helper.c b/src/settings/plugins/ifcfg-rh/nm-inotify-helper.c
index 51b180b233..51b180b233 100644
--- a/src/settings/nm-inotify-helper.c
+++ b/src/settings/plugins/ifcfg-rh/nm-inotify-helper.c
diff --git a/src/settings/nm-inotify-helper.h b/src/settings/plugins/ifcfg-rh/nm-inotify-helper.h
index 2715f3eec5..b887ae378a 100644
--- a/src/settings/nm-inotify-helper.h
+++ b/src/settings/plugins/ifcfg-rh/nm-inotify-helper.h
@@ -43,4 +43,17 @@ int nm_inotify_helper_add_watch (NMInotifyHelper *helper, const char *path);
void nm_inotify_helper_remove_watch (NMInotifyHelper *helper, int wd);
+static inline gboolean
+nm_inotify_helper_clear_watch (NMInotifyHelper *helper, int *wd)
+{
+ int x;
+
+ if (wd && ((x = *wd) >= 0)) {
+ *wd = -1;
+ nm_inotify_helper_remove_watch (helper, x);
+ return TRUE;
+ }
+ return FALSE;
+}
+
#endif /* __NM_INOTIFY_HELPER_H__ */
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c
index 4c1d02ae08..5d3428d6bf 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c
@@ -36,13 +36,13 @@
#include "nm-setting-wireless-security.h"
#include "nm-setting-8021x.h"
#include "platform/nm-platform.h"
-#include "settings/nm-inotify-helper.h"
#include "nm-config.h"
#include "nms-ifcfg-rh-common.h"
#include "nms-ifcfg-rh-reader.h"
#include "nms-ifcfg-rh-writer.h"
#include "nms-ifcfg-rh-utils.h"
+#include "nm-inotify-helper.h"
/*****************************************************************************/
@@ -96,14 +96,6 @@ G_DEFINE_TYPE (NMIfcfgConnection, nm_ifcfg_connection, NM_TYPE_SETTINGS_CONNECTI
/*****************************************************************************/
-static NMInotifyHelper *
-_get_inotify_helper (NMIfcfgConnectionPrivate *priv)
-{
- if (!priv->inotify_helper)
- priv->inotify_helper = g_object_ref (nm_inotify_helper_get ());
- return priv->inotify_helper;
-}
-
static gboolean
devtimeout_ready (gpointer user_data)
{
@@ -225,37 +217,17 @@ static void
path_watch_stop (NMIfcfgConnection *self)
{
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (self);
- NMInotifyHelper *ih;
-
- ih = _get_inotify_helper (priv);
-
- nm_clear_g_signal_handler (ih, &priv->ih_event_id);
-
- if (priv->file_wd >= 0) {
- nm_inotify_helper_remove_watch (ih, priv->file_wd);
- priv->file_wd = -1;
- }
- g_free (priv->keyfile);
- priv->keyfile = NULL;
- if (priv->keyfile_wd >= 0) {
- nm_inotify_helper_remove_watch (ih, priv->keyfile_wd);
- priv->keyfile_wd = -1;
- }
+ nm_clear_g_signal_handler (priv->inotify_helper, &priv->ih_event_id);
- g_free (priv->routefile);
- priv->routefile = NULL;
- if (priv->routefile_wd >= 0) {
- nm_inotify_helper_remove_watch (ih, priv->routefile_wd);
- priv->routefile_wd = -1;
- }
+ nm_inotify_helper_clear_watch (priv->inotify_helper, &priv->file_wd);
+ nm_inotify_helper_clear_watch (priv->inotify_helper, &priv->keyfile_wd);
+ nm_inotify_helper_clear_watch (priv->inotify_helper, &priv->routefile_wd);
+ nm_inotify_helper_clear_watch (priv->inotify_helper, &priv->route6file_wd);
- g_free (priv->route6file);
- priv->route6file = NULL;
- if (priv->route6file_wd >= 0) {
- nm_inotify_helper_remove_watch (ih, priv->route6file_wd);
- priv->route6file_wd = -1;
- }
+ nm_clear_g_free (&priv->keyfile);
+ nm_clear_g_free (&priv->routefile);
+ nm_clear_g_free (&priv->route6file);
}
static void
@@ -280,7 +252,9 @@ filename_changed (GObject *object,
if (nm_config_get_monitor_connection_files (nm_config_get ())) {
NMInotifyHelper *ih;
- ih = _get_inotify_helper (priv);
+ if (!priv->inotify_helper)
+ priv->inotify_helper = g_object_ref (nm_inotify_helper_get ());
+ ih = priv->inotify_helper;
priv->ih_event_id = g_signal_connect (ih, "event", G_CALLBACK (files_changed_cb), self);
priv->file_wd = nm_inotify_helper_add_watch (ih, ifcfg_path);
@@ -324,7 +298,7 @@ commit_changes (NMSettingsConnection *connection,
nm_assert (!out_logmsg_change || !*out_logmsg_change);
filename = nm_settings_connection_get_filename (connection);
- if (!nms_ifcfg_rh_writer_write_connection (new_connection ?: NM_CONNECTION (connection),
+ if (!nms_ifcfg_rh_writer_write_connection (new_connection,
IFCFG_DIR,
filename,
&ifcfg_path,
@@ -429,18 +403,12 @@ nm_ifcfg_connection_new (NMConnection *source,
NMConnection *tmp;
char *unhandled_spec = NULL;
const char *unmanaged_spec = NULL, *unrecognized_spec = NULL;
- gboolean update_unsaved = TRUE;
g_assert (source || full_path);
if (out_ignore_error)
*out_ignore_error = FALSE;
- if (full_path) {
- /* The connection already is on the disk */
- update_unsaved = FALSE;
- }
-
/* If we're given a connection already, prefer that instead of re-reading */
if (source)
tmp = g_object_ref (source);
@@ -464,11 +432,14 @@ nm_ifcfg_connection_new (NMConnection *source,
NM_IFCFG_CONNECTION_UNRECOGNIZED_SPEC, unrecognized_spec,
NULL);
/* Update our settings with what was read from the file */
- if (nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object),
- tmp,
- update_unsaved,
- NULL,
- error))
+ if (nm_settings_connection_update (NM_SETTINGS_CONNECTION (object),
+ tmp,
+ full_path
+ ? NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP /* connection is already on disk */
+ : NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY,
+ NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
+ NULL,
+ error))
nm_ifcfg_connection_check_devtimeout (NM_IFCFG_CONNECTION (object));
else
g_clear_object (&object);
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c
index 1ebdeafa7f..8ad3a53f3d 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c
@@ -313,11 +313,12 @@ update_connection (SettingsPluginIfcfg *self,
NM_IFCFG_CONNECTION_UNRECOGNIZED_SPEC, new_unrecognized,
NULL);
- if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (connection_by_uuid),
- NM_CONNECTION (connection_new),
- FALSE, /* don't set Unsaved */
- "ifcfg-update",
- &local)) {
+ if (!nm_settings_connection_update (NM_SETTINGS_CONNECTION (connection_by_uuid),
+ NM_CONNECTION (connection_new),
+ NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP,
+ NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
+ "ifcfg-update",
+ &local)) {
/* Shouldn't ever get here as 'connection_new' was verified by the reader already
* and the UUID did not change. */
g_assert_not_reached ();
diff --git a/src/settings/plugins/ifnet/nms-ifnet-connection.c b/src/settings/plugins/ifnet/nms-ifnet-connection.c
index 5dbb124c30..aeb4467472 100644
--- a/src/settings/plugins/ifnet/nms-ifnet-connection.c
+++ b/src/settings/plugins/ifnet/nms-ifnet-connection.c
@@ -93,7 +93,7 @@ commit_changes (NMSettingsConnection *connection,
g_signal_emit (connection, signals[IFNET_CANCEL_MONITORS], 0);
if (priv->conn_name) {
- success = ifnet_update_parsers_by_connection (NM_CONNECTION (connection),
+ success = ifnet_update_parsers_by_connection (new_connection,
priv->conn_name,
CONF_NET_FILE,
WPA_SUPPLICANT_CONF,
@@ -102,7 +102,7 @@ commit_changes (NMSettingsConnection *connection,
error);
} else {
added = TRUE;
- success = ifnet_add_new_connection (NM_CONNECTION (connection),
+ success = ifnet_add_new_connection (new_connection,
CONF_NET_FILE,
WPA_SUPPLICANT_CONF,
&new_name,
@@ -186,11 +186,14 @@ nm_ifnet_connection_new (NMConnection *source, const char *conn_name)
object = (GObject *) g_object_new (NM_TYPE_IFNET_CONNECTION, NULL);
NM_IFNET_CONNECTION_GET_PRIVATE ((NMIfnetConnection *) object)->conn_name = g_strdup (conn_name);
- if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object),
- tmp,
- update_unsaved,
- NULL,
- NULL)) {
+ if (!nm_settings_connection_update (NM_SETTINGS_CONNECTION (object),
+ tmp,
+ update_unsaved
+ ? NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY
+ : NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP,
+ NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
+ NULL,
+ NULL)) {
g_object_unref (object);
return NULL;
}
diff --git a/src/settings/plugins/ifnet/nms-ifnet-plugin.c b/src/settings/plugins/ifnet/nms-ifnet-plugin.c
index 998b04b47a..98e56e449a 100644
--- a/src/settings/plugins/ifnet/nms-ifnet-plugin.c
+++ b/src/settings/plugins/ifnet/nms-ifnet-plugin.c
@@ -269,11 +269,12 @@ reload_connections (NMSettingsPlugin *config)
}
} else {
/* Update existing connection with new settings */
- if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (old),
- NM_CONNECTION (new),
- FALSE, /* don't set Unsaved */
- "ifnet-update",
- &error)) {
+ if (!nm_settings_connection_update (NM_SETTINGS_CONNECTION (old),
+ NM_CONNECTION (new),
+ NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP,
+ NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
+ "ifnet-update",
+ &error)) {
/* Shouldn't ever get here as 'new' was verified by the reader already
* and the UUID did not change. */
g_assert_not_reached ();
diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c b/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c
index 0928772afa..87afb6c8e9 100644
--- a/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c
+++ b/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c
@@ -139,10 +139,12 @@ bind_device_to_connection (SettingsPluginIfupdown *self,
g_object_set (s_wifi, NM_SETTING_WIRELESS_MAC_ADDRESS, address, NULL);
}
- nm_settings_connection_commit_changes (NM_SETTINGS_CONNECTION (exported),
- NULL,
- NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
- NULL);
+ nm_settings_connection_update (NM_SETTINGS_CONNECTION (exported),
+ NULL,
+ NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK,
+ NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
+ "ifupdown-new",
+ NULL);
}
static void
diff --git a/src/settings/plugins/keyfile/nms-keyfile-connection.c b/src/settings/plugins/keyfile/nms-keyfile-connection.c
index 300aa9f7b3..9e9ab9621b 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-connection.c
+++ b/src/settings/plugins/keyfile/nms-keyfile-connection.c
@@ -65,7 +65,7 @@ commit_changes (NMSettingsConnection *connection,
nm_assert (out_reread_connection && !*out_reread_connection);
nm_assert (!out_logmsg_change || !*out_logmsg_change);
- if (!nms_keyfile_writer_connection (new_connection ?: NM_CONNECTION (connection),
+ if (!nms_keyfile_writer_connection (new_connection,
nm_settings_connection_get_filename (connection),
NM_FLAGS_ALL (commit_reason, NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION
| NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED),
@@ -159,11 +159,14 @@ nms_keyfile_connection_new (NMConnection *source,
NULL);
/* Update our settings with what was read from the file */
- if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object),
- tmp,
- update_unsaved,
- NULL,
- error)) {
+ if (!nm_settings_connection_update (NM_SETTINGS_CONNECTION (object),
+ tmp,
+ update_unsaved
+ ? NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY
+ : NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP,
+ NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
+ NULL,
+ error)) {
g_object_unref (object);
object = NULL;
}
diff --git a/src/settings/plugins/keyfile/nms-keyfile-plugin.c b/src/settings/plugins/keyfile/nms-keyfile-plugin.c
index dfc311af33..dd179565a2 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-plugin.c
+++ b/src/settings/plugins/keyfile/nms-keyfile-plugin.c
@@ -258,11 +258,12 @@ update_connection (NMSKeyfilePlugin *self,
else
_LOGI ("update and persist "NMS_KEYFILE_CONNECTION_LOG_FMT, NMS_KEYFILE_CONNECTION_LOG_ARG (connection_new));
- if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (connection_by_uuid),
- NM_CONNECTION (connection_new),
- FALSE, /* don't set Unsaved */
- "keyfile-update",
- &local)) {
+ if (!nm_settings_connection_update (NM_SETTINGS_CONNECTION (connection_by_uuid),
+ NM_CONNECTION (connection_new),
+ NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP,
+ NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
+ "keyfile-update",
+ &local)) {
/* Shouldn't ever get here as 'connection_new' was verified by the reader already
* and the UUID did not change. */
g_assert_not_reached ();