diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index ac408d3d9f..22d2bfa923 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -1463,7 +1463,7 @@ new_default_connection (NMDevice *self) const char *hw_address; char *defname, *uuid; - if (!nm_config_get_ethernet_can_auto_default (nm_config_get (), self)) + if (nm_config_get_no_auto_default_for_device (nm_config_get (), self)) return NULL; hw_address = nm_device_get_hw_address (self); diff --git a/src/nm-config-data.c b/src/nm-config-data.c index 93a56df1e3..cf140739fc 100644 --- a/src/nm-config-data.c +++ b/src/nm-config-data.c @@ -37,6 +37,11 @@ typedef struct { char *response; guint interval; } connectivity; + + struct { + char **arr; + GSList *specs; + } no_auto_default; } NMConfigDataPrivate; @@ -48,6 +53,7 @@ enum { PROP_CONNECTIVITY_URI, PROP_CONNECTIVITY_INTERVAL, PROP_CONNECTIVITY_RESPONSE, + PROP_NO_AUTO_DEFAULT, LAST_PROP }; @@ -106,6 +112,21 @@ nm_config_data_get_connectivity_response (const NMConfigData *self) return NM_CONFIG_DATA_GET_PRIVATE (self)->connectivity.response; } +const char *const* +nm_config_data_get_no_auto_default (const NMConfigData *self) +{ + g_return_val_if_fail (self, FALSE); + + return (const char *const*) NM_CONFIG_DATA_GET_PRIVATE (self)->no_auto_default.arr; +} + +const GSList * +nm_config_data_get_no_auto_default_list (const NMConfigData *self) +{ + g_return_val_if_fail (self, NULL); + + return NM_CONFIG_DATA_GET_PRIVATE (self)->no_auto_default.specs; +} /************************************************************************/ @@ -141,6 +162,7 @@ nm_config_data_diff (NMConfigData *old_data, NMConfigData *new_data) { GHashTable *changes; NMConfigDataPrivate *priv_old, *priv_new; + GSList *spec_old, *spec_new; g_return_val_if_fail (NM_IS_CONFIG_DATA (old_data), NULL); g_return_val_if_fail (NM_IS_CONFIG_DATA (new_data), NULL); @@ -163,6 +185,15 @@ nm_config_data_diff (NMConfigData *old_data, NMConfigData *new_data) || g_strcmp0 (nm_config_data_get_connectivity_response (old_data), nm_config_data_get_connectivity_response (new_data))) g_hash_table_insert (changes, NM_CONFIG_CHANGES_CONNECTIVITY, NULL); + spec_old = priv_old->no_auto_default.specs; + spec_new = priv_new->no_auto_default.specs; + while (spec_old && spec_new && strcmp (spec_old->data, spec_new->data) == 0) { + spec_old = spec_old->next; + spec_new = spec_new->next; + } + if (spec_old || spec_new) + g_hash_table_insert (changes, NM_CONFIG_CHANGES_NO_AUTO_DEFAULT, NULL); + if (!g_hash_table_size (changes)) { g_hash_table_destroy (changes); return NULL; @@ -187,6 +218,9 @@ get_property (GObject *object, case PROP_CONFIG_DESCRIPTION: g_value_set_string (value, nm_config_data_get_config_description (self)); break; + case PROP_NO_AUTO_DEFAULT: + g_value_take_boxed (value, g_strdupv ((char **) nm_config_data_get_no_auto_default (self))); + break; case PROP_CONNECTIVITY_URI: g_value_set_string (value, nm_config_data_get_connectivity_uri (self)); break; @@ -210,6 +244,7 @@ set_property (GObject *object, { NMConfigData *self = NM_CONFIG_DATA (object); NMConfigDataPrivate *priv = NM_CONFIG_DATA_GET_PRIVATE (self); + guint i; /* This type is immutable. All properties are construct only. */ switch (prop_id) { @@ -224,6 +259,14 @@ set_property (GObject *object, if (!priv->keyfile) priv->keyfile = nm_config_create_keyfile (); break; + case PROP_NO_AUTO_DEFAULT: + priv->no_auto_default.arr = g_strdupv (g_value_get_boxed (value)); + if (!priv->no_auto_default.arr) + priv->no_auto_default.arr = g_new0 (char *, 1); + for (i = 0; priv->no_auto_default.arr[i]; i++) + priv->no_auto_default.specs = g_slist_prepend (priv->no_auto_default.specs, priv->no_auto_default.arr[i]); + priv->no_auto_default.specs = g_slist_reverse (priv->no_auto_default.specs); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -246,6 +289,9 @@ finalize (GObject *gobject) g_free (priv->connectivity.uri); g_free (priv->connectivity.response); + g_slist_free (priv->no_auto_default.specs); + g_strfreev (priv->no_auto_default.arr); + G_OBJECT_CLASS (nm_config_data_parent_class)->finalize (gobject); } @@ -273,12 +319,28 @@ constructed (GObject *object) NMConfigData * nm_config_data_new (const char *config_main_file, const char *config_description, + const char *const*no_auto_default, GKeyFile *keyfile) { return g_object_new (NM_TYPE_CONFIG_DATA, NM_CONFIG_DATA_CONFIG_MAIN_FILE, config_main_file, NM_CONFIG_DATA_CONFIG_DESCRIPTION, config_description, NM_CONFIG_DATA_KEYFILE, keyfile, + NM_CONFIG_DATA_NO_AUTO_DEFAULT, no_auto_default, + NULL); +} + +NMConfigData * +nm_config_data_new_update_no_auto_default (const NMConfigData *base, + const char *const*no_auto_default) +{ + NMConfigDataPrivate *priv = NM_CONFIG_DATA_GET_PRIVATE (base); + + return g_object_new (NM_TYPE_CONFIG_DATA, + NM_CONFIG_DATA_CONFIG_MAIN_FILE, priv->config_main_file, + NM_CONFIG_DATA_CONFIG_DESCRIPTION, priv->config_description, + NM_CONFIG_DATA_KEYFILE, priv->keyfile, /* the keyfile is unchanged. It's safe to share it. */ + NM_CONFIG_DATA_NO_AUTO_DEFAULT, no_auto_default, NULL); } @@ -340,5 +402,13 @@ nm_config_data_class_init (NMConfigDataClass *config_class) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, PROP_NO_AUTO_DEFAULT, + g_param_spec_boxed (NM_CONFIG_DATA_NO_AUTO_DEFAULT, "", "", + G_TYPE_STRV, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + } diff --git a/src/nm-config-data.h b/src/nm-config-data.h index d3425632b0..59b2806ccd 100644 --- a/src/nm-config-data.h +++ b/src/nm-config-data.h @@ -42,6 +42,7 @@ G_BEGIN_DECLS #define NM_CONFIG_DATA_CONNECTIVITY_URI "connectivity-uri" #define NM_CONFIG_DATA_CONNECTIVITY_INTERVAL "connectivity-interval" #define NM_CONFIG_DATA_CONNECTIVITY_RESPONSE "connectivity-response" +#define NM_CONFIG_DATA_NO_AUTO_DEFAULT "no-auto-default" struct _NMConfigData { GObject parent; @@ -55,7 +56,9 @@ GType nm_config_data_get_type (void); NMConfigData *nm_config_data_new (const char *config_main_file, const char *config_description, + const char *const*no_auto_default, GKeyFile *keyfile); +NMConfigData *nm_config_data_new_update_no_auto_default (const NMConfigData *base, const char *const*no_auto_default); GHashTable *nm_config_data_diff (NMConfigData *old_data, NMConfigData *new_data); @@ -68,6 +71,9 @@ const char *nm_config_data_get_connectivity_uri (const NMConfigData *config_data const guint nm_config_data_get_connectivity_interval (const NMConfigData *config_data); const char *nm_config_data_get_connectivity_response (const NMConfigData *config_data); +const char *const*nm_config_data_get_no_auto_default (const NMConfigData *config_data); +const GSList * nm_config_data_get_no_auto_default_list (const NMConfigData *config_data); + G_END_DECLS #endif /* NM_CONFIG_DATA_H */ diff --git a/src/nm-config.c b/src/nm-config.c index e6f8a38632..3d93edc9b0 100644 --- a/src/nm-config.c +++ b/src/nm-config.c @@ -73,13 +73,9 @@ typedef struct { char *debug; - char **no_auto_default_orig; char **ignore_carrier; gboolean configure_and_quit; - - /* MUTABLE properties: */ - char **no_auto_default; /* mutable via merge_no_auto_default_state() */ } NMConfigPrivate; enum { @@ -102,6 +98,10 @@ G_DEFINE_TYPE (NMConfig, nm_config, G_TYPE_OBJECT) /************************************************************************/ +static void _set_config_data (NMConfig *self, NMConfigData *new_data); + +/************************************************************************/ + static gboolean _get_bool_value (GKeyFile *keyfile, const char *section, @@ -288,32 +288,31 @@ no_auto_default_merge_from_file (const char *no_auto_default_file, const char *c } gboolean -nm_config_get_ethernet_can_auto_default (NMConfig *config, NMDevice *device) +nm_config_get_no_auto_default_for_device (NMConfig *self, NMDevice *device) { - NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); - GSList *specs = NULL; - int i; - gboolean match; + NMConfigData *config_data; - for (i = 0; priv->no_auto_default[i]; i++) - specs = g_slist_prepend (specs, priv->no_auto_default[i]); + g_return_val_if_fail (NM_IS_CONFIG (self), FALSE); + g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); - match = nm_device_spec_match_list (device, specs); - - g_slist_free (specs); - return !match; + config_data = NM_CONFIG_GET_PRIVATE (self)->config_data; + return nm_device_spec_match_list (device, nm_config_data_get_no_auto_default_list (config_data)); } void -nm_config_set_ethernet_no_auto_default (NMConfig *config, NMDevice *device) +nm_config_set_no_auto_default_for_device (NMConfig *self, NMDevice *device) { - NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); + NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (self); char *current; GString *updated; GError *error = NULL; char **no_auto_default; + NMConfigData *new_data = NULL; - if (!nm_config_get_ethernet_can_auto_default (config, device)) + g_return_if_fail (NM_IS_CONFIG (self)); + g_return_if_fail (NM_IS_DEVICE (device)); + + if (nm_config_get_no_auto_default_for_device (self, device)) return; updated = g_string_new (NULL); @@ -335,9 +334,11 @@ nm_config_set_ethernet_no_auto_default (NMConfig *config, NMDevice *device) g_string_free (updated, TRUE); - no_auto_default = no_auto_default_merge_from_file (priv->no_auto_default_file, (const char *const *) priv->no_auto_default); - g_strfreev (priv->no_auto_default); - priv->no_auto_default = no_auto_default; + no_auto_default = no_auto_default_merge_from_file (priv->no_auto_default_file, nm_config_data_get_no_auto_default (priv->config_data)); + new_data = nm_config_data_new_update_no_auto_default (priv->config_data, (const char *const*) no_auto_default); + g_strfreev (no_auto_default); + + _set_config_data (self, new_data); } /************************************************************************/ @@ -681,9 +682,7 @@ nm_config_reload (NMConfig *self) { NMConfigPrivate *priv; GError *error = NULL; - GHashTable *changes; GKeyFile *keyfile; - NMConfigData *old_data; NMConfigData *new_data = NULL; char *config_main_file = NULL; char *config_description = NULL; @@ -692,7 +691,6 @@ nm_config_reload (NMConfig *self) priv = NM_CONFIG_GET_PRIVATE (self); - /* pass on the original command line options. This means, that * options specified at command line cannot ever be reloaded from * file. That seems desirable. @@ -707,12 +705,21 @@ nm_config_reload (NMConfig *self) g_clear_error (&error); return; } - new_data = nm_config_data_new (config_main_file, config_description, keyfile); + new_data = nm_config_data_new (config_main_file, config_description, nm_config_data_get_no_auto_default (priv->config_data), keyfile); g_free (config_main_file); g_free (config_description); g_key_file_unref (keyfile); - old_data = priv->config_data; + _set_config_data (self, new_data); +} + +static void +_set_config_data (NMConfig *self, NMConfigData *new_data) +{ + NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (self); + NMConfigData *old_data = priv->config_data; + GHashTable *changes; + changes = nm_config_data_diff (old_data, new_data); if (!changes) { @@ -771,6 +778,8 @@ nm_config_new (const NMConfigCmdLineOptions *cli, GError **error) GKeyFile *keyfile; char *config_main_file = NULL; char *config_description = NULL; + char **no_auto_default; + char **no_auto_default_orig; self = NM_CONFIG (g_object_new (NM_TYPE_CONFIG, NM_CONFIG_CMD_LINE_OPTIONS, cli, @@ -798,7 +807,6 @@ nm_config_new (const NMConfigCmdLineOptions *cli, GError **error) priv->no_auto_default_file = g_strdup (priv->cli.no_auto_default_file); else priv->no_auto_default_file = g_strdup (NM_NO_AUTO_DEFAULT_STATE_FILE); - priv->no_auto_default_orig = g_key_file_get_string_list (keyfile, "main", "no-auto-default", NULL, NULL); priv->plugins = g_key_file_get_string_list (keyfile, "main", "plugins", NULL, NULL); if (!priv->plugins) @@ -820,13 +828,18 @@ nm_config_new (const NMConfigCmdLineOptions *cli, GError **error) priv->configure_and_quit = _get_bool_value (keyfile, "main", "configure-and-quit", FALSE); - priv->config_data_orig = nm_config_data_new (config_main_file, config_description, keyfile); + no_auto_default_orig = g_key_file_get_string_list (keyfile, "main", "no-auto-default", NULL, NULL); + no_auto_default = no_auto_default_merge_from_file (priv->no_auto_default_file, (const char *const *) no_auto_default_orig); + + priv->config_data_orig = nm_config_data_new (config_main_file, config_description, (const char *const*) no_auto_default, keyfile); + + g_strfreev (no_auto_default); + g_strfreev (no_auto_default_orig); /* Initialize mutable members. */ priv->config_data = g_object_ref (priv->config_data_orig); - priv->no_auto_default = no_auto_default_merge_from_file (priv->no_auto_default_file, (const char *const *) priv->no_auto_default_orig); g_free (config_main_file); g_free (config_description); @@ -855,8 +868,6 @@ finalize (GObject *gobject) g_free (priv->log_level); g_free (priv->log_domains); g_free (priv->debug); - g_strfreev (priv->no_auto_default_orig); - g_strfreev (priv->no_auto_default); g_strfreev (priv->ignore_carrier); _nm_config_cmd_line_options_clear (&priv->cli); diff --git a/src/nm-config.h b/src/nm-config.h index 98a9d2af6d..b52a6b58f8 100644 --- a/src/nm-config.h +++ b/src/nm-config.h @@ -46,6 +46,7 @@ G_BEGIN_DECLS #define NM_CONFIG_CHANGES_CONFIG_FILES "config-files" #define NM_CONFIG_CHANGES_VALUES "values" #define NM_CONFIG_CHANGES_CONNECTIVITY "connectivity" +#define NM_CONFIG_CHANGES_NO_AUTO_DEFAULT "no-auto-default" typedef struct NMConfigCmdLineOptions NMConfigCmdLineOptions; @@ -76,9 +77,6 @@ const char *nm_config_get_log_domains (NMConfig *config); const char *nm_config_get_debug (NMConfig *config); gboolean nm_config_get_configure_and_quit (NMConfig *config); -gboolean nm_config_get_ethernet_can_auto_default (NMConfig *config, NMDevice *device); -void nm_config_set_ethernet_no_auto_default (NMConfig *config, NMDevice *device); - gboolean nm_config_get_ignore_carrier (NMConfig *config, NMDevice *device); /* for main.c only */ @@ -87,6 +85,9 @@ void nm_config_cmd_line_options_free (NMConfigCmdLineOptions void nm_config_cmd_line_options_add_to_entries (NMConfigCmdLineOptions *cli, GOptionContext *opt_ctx); +gboolean nm_config_get_no_auto_default_for_device (NMConfig *config, NMDevice *device); +void nm_config_set_no_auto_default_for_device (NMConfig *config, NMDevice *device); + NMConfig *nm_config_new (const NMConfigCmdLineOptions *cli, GError **error); NMConfig *nm_config_setup (const NMConfigCmdLineOptions *cli, GError **error); void nm_config_reload (NMConfig *config); diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index fe3f9eeece..3a586b747e 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -1687,7 +1687,7 @@ default_wired_clear_tag (NMSettings *self, g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (default_wired_connection_updated_by_user_cb), self); if (add_to_no_auto_default) - nm_config_set_ethernet_no_auto_default (NM_SETTINGS_GET_PRIVATE (self)->config, device); + nm_config_set_no_auto_default_for_device (NM_SETTINGS_GET_PRIVATE (self)->config, device); } void diff --git a/src/tests/config/test-config.c b/src/tests/config/test-config.c index e677243103..67ba5904ec 100644 --- a/src/tests/config/test-config.c +++ b/src/tests/config/test-config.c @@ -198,13 +198,16 @@ test_config_no_auto_default (void) dev3 = nm_test_device_new ("33:33:33:33:33:33"); dev4 = nm_test_device_new ("44:44:44:44:44:44"); - g_assert (!nm_config_get_ethernet_can_auto_default (config, dev1)); - g_assert (!nm_config_get_ethernet_can_auto_default (config, dev2)); - g_assert (nm_config_get_ethernet_can_auto_default (config, dev3)); - g_assert (!nm_config_get_ethernet_can_auto_default (config, dev4)); + g_assert (nm_config_get_no_auto_default_for_device (config, dev1)); + g_assert (nm_config_get_no_auto_default_for_device (config, dev2)); + g_assert (!nm_config_get_no_auto_default_for_device (config, dev3)); + g_assert (nm_config_get_no_auto_default_for_device (config, dev4)); - nm_config_set_ethernet_no_auto_default (config, dev3); - g_assert (!nm_config_get_ethernet_can_auto_default (config, dev3)); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*config: update * (no-auto-default)*"); + nm_config_set_no_auto_default_for_device (config, dev3); + g_test_assert_expected_messages (); + + g_assert (nm_config_get_no_auto_default_for_device (config, dev3)); g_object_unref (config); @@ -212,10 +215,10 @@ test_config_no_auto_default (void) "--no-auto-default", state_file, NULL); - g_assert (!nm_config_get_ethernet_can_auto_default (config, dev1)); - g_assert (!nm_config_get_ethernet_can_auto_default (config, dev2)); - g_assert (!nm_config_get_ethernet_can_auto_default (config, dev3)); - g_assert (!nm_config_get_ethernet_can_auto_default (config, dev4)); + g_assert (nm_config_get_no_auto_default_for_device (config, dev1)); + g_assert (nm_config_get_no_auto_default_for_device (config, dev2)); + g_assert (nm_config_get_no_auto_default_for_device (config, dev3)); + g_assert (nm_config_get_no_auto_default_for_device (config, dev4)); g_object_unref (config);