From 41598c1f1ad68c3ff8d3e923000ce4278d648feb Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 7 Jan 2015 17:09:52 +0100 Subject: [PATCH] config: move no-auto-default to NMConfigData With this change, NMConfig is really immutable and all modifyable parts migrated to NMConfigData. Another advantage is that components can now subscribe to NMConfig changes to pickup changes to no-auto-default. (cherry picked from commit 13c7f6a56db55db47d31a181c85913f1d183f95a) --- src/devices/nm-device-ethernet.c | 2 +- src/nm-config-data.c | 70 ++++++++++++++++++++++++++++++ src/nm-config-data.h | 6 +++ src/nm-config.c | 73 ++++++++++++++++++-------------- src/nm-config.h | 7 +-- src/settings/nm-settings.c | 2 +- src/tests/config/test-config.c | 23 +++++----- 7 files changed, 137 insertions(+), 46 deletions(-) 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);