core: merge branch 'th/user-block-autoconnect-rh1401515'

https://bugzilla.redhat.com/show_bug.cgi?id=1401515
This commit is contained in:
Thomas Haller 2017-12-05 21:07:31 +01:00
commit 632e693251
30 changed files with 1082 additions and 586 deletions

View file

@ -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 \

View file

@ -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 \

View file

@ -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())

View file

@ -101,6 +101,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:

View file

@ -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__ */

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -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,

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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 */

View file

@ -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);
}

View file

@ -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);

View file

@ -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));
/* 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 (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;
}
}
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");
out:
if (local) {
_LOGI ("write: failure to update connection: %s", local->message);
g_propagate_error (error, local);
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));
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 (!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 (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);
if (priv->autoconnect_blocked_reason != NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE)
return TRUE;
if (priv->autoconnect_retries == 0)
return TRUE;
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;
}
/*****************************************************************************/
/**
* 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);
}
/**
* 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);
}
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);
}

View file

@ -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);
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_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);
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);

View file

@ -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,

View file

@ -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:

View file

@ -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;

View file

@ -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__ */

View file

@ -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 (priv->inotify_helper, &priv->ih_event_id);
nm_clear_g_signal_handler (ih, &priv->ih_event_id);
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);
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;
}
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;
}
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);

View file

@ -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 ();

View file

@ -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;
}

View file

@ -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 ();

View file

@ -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

View file

@ -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;
}

View file

@ -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 ();