diff options
-rw-r--r-- | introspection/org.freedesktop.NetworkManager.Settings.Connection.xml | 3 | ||||
-rw-r--r-- | libnm-core/nm-dbus-interface.h | 25 | ||||
-rw-r--r-- | src/settings/nm-settings-connection.c | 121 | ||||
-rw-r--r-- | src/settings/nm-settings-connection.h | 4 |
4 files changed, 110 insertions, 43 deletions
diff --git a/introspection/org.freedesktop.NetworkManager.Settings.Connection.xml b/introspection/org.freedesktop.NetworkManager.Settings.Connection.xml index 9064ecaf39..ec596fd1e9 100644 --- a/introspection/org.freedesktop.NetworkManager.Settings.Connection.xml +++ b/introspection/org.freedesktop.NetworkManager.Settings.Connection.xml @@ -108,6 +108,9 @@ @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 diff --git a/libnm-core/nm-dbus-interface.h b/libnm-core/nm-dbus-interface.h index 6012e989bb..34d2e95ad8 100644 --- a/libnm-core/nm-dbus-interface.h +++ b/libnm-core/nm-dbus-interface.h @@ -898,6 +898,28 @@ typedef enum { /*< flags >*/ * @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 @@ -909,6 +931,9 @@ 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; diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index cef26d6cb8..3afe7de820 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -488,26 +488,41 @@ secrets_cleared_cb (NMSettingsConnection *self) } static void -set_unsaved (NMSettingsConnection *self, gboolean now_unsaved) +set_persist_mode (NMSettingsConnection *self, NMSettingsConnectionPersistMode persist_mode) { - NMSettingsConnectionFlags flags; + 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 (nm_settings_connection_get_flags (self), NM_SETTINGS_CONNECTION_FLAGS_UNSAVED) != !!now_unsaved) { - if (now_unsaved) - flags = NM_SETTINGS_CONNECTION_FLAGS_UNSAVED; - else - flags = NM_SETTINGS_CONNECTION_FLAGS_NONE; - nm_settings_connection_set_flags_full (self, ALL, 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); } @@ -515,23 +530,34 @@ 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 (error, + g_set_error (&local, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "delete not supported"); - return FALSE; + goto fail; } if (!klass->delete (self, - error)) - return FALSE; + &local)) + goto fail; - nm_settings_connection_set_filename (self, NULL); + 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 @@ -576,18 +602,17 @@ nm_settings_connection_update (NMSettingsConnection *self, 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); priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - if (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP) { - persist_mode = nm_settings_connection_get_unsaved (self) - ? NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY - : NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK; - } + 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 (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK) { + if (save_to_disk) { klass = NM_SETTINGS_CONNECTION_GET_CLASS (self); if (!klass->commit_changes) { g_set_error (&local, @@ -604,7 +629,7 @@ nm_settings_connection_update (NMSettingsConnection *self, &local)) goto out; - if (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK) { + if (save_to_disk) { if (!klass->commit_changes (self, new_connection ?: NM_CONNECTION (self), commit_reason, @@ -666,19 +691,14 @@ nm_settings_connection_update (NMSettingsConnection *self, 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. - */ - switch (persist_mode) { - case NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY: - set_unsaved (self, TRUE); - break; - case NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK: - set_unsaved (self, FALSE); - break; - case NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP: - break; - } + 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); @@ -1700,15 +1720,23 @@ update_auth_cb (NMSettingsConnection *self, 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 + 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_IN_MEMORY + 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-unsaved" : "make-unsaved"; - else + && !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, @@ -1887,9 +1915,13 @@ impl_settings_connection_update2 (NMSettingsConnection *self, 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) (NM_SETTINGS_UPDATE2_FLAG_TO_DISK | - NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY | + 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, @@ -1898,8 +1930,11 @@ impl_settings_connection_update2 (NMSettingsConnection *self, return; } - if (NM_FLAGS_ALL (flags, NM_SETTINGS_UPDATE2_FLAG_TO_DISK | - NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY)) { + 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"); diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h index 7615fb4655..051fcf7ff9 100644 --- a/src/settings/nm-settings-connection.h +++ b/src/settings/nm-settings-connection.h @@ -139,6 +139,10 @@ 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, |