diff options
Diffstat (limited to 'src/core/settings/nm-settings.c')
| -rw-r--r-- | src/core/settings/nm-settings.c | 88 |
1 files changed, 79 insertions, 9 deletions
diff --git a/src/core/settings/nm-settings.c b/src/core/settings/nm-settings.c index 6619d3e0..1ff66e25 100644 --- a/src/core/settings/nm-settings.c +++ b/src/core/settings/nm-settings.c @@ -236,12 +236,16 @@ _sett_conn_entry_get_conn(SettConnEntry *sett_conn_entry) * update-connection. If this parameter is omitted, then it's about what happens * when adding a new profile (add-connection). * + * @storage_check_ignore is optional, and if given then it skips this particular + * storage. + * * Returns: the conflicting storage or %NULL if there is none. */ static NMSettingsStorage * _sett_conn_entry_storage_find_conflicting_storage(SettConnEntry *sett_conn_entry, NMSettingsPlugin *target_plugin, NMSettingsStorage *storage_check_including, + NMSettingsStorage *storage_check_ignore, const GSList *plugins) { StorageData *sd; @@ -269,6 +273,12 @@ _sett_conn_entry_storage_find_conflicting_storage(SettConnEntry *sett_conn_e continue; } + if (sd->storage == storage_check_ignore) { + /* We ignore this one, because we're in the process of + * replacing it. */ + continue; + } + if (sd->storage == storage_check_including) { /* ok, the storage is the one we are about to check. All other * storages are lower priority, so there is no storage that hides @@ -557,6 +567,8 @@ _startup_complete_check(NMSettings *self, gint64 now_msec) return; } + nm_clear_g_source(&priv->startup_complete_timeout_id); + if (c_list_is_empty(&priv->startup_complete_scd_lst_head)) goto ready; @@ -592,8 +604,6 @@ next_with_ready: } c_list_splice(&priv->startup_complete_scd_lst_head, &ready_lst); - nm_clear_g_source(&priv->startup_complete_timeout_id); - if (scd_not_ready) { gint64 timeout_msec; @@ -1463,6 +1473,7 @@ _plugin_connections_reload(NMSettings *self) static gboolean _add_connection_to_first_plugin(NMSettings *self, + const char *plugin_name, SettConnEntry *sett_conn_entry, NMConnection *new_connection, gboolean in_memory, @@ -1471,12 +1482,14 @@ _add_connection_to_first_plugin(NMSettings *self, gboolean shadowed_owned, NMSettingsStorage **out_new_storage, NMConnection **out_new_connection, + NMSettingsStorage *drop_storage, GError **error) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self); gs_free_error GError *first_error = NULL; GSList *iter; const char *uuid; + gboolean no_plugin = TRUE; uuid = nm_connection_get_uuid(new_connection); @@ -1493,12 +1506,18 @@ _add_connection_to_first_plugin(NMSettings *self, gboolean success; const char *filename; + if (plugin_name && strcmp(plugin_name, nm_settings_plugin_get_plugin_name(plugin))) { + /* Not the plugin we're confined to. Ignore. */ + continue; + } + if (!in_memory) { NMSettingsStorage *conflicting_storage; conflicting_storage = _sett_conn_entry_storage_find_conflicting_storage(sett_conn_entry, plugin, NULL, + drop_storage, priv->plugins); if (conflicting_storage) { /* we have a connection provided by a plugin with higher priority than the one @@ -1545,6 +1564,8 @@ _add_connection_to_first_plugin(NMSettings *self, &add_error); } + no_plugin = FALSE; + if (!success) { _LOGT("add-connection: failed to add %s/'%s': %s", nm_connection_get_uuid(new_connection), @@ -1588,8 +1609,18 @@ _add_connection_to_first_plugin(NMSettings *self, return TRUE; } - nm_assert(first_error); - g_propagate_error(error, g_steal_pointer(&first_error)); + if (no_plugin) { + nm_assert(plugin_name); + nm_assert(!first_error); + g_set_error(error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_ARGUMENTS, + "a plugin by the name of '%s' is not available", + plugin_name); + } else { + nm_assert(first_error); + g_propagate_error(error, g_steal_pointer(&first_error)); + } return FALSE; } @@ -1704,6 +1735,7 @@ _set_nmmeta_tombstone(NMSettings *self, */ gboolean nm_settings_add_connection(NMSettings *self, + const char *plugin, NMConnection *connection, NMSettingsConnectionPersistMode persist_mode, NMSettingsConnectionAddReason add_reason, @@ -1800,6 +1832,7 @@ nm_settings_add_connection(NMSettings *self, sett_conn_entry, nm_settings_storage_get_plugin(shadowed_storage), shadowed_storage, + NULL, priv->plugins); if (conflicting_storage) { /* We cannot add the profile as @shadowed_storage, because there is another, existing storage @@ -1824,6 +1857,7 @@ again_add_connection: if (!update_storage) { success = _add_connection_to_first_plugin(self, + plugin, sett_conn_entry, connection, new_in_memory, @@ -1832,6 +1866,7 @@ again_add_connection: FALSE, &new_storage, &new_connection, + NULL, &local); } else { success = _update_connection_to_plugin(self, @@ -1948,6 +1983,7 @@ again_delete_tombstone: gboolean nm_settings_update_connection(NMSettings *self, NMSettingsConnection *sett_conn, + const char *plugin_name, NMConnection *connection, NMSettingsConnectionPersistMode persist_mode, NMSettingsConnectionIntFlags sett_flags, @@ -2154,8 +2190,9 @@ nm_settings_update_connection(NMSettings *self, } else if (nm_settings_storage_is_keyfile_lib(cur_storage)) { /* the profile is a keyfile in /usr/lib. It cannot be overwritten, we must migrate it * from /usr/lib to /etc. */ - } else + } else { update_storage = cur_storage; + } if (new_in_memory) { if (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY) { @@ -2174,8 +2211,22 @@ nm_settings_update_connection(NMSettings *self, } } + if (update_storage && plugin_name) { + NMSettingsPlugin *plugin = nm_settings_storage_get_plugin(update_storage); + + if (strcmp(plugin_name, nm_settings_plugin_get_plugin_name(plugin))) { + /* We're updating a connection, we're confined to a particular + * plugin, but the connection is currently using a different one. + * We need to migrate. Drop the existing storage and look out for + * a new one. */ + drop_storage = update_storage; + update_storage = NULL; + } + } + if (!update_storage) { success = _add_connection_to_first_plugin(self, + plugin_name, sett_conn_entry, connection, new_in_memory, @@ -2184,6 +2235,7 @@ nm_settings_update_connection(NMSettings *self, new_shadowed_owned, &new_storage, &new_connection, + drop_storage, &local); } else { success = _update_connection_to_plugin(self, @@ -2462,6 +2514,7 @@ pk_add_cb(NMAuthChain *chain, GDBusMethodInvocation *context, gpointer user_data nm_assert(NM_IS_CONNECTION(connection)); nm_settings_add_connection(self, + nm_auth_chain_get_data(chain, "plugin"), connection, GPOINTER_TO_UINT(nm_auth_chain_get_data(chain, "persist-mode")), GPOINTER_TO_UINT(nm_auth_chain_get_data(chain, "add-reason")), @@ -2489,6 +2542,7 @@ pk_add_cb(NMAuthChain *chain, GDBusMethodInvocation *context, gpointer user_data void nm_settings_add_connection_dbus(NMSettings *self, + const char *plugin, NMConnection *connection, NMSettingsConnectionPersistMode persist_mode, NMSettingsConnectionAddReason add_reason, @@ -2549,6 +2603,7 @@ nm_settings_add_connection_dbus(NMSettings *self, nm_auth_chain_set_data(chain, "persist-mode", GUINT_TO_POINTER(persist_mode), NULL); nm_auth_chain_set_data(chain, "add-reason", GUINT_TO_POINTER(add_reason), NULL); nm_auth_chain_set_data(chain, "sett-flags", GUINT_TO_POINTER(sett_flags), NULL); + nm_auth_chain_set_data(chain, "plugin", g_strdup(plugin), g_free); nm_auth_chain_add_call_unsafe(chain, perm, TRUE); return; @@ -2601,6 +2656,7 @@ settings_add_connection_helper(NMSettings *self, GDBusMethodInvocation *context, gboolean is_add_connection_2, GVariant *settings, + const char *plugin, NMSettingsAddConnection2Flags flags) { gs_unref_object NMConnection *connection = NULL; @@ -2636,6 +2692,7 @@ settings_add_connection_helper(NMSettings *self, nm_settings_add_connection_dbus( self, + plugin, connection, persist_mode, NM_FLAGS_HAS(flags, NM_SETTINGS_ADD_CONNECTION2_FLAG_BLOCK_AUTOCONNECT) @@ -2665,6 +2722,7 @@ impl_settings_add_connection(NMDBusObject *obj, invocation, FALSE, settings, + NULL, NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK); } @@ -2685,6 +2743,7 @@ impl_settings_add_connection_unsaved(NMDBusObject *obj, invocation, FALSE, settings, + NULL, NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY); } @@ -2700,8 +2759,10 @@ impl_settings_add_connection2(NMDBusObject *obj, NMSettings *self = NM_SETTINGS(obj); gs_unref_variant GVariant *settings = NULL; gs_unref_variant GVariant *args = NULL; + gs_free char *plugin = NULL; NMSettingsAddConnection2Flags flags; const char *args_name; + GVariant *args_value; GVariantIter iter; guint32 flags_u; @@ -2745,7 +2806,13 @@ impl_settings_add_connection2(NMDBusObject *obj, nm_assert(g_variant_is_of_type(args, G_VARIANT_TYPE("a{sv}"))); g_variant_iter_init(&iter, args); - while (g_variant_iter_next(&iter, "{&sv}", &args_name, NULL)) { + while (g_variant_iter_next(&iter, "{&sv}", &args_name, &args_value)) { + if (plugin == NULL && nm_streq(args_name, "plugin") + && g_variant_is_of_type(args_value, G_VARIANT_TYPE_STRING)) { + plugin = g_variant_dup_string(args_value, NULL); + continue; + } + g_dbus_method_invocation_take_error(invocation, g_error_new(NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_ARGUMENTS, @@ -2754,7 +2821,7 @@ impl_settings_add_connection2(NMDBusObject *obj, return; } - settings_add_connection_helper(self, invocation, TRUE, settings, flags); + settings_add_connection_helper(self, invocation, TRUE, settings, plugin, flags); } /*****************************************************************************/ @@ -3201,8 +3268,10 @@ nm_settings_get_connection_by_path(NMSettings *self, const char *path) priv = NM_SETTINGS_GET_PRIVATE(self); connection = - nm_dbus_manager_lookup_object(nm_dbus_object_get_manager(NM_DBUS_OBJECT(self)), path); - if (!connection || !NM_IS_SETTINGS_CONNECTION(connection)) + nm_dbus_manager_lookup_object_with_type(nm_dbus_object_get_manager(NM_DBUS_OBJECT(self)), + NM_TYPE_SETTINGS_CONNECTION, + path); + if (!connection) return NULL; nm_assert(c_list_contains(&priv->connections_lst_head, &connection->_connections_lst)); @@ -3604,6 +3673,7 @@ device_realized(NMDevice *device, GParamSpec *pspec, NMSettings *self) nm_device_get_iface(device)); nm_settings_add_connection(self, + NULL, connection, NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY, NM_SETTINGS_CONNECTION_ADD_REASON_NONE, |