From ced1dcabefdf8663e034822d8773aa79a071a043 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 1 Oct 2015 10:50:14 +0200 Subject: [PATCH 1/4] config/trivial: rename nm_config_get_device_match_spec() to nm_config_get_match_spec() We want to use the term match-spec more generally and not only for "device-specs". --- src/nm-config-data.c | 14 +++++++------- src/nm-config.c | 2 +- src/nm-config.h | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/nm-config-data.c b/src/nm-config-data.c index 02467c53d7..a9b9891e46 100644 --- a/src/nm-config-data.c +++ b/src/nm-config-data.c @@ -1087,10 +1087,10 @@ _get_connection_info_init (ConnectionInfo *connection_info, GKeyFile *keyfile, c /* pass ownership of @group on... */ connection_info->group_name = group; - connection_info->match_device.spec = nm_config_get_device_match_spec (keyfile, - group, - "match-device", - &connection_info->match_device.has); + connection_info->match_device.spec = nm_config_get_match_spec (keyfile, + group, + "match-device", + &connection_info->match_device.has); connection_info->stop_match = nm_config_keyfile_get_boolean (keyfile, group, "stop-match", FALSE); } @@ -1362,10 +1362,10 @@ constructed (GObject *object) priv->dns_mode = nm_strstrip (g_key_file_get_string (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "dns", NULL)); priv->rc_manager = nm_strstrip (g_key_file_get_string (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "rc-manager", NULL)); - priv->ignore_carrier = nm_config_get_device_match_spec (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "ignore-carrier", NULL); - priv->assume_ipv6ll_only = nm_config_get_device_match_spec (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "assume-ipv6ll-only", NULL); + priv->ignore_carrier = nm_config_get_match_spec (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "ignore-carrier", NULL); + priv->assume_ipv6ll_only = nm_config_get_match_spec (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "assume-ipv6ll-only", NULL); - priv->no_auto_default.specs_config = nm_config_get_device_match_spec (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "no-auto-default", NULL); + priv->no_auto_default.specs_config = nm_config_get_match_spec (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "no-auto-default", NULL); priv->global_dns = load_global_dns (priv->keyfile_user, FALSE); if (!priv->global_dns) diff --git a/src/nm-config.c b/src/nm-config.c index f2b72e3a57..e09ec48ecd 100644 --- a/src/nm-config.c +++ b/src/nm-config.c @@ -1416,7 +1416,7 @@ intern_config_write (const char *filename, /************************************************************************/ GSList * -nm_config_get_device_match_spec (const GKeyFile *keyfile, const char *group, const char *key, gboolean *out_has_key) +nm_config_get_match_spec (const GKeyFile *keyfile, const char *group, const char *key, gboolean *out_has_key) { gs_free char *value = NULL; diff --git a/src/nm-config.h b/src/nm-config.h index 0e96c3e85c..46b2ac85ff 100644 --- a/src/nm-config.h +++ b/src/nm-config.h @@ -143,7 +143,7 @@ void nm_config_keyfile_set_string_list (GKeyFile *keyfile, const char *key, const char *const* strv, gssize len); -GSList *nm_config_get_device_match_spec (const GKeyFile *keyfile, const char *group, const char *key, gboolean *out_has_key); +GSList *nm_config_get_match_spec (const GKeyFile *keyfile, const char *group, const char *key, gboolean *out_has_key); void _nm_config_sort_groups (char **groups, gsize ngroups); From 72ff5e8cac5739c427b1f0c8bfe7f431396d12b9 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 1 Oct 2015 13:01:39 +0200 Subject: [PATCH 2/4] core: add nm_utils_ascii_str_to_bool() This is effectively the same as nm_config_parse_boolean(). The difference is, that "nm-config.c" is not available to the interface-helper, thus any code used by interface-helper (like "NetworkManager.c") cannot use this function. Still don't drop nm_config_parse_boolean() entirely, because it's better to have the explicit notion of parsing a string in the config-context. I ended up not using the function. But I'd still keep this patch. --- src/NetworkManagerUtils.c | 34 ++++++++++++++++++++++++++++++++++ src/NetworkManagerUtils.h | 5 +++++ src/nm-config.c | 27 +-------------------------- 3 files changed, 40 insertions(+), 26 deletions(-) diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index d5bb6c87f0..5d9df4ec8c 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -188,6 +188,40 @@ _nm_singleton_instance_register_destruction (GObject *instance) /*****************************************************************************/ +gint +nm_utils_ascii_str_to_bool (const char *str, + gint default_value) +{ + gsize len; + char *s = NULL; + + if (!str) + return default_value; + + while (str[0] && g_ascii_isspace (str[0])) + str++; + + if (!str[0]) + return default_value; + + len = strlen (str); + if (g_ascii_isspace (str[len - 1])) { + s = g_strdup (str); + g_strchomp (s); + str = s; + } + + if (!g_ascii_strcasecmp (str, "true") || !g_ascii_strcasecmp (str, "yes") || !g_ascii_strcasecmp (str, "on") || !g_ascii_strcasecmp (str, "1")) + default_value = TRUE; + else if (!g_ascii_strcasecmp (str, "false") || !g_ascii_strcasecmp (str, "no") || !g_ascii_strcasecmp (str, "off") || !g_ascii_strcasecmp (str, "0")) + default_value = FALSE; + if (s) + g_free (s); + return default_value; +} + +/*****************************************************************************/ + /* * nm_ethernet_address_is_valid: * @addr: pointer to a binary or ASCII Ethernet address diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h index 3af93e5a03..ceaa2c0c77 100644 --- a/src/NetworkManagerUtils.h +++ b/src/NetworkManagerUtils.h @@ -114,6 +114,11 @@ gboolean nm_utils_error_is_cancelled (GError *error, /*****************************************************************************/ +gint nm_utils_ascii_str_to_bool (const char *str, + gint default_value); + +/*****************************************************************************/ + gboolean nm_ethernet_address_is_valid (gconstpointer addr, gssize len); in_addr_t nm_utils_ip4_address_clear_host_address (in_addr_t addr, guint8 plen); diff --git a/src/nm-config.c b/src/nm-config.c index e09ec48ecd..fb9f0be988 100644 --- a/src/nm-config.c +++ b/src/nm-config.c @@ -126,32 +126,7 @@ gint nm_config_parse_boolean (const char *str, gint default_value) { - gsize len; - char *s = NULL; - - if (!str) - return default_value; - - while (str[0] && g_ascii_isspace (str[0])) - str++; - - if (!str[0]) - return default_value; - - len = strlen (str); - if (g_ascii_isspace (str[len - 1])) { - s = g_strdup (str); - g_strchomp (s); - str = s; - } - - if (!g_ascii_strcasecmp (str, "true") || !g_ascii_strcasecmp (str, "yes") || !g_ascii_strcasecmp (str, "on") || !g_ascii_strcasecmp (str, "1")) - default_value = TRUE; - else if (!g_ascii_strcasecmp (str, "false") || !g_ascii_strcasecmp (str, "no") || !g_ascii_strcasecmp (str, "off") || !g_ascii_strcasecmp (str, "0")) - default_value = FALSE; - if (s) - g_free (s); - return default_value; + return nm_utils_ascii_str_to_bool (str, default_value); } gint From 7182304684250a8b52664f6bee34747a05e41bd5 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 1 Oct 2015 10:43:33 +0200 Subject: [PATCH 3/4] config: allow to enable/disable configuration snippets Support a new configuration option [.config] enable= for configuration snippets. This new [.config] section is only relevant within the snippet itself and it is not merged into the combined configuration. Currently only the "enable" key is supported. If the "enable" key is missing, it obviously defaults to being enabled. It allows snippets to be skipped from loading. The main configuration "NetworkManager.conf" cannot be skipped. can be a boolean value (false), to skip a configuration snippet from loading. It can also be a string to match against the NetworkManager version, like "enable=nm-version-min:1.1,nm-version-min:1.0.6" There are several motivations for this: - the user can disable an entire configuration snippet by toggeling one entry. This generalizes the functionality of the global-dns.enable setting, but in a way that applies to configuration on a per-file basis. - for developing, we often switch between different versions of NetworkManager. Thus, we might want to use different configuration. E.g. before global-dns options, I want to use "dns=none" and manage resolv.conf myself. Now, I can use global-dns setting to do that. That can be achieved with something like the following (not exactly, it's an example only): [.config] enable=nm-version-min:1.1 [main] dns=default [global-dns-domain-*] nameserver=127.0.0.1 Arguably, this would be more awesome, if we would bump our micro devel version (1.1.0) more often while developing 1.2.0 (*hint*). - in principle, packages could drop configuration snippets and enable them based on the NetworkManager version. - with the "env:" spec, you can enable/disable snippets by configuring an environment variable. Again, useful for testing and developing. --- include/nm-macros-internal.h | 15 ++ man/NetworkManager.conf.xml.in | 89 +++++++++++ src/NetworkManagerUtils.c | 118 +++++++++++++++ src/NetworkManagerUtils.h | 1 + src/nm-config.c | 66 +++++++- src/nm-config.h | 6 + src/tests/config/Makefile.am | 1 + .../config/conf.d/20-config-enable-1.conf | 5 + src/tests/config/test-config.c | 36 +++++ src/tests/test-general.c | 143 ++++++++++++++++++ 10 files changed, 474 insertions(+), 6 deletions(-) create mode 100644 src/tests/config/conf.d/20-config-enable-1.conf diff --git a/include/nm-macros-internal.h b/include/nm-macros-internal.h index b1d75e68ed..0bf25821ad 100644 --- a/include/nm-macros-internal.h +++ b/include/nm-macros-internal.h @@ -286,4 +286,19 @@ nm_strstrip (char *str) /*****************************************************************************/ +static inline guint +nm_encode_version (guint major, guint minor, guint micro) { + /* analog to the preprocessor macro NM_ENCODE_VERSION(). */ + return (major << 16) | (minor << 8) | micro; +} + +static inline void +nm_decode_version (guint version, guint *major, guint *minor, guint *micro) { + *major = (version & 0xFFFF0000u) >> 16; + *minor = (version & 0x0000FF00u) >> 8; + *micro = (version & 0x000000FFu); +} + +/*****************************************************************************/ + #endif /* __NM_MACROS_INTERNAL_H__ */ diff --git a/man/NetworkManager.conf.xml.in b/man/NetworkManager.conf.xml.in index a8b7f3a38d..0fccc84dc6 100644 --- a/man/NetworkManager.conf.xml.in +++ b/man/NetworkManager.conf.xml.in @@ -702,6 +702,95 @@ ipv6.ip6-privacy=1 + + <literal>.config</literal> sections + This is a special section that contains options which apply + to the configuration file that contains the option. + + + + + enable + + + Defaults to "true". If "false", + the configuration file will be skipped during loading. + Note that the main configation file NetworkManger.conf + cannot be disabled. + +# always skip loading the config file +[.config] +enable=false + + + + You can also match against the version of NetworkManager. For example + the following are valid configurations: + +# only load on version 1.0.6 +[.config] +enable=nm-version:1.0.6 + +# load on all versions 1.0.x, but not 1.2.x +[.config] +enable=nm-version:1.0 + +# only load on versions >= 1.1.6. This does not match +# with version 1.2.0 or 1.4.4. Only the last digit is considered. +[.config] +enable=nm-version-min:1.1.6 + +# only load on versions >= 1.2. Contrary to the previous +# example, this also matches with 1.2.0, 1.2.10, 1.4.4, etc. +[.config] +enable=nm-version-min:1.2 + +# Match against the maximum allowed version. The example matches +# versions 1.2.0, 1.2.2, 1.2.4. Again, only the last version digit +# is allowed to be smaller. So this would not match match on 1.1.10. +[.config] +enable=nm-version-max:1.2.6 + + + + You can also match against the value of the environment variable + NM_CONFIG_ENABLE_TAG, like: + +# always skip loading the file when running NetworkManager with +# environment variable "NM_CONFIG_ENABLE_TAG=TAG1" +[.config] +enable=env:TAG1 + + + + More then one match can be specified. The configuration will be + enabled if one of the predicates matches ("or"). The special prefix "except:" can + be used to negate the match. Note that if one except-predicate + matches, the entire configuration will be disabled. + In other words, a except predicate always wins over other predicates. + +# enable the configuration either when the environment variable +# is present or the version is at least 1.2.0. +[.config] +enable=env:TAG2,nm-version-min:1.2 + +# enable the configuration for version >= 1.2.0, but disable +# it when the environment variable is set to "TAG3" +[.config] +enable=except:env:TAG3,nm-version-min:1.2 + +# enable the configuration on >= 1.3, >= 1.2.6, and >= 1.0.16. +# Useful if a certain feature is only present since those releases. +[.config] +enable=nm-version-min:1.3,nm-version-min:1.2.6,nm-version-min:1.0.16 + + + + + + + + Plugins diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 5d9df4ec8c..726ceb9b4a 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -1193,6 +1193,22 @@ nm_utils_find_helper(const char *progname, const char *try_first, GError **error #define DEVICE_TYPE_TAG "type:" #define SUBCHAN_TAG "s390-subchannels:" #define EXCEPT_TAG "except:" +#define MATCH_TAG_CONFIG_NM_VERSION "nm-version:" +#define MATCH_TAG_CONFIG_NM_VERSION_MIN "nm-version-min:" +#define MATCH_TAG_CONFIG_NM_VERSION_MAX "nm-version-max:" +#define MATCH_TAG_CONFIG_ENV "env:" + +#define _spec_has_prefix(pspec, tag) \ + ({ \ + const char **_spec = (pspec); \ + gboolean _has = FALSE; \ + \ + if (!g_ascii_strncasecmp (*_spec, (""tag), STRLEN (tag))) { \ + *_spec += STRLEN (tag); \ + _has = TRUE; \ + } \ + _has; \ + }) static const char * _match_except (const char *spec_str, gboolean *out_except) @@ -1422,6 +1438,108 @@ nm_match_spec_s390_subchannels (const GSList *specs, const char *subchannels) return match; } +static gboolean +_match_config_nm_version (const char *str, const char *tag, guint cur_nm_version) +{ + gs_free char *s_ver = NULL; + gs_strfreev char **s_ver_tokens = NULL; + gint v_maj = -1, v_min = -1, v_mic = -1; + guint c_maj = -1, c_min = -1, c_mic = -1; + guint n_tokens; + + s_ver = g_strdup (str); + g_strstrip (s_ver); + + /* Let's be strict with the accepted format here. No funny stuff!! */ + + if (s_ver[strspn (s_ver, ".0123456789")] != '\0') + return FALSE; + + s_ver_tokens = g_strsplit (s_ver, ".", -1); + n_tokens = g_strv_length (s_ver_tokens); + if (n_tokens == 0 || n_tokens > 3) + return FALSE; + + v_maj = _nm_utils_ascii_str_to_int64 (s_ver_tokens[0], 10, 0, 0xFFFF, -1); + if (v_maj < 0) + return FALSE; + if (n_tokens >= 2) { + v_min = _nm_utils_ascii_str_to_int64 (s_ver_tokens[1], 10, 0, 0xFF, -1); + if (v_min < 0) + return FALSE; + } + if (n_tokens >= 3) { + v_mic = _nm_utils_ascii_str_to_int64 (s_ver_tokens[2], 10, 0, 0xFF, -1); + if (v_mic < 0) + return FALSE; + } + + nm_decode_version (cur_nm_version, &c_maj, &c_min, &c_mic); + +#define CHECK_AND_RETURN_FALSE(cur, val, tag, is_last_digit) \ + G_STMT_START { \ + if (!strcmp (tag, MATCH_TAG_CONFIG_NM_VERSION_MIN)) { \ + if (cur < val) \ + return FALSE; \ + } else if (!strcmp (tag, MATCH_TAG_CONFIG_NM_VERSION_MAX)) { \ + if (cur > val) \ + return FALSE; \ + } else { \ + if (cur != val) \ + return FALSE; \ + } \ + if (!(is_last_digit)) { \ + if (cur != val) \ + return FALSE; \ + } \ + } G_STMT_END + if (v_mic >= 0) + CHECK_AND_RETURN_FALSE (c_mic, v_mic, tag, TRUE); + if (v_min >= 0) + CHECK_AND_RETURN_FALSE (c_min, v_min, tag, v_mic < 0); + CHECK_AND_RETURN_FALSE (c_maj, v_maj, tag, v_min < 0); + return TRUE; +} + +NMMatchSpecMatchType +nm_match_spec_match_config (const GSList *specs, guint cur_nm_version, const char *env) +{ + const GSList *iter; + NMMatchSpecMatchType match = NM_MATCH_SPEC_NO_MATCH; + + if (!specs) + return NM_MATCH_SPEC_NO_MATCH; + + for (iter = specs; iter; iter = g_slist_next (iter)) { + const char *spec_str = iter->data; + gboolean except; + gboolean v_match; + + if (!spec_str || !*spec_str) + continue; + + spec_str = _match_except (spec_str, &except); + + if (_spec_has_prefix (&spec_str, MATCH_TAG_CONFIG_NM_VERSION)) + v_match = _match_config_nm_version (spec_str, MATCH_TAG_CONFIG_NM_VERSION, cur_nm_version); + else if (_spec_has_prefix (&spec_str, MATCH_TAG_CONFIG_NM_VERSION_MIN)) + v_match = _match_config_nm_version (spec_str, MATCH_TAG_CONFIG_NM_VERSION_MIN, cur_nm_version); + else if (_spec_has_prefix (&spec_str, MATCH_TAG_CONFIG_NM_VERSION_MAX)) + v_match = _match_config_nm_version (spec_str, MATCH_TAG_CONFIG_NM_VERSION_MAX, cur_nm_version); + else if (_spec_has_prefix (&spec_str, MATCH_TAG_CONFIG_ENV)) + v_match = env && env[0] && !strcmp (spec_str, env); + else + continue; + + if (v_match) { + if (except) + return NM_MATCH_SPEC_NEG_MATCH; + match = NM_MATCH_SPEC_MATCH; + } + } + return match; +} + /** * nm_match_spec_split: * @value: the string of device specs diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h index ceaa2c0c77..bf90e741cd 100644 --- a/src/NetworkManagerUtils.h +++ b/src/NetworkManagerUtils.h @@ -187,6 +187,7 @@ NMMatchSpecMatchType nm_match_spec_device_type (const GSList *specs, const char NMMatchSpecMatchType nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr); NMMatchSpecMatchType nm_match_spec_s390_subchannels (const GSList *specs, const char *subchannels); NMMatchSpecMatchType nm_match_spec_interface_name (const GSList *specs, const char *interface_name); +NMMatchSpecMatchType nm_match_spec_match_config (const GSList *specs, guint nm_version, const char *env); GSList *nm_match_spec_split (const char *value); char *nm_match_spec_join (GSList *specs); diff --git a/src/nm-config.c b/src/nm-config.c index fb9f0be988..f8c4ee817d 100644 --- a/src/nm-config.c +++ b/src/nm-config.c @@ -495,6 +495,47 @@ nm_config_create_keyfile () return keyfile; } +/* this is an external variable, to make loading testable. Other then that, + * no code is supposed to change this. */ +guint _nm_config_match_nm_version = NM_VERSION_CUR_STABLE; +char *_nm_config_match_env = NULL; + +static gboolean +ignore_config_snippet (GKeyFile *keyfile, gboolean is_base_config) +{ + GSList *specs; + gboolean as_bool; + NMMatchSpecMatchType match_type; + + if (is_base_config) + return FALSE; + + if (!g_key_file_has_key (keyfile, NM_CONFIG_KEYFILE_GROUP_CONFIG, NM_CONFIG_KEYFILE_KEY_CONFIG_ENABLE, NULL)) + return FALSE; + + /* first, let's try to parse the value as plain boolean. If that is possible, we don't treat + * the value as match-spec. */ + as_bool = nm_config_keyfile_get_boolean (keyfile, NM_CONFIG_KEYFILE_GROUP_CONFIG, NM_CONFIG_KEYFILE_KEY_CONFIG_ENABLE, -1); + if (as_bool != -1) + return !as_bool; + + if (G_UNLIKELY (!_nm_config_match_env)) { + const char *e; + + e = g_getenv ("NM_CONFIG_ENABLE_TAG"); + _nm_config_match_env = g_strdup (e ? e : ""); + } + + /* second, interpret the value as match-spec. */ + specs = nm_config_get_match_spec (keyfile, NM_CONFIG_KEYFILE_GROUP_CONFIG, NM_CONFIG_KEYFILE_KEY_CONFIG_ENABLE, NULL); + match_type = nm_match_spec_match_config (specs, + _nm_config_match_nm_version, + _nm_config_match_env); + g_slist_free_full (specs, g_free); + + return match_type != NM_MATCH_SPEC_MATCH; +} + static int _sort_groups_cmp (const char **pa, const char **pb, gpointer dummy) { @@ -568,7 +609,7 @@ _setting_is_string_list (const char *group, const char *key) } static gboolean -read_config (GKeyFile *keyfile, const char *dirname, const char *path, GError **error) +read_config (GKeyFile *keyfile, gboolean is_base_config, const char *dirname, const char *path, GError **error) { GKeyFile *kf; char **groups, **keys; @@ -598,6 +639,16 @@ read_config (GKeyFile *keyfile, const char *dirname, const char *path, GError ** return FALSE; } + if (ignore_config_snippet (kf, is_base_config)) { + g_key_file_free (kf); + return TRUE; + } + + /* the config-group is internal to every configuration snippets. It doesn't make sense + * to merge the into the global configuration, and it doesn't make sense to preserve the + * group beyond this point. */ + g_key_file_remove_group (keyfile, NM_CONFIG_KEYFILE_GROUP_CONFIG, NULL); + /* Override the current settings with the new ones */ groups = g_key_file_get_groups (kf, &ngroups); if (!groups) @@ -744,7 +795,7 @@ read_base_config (GKeyFile *keyfile, /* Try a user-specified config file first */ if (cli_config_main_file) { /* Bad user-specific config file path is a hard error */ - if (read_config (keyfile, NULL, cli_config_main_file, error)) { + if (read_config (keyfile, TRUE, NULL, cli_config_main_file, error)) { *out_config_main_file = g_strdup (cli_config_main_file); return TRUE; } else @@ -759,7 +810,7 @@ read_base_config (GKeyFile *keyfile, */ /* Try deprecated nm-system-settings.conf first */ - if (read_config (keyfile, NULL, DEFAULT_CONFIG_MAIN_FILE_OLD, &my_error)) { + if (read_config (keyfile, TRUE, NULL, DEFAULT_CONFIG_MAIN_FILE_OLD, &my_error)) { *out_config_main_file = g_strdup (DEFAULT_CONFIG_MAIN_FILE_OLD); return TRUE; } @@ -772,7 +823,7 @@ read_base_config (GKeyFile *keyfile, g_clear_error (&my_error); /* Try the standard config file location next */ - if (read_config (keyfile, NULL, DEFAULT_CONFIG_MAIN_FILE, &my_error)) { + if (read_config (keyfile, TRUE, NULL, DEFAULT_CONFIG_MAIN_FILE, &my_error)) { *out_config_main_file = g_strdup (DEFAULT_CONFIG_MAIN_FILE); return TRUE; } @@ -878,7 +929,7 @@ read_entire_config (const NMConfigCmdLineOptions *cli, continue; } - if (!read_config (keyfile, system_config_dir, filename, error)) { + if (!read_config (keyfile, FALSE, system_config_dir, filename, error)) { g_key_file_free (keyfile); return NULL; } @@ -894,7 +945,7 @@ read_entire_config (const NMConfigCmdLineOptions *cli, g_assert (o_config_main_file); for (i = 0; i < confs->len; i++) { - if (!read_config (keyfile, config_dir, confs->pdata[i], error)) { + if (!read_config (keyfile, FALSE, config_dir, confs->pdata[i], error)) { g_key_file_free (keyfile); return NULL; } @@ -1067,6 +1118,9 @@ intern_config_read (const char *filename, const char *group = groups[g]; gboolean is_intern, is_atomic; + if (!strcmp (group, NM_CONFIG_KEYFILE_GROUP_CONFIG)) + continue; + keys = g_key_file_get_keys (keyfile, group, NULL, NULL); if (!keys) continue; diff --git a/src/nm-config.h b/src/nm-config.h index 46b2ac85ff..59a3e854b2 100644 --- a/src/nm-config.h +++ b/src/nm-config.h @@ -56,6 +56,7 @@ G_BEGIN_DECLS #define NM_CONFIG_KEYFILE_GROUP_LOGGING "logging" #define NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY "connectivity" #define NM_CONFIG_KEYFILE_GROUP_GLOBAL_DNS "global-dns" +#define NM_CONFIG_KEYFILE_GROUP_CONFIG ".config" #define NM_CONFIG_KEYFILE_GROUP_KEYFILE "keyfile" #define NM_CONFIG_KEYFILE_GROUP_IFUPDOWN "ifupdown" @@ -63,6 +64,7 @@ G_BEGIN_DECLS #define NM_CONFIG_KEYFILE_KEY_LOGGING_BACKEND "backend" #define NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_ENABLE "enable" +#define NM_CONFIG_KEYFILE_KEY_CONFIG_ENABLE "enable" #define NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS ".was" #define NM_CONFIG_KEYFILE_KEY_IFNET_AUTO_REFRESH "auto_refresh" #define NM_CONFIG_KEYFILE_KEY_IFNET_MANAGED "managed" @@ -149,6 +151,10 @@ void _nm_config_sort_groups (char **groups, gsize ngroups); gboolean nm_config_set_global_dns (NMConfig *self, NMGlobalDnsConfig *global_dns, GError **error); +/* internal defines ... */ +extern guint _nm_config_match_nm_version; +extern char *_nm_config_match_env; + G_END_DECLS #endif /* __NETWORKMANAGER_CONFIG_H__ */ diff --git a/src/tests/config/Makefile.am b/src/tests/config/Makefile.am index 6ad9876f1f..4f3d7805d8 100644 --- a/src/tests/config/Makefile.am +++ b/src/tests/config/Makefile.am @@ -34,4 +34,5 @@ EXTRA_DIST = \ global-dns-invalid.conf \ conf.d/00-overrides.conf \ conf.d/10-more.conf \ + conf.d/20-config-enable-1.conf \ conf.d/90-last.conf diff --git a/src/tests/config/conf.d/20-config-enable-1.conf b/src/tests/config/conf.d/20-config-enable-1.conf new file mode 100644 index 0000000000..e6800f5236 --- /dev/null +++ b/src/tests/config/conf.d/20-config-enable-1.conf @@ -0,0 +1,5 @@ +[.config] +enable=nm-version:1.5.32,env:test-match-env-1 + +[test-group-config-enable-1] +key1=enabled diff --git a/src/tests/config/test-config.c b/src/tests/config/test-config.c index d3b2db6920..5eee306a9e 100644 --- a/src/tests/config/test-config.c +++ b/src/tests/config/test-config.c @@ -905,6 +905,40 @@ test_config_signal (void) /*****************************************************************************/ +static void +test_config_enable (void) +{ + gs_unref_object NMConfig *config = NULL; + guint match_nm_version = _nm_config_match_nm_version; + char *match_env = g_strdup (_nm_config_match_env); + + g_clear_pointer (&_nm_config_match_env, g_free); + _nm_config_match_env = g_strdup ("something-else"); + + _nm_config_match_nm_version = nm_encode_version (1, 3, 4); + config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, SRCDIR "/conf.d", "", NULL); + assert_config_value (nm_config_get_data_orig (config), "test-group-config-enable-1", "key1", NULL); + g_clear_object (&config); + + _nm_config_match_nm_version = nm_encode_version (1, 5, 32); + config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, SRCDIR "/conf.d", "", NULL); + assert_config_value (nm_config_get_data_orig (config), "test-group-config-enable-1", "key1", "enabled"); + g_clear_object (&config); + + _nm_config_match_nm_version = nm_encode_version (1, 5, 3); + g_clear_pointer (&_nm_config_match_env, g_free); + _nm_config_match_env = g_strdup ("test-match-env-1"); + config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, SRCDIR "/conf.d", "", NULL); + assert_config_value (nm_config_get_data_orig (config), "test-group-config-enable-1", "key1", "enabled"); + g_clear_object (&config); + + _nm_config_match_nm_version = match_nm_version; + g_clear_pointer (&_nm_config_match_env, g_free); + _nm_config_match_env = match_env; +} + +/*****************************************************************************/ + NMTST_DEFINE (); int @@ -933,6 +967,8 @@ main (int argc, char **argv) g_test_add_func ("/config/signal", test_config_signal); + g_test_add_func ("/config/enable", test_config_enable); + /* This one has to come last, because it leaves its values in * nm-config.c's global variables, and there's no way to reset * those to NULL. diff --git a/src/tests/test-general.c b/src/tests/test-general.c index ba3d958fb3..3c2a33a97d 100644 --- a/src/tests/test-general.c +++ b/src/tests/test-general.c @@ -773,6 +773,148 @@ test_nm_match_spec_interface_name (void) /*******************************************/ +static void +_do_test_match_spec_match_config (const char *file, gint line, const char *spec_str, guint version, guint v_maj, guint v_min, guint v_mic, NMMatchSpecMatchType expected) +{ + GSList *specs; + NMMatchSpecMatchType match_result; + guint c_maj, c_min, c_mic; + + g_assert_cmpint (version, ==, nm_encode_version (v_maj, v_min, v_mic)); + + nm_decode_version (version, &c_maj, &c_min, &c_mic); + g_assert_cmpint (c_maj, ==, c_maj); + g_assert_cmpint (c_min, ==, c_min); + g_assert_cmpint (c_mic, ==, c_mic); + + specs = nm_match_spec_split (spec_str); + + match_result = nm_match_spec_match_config (specs, version, NULL); + + if (expected != match_result) + g_error ("%s:%d: faild comparing \"%s\" with %u.%u.%u. Expected %d, but got %d", file, line, spec_str, v_maj, v_min, v_mic, (int) expected, (int) match_result); + + if (g_slist_length (specs) == 1 && match_result != NM_MATCH_SPEC_NEG_MATCH) { + /* there is only one spec in the list... test that we match except: */ + char *sss = g_strdup_printf ("except:%s", (char *) specs->data); + GSList *specs2 = g_slist_append (NULL, sss); + NMMatchSpecMatchType match_result2; + + + match_result2 = nm_match_spec_match_config (specs2, version, NULL); + if (match_result == NM_MATCH_SPEC_NO_MATCH) + g_assert_cmpint (match_result2, ==, NM_MATCH_SPEC_NO_MATCH); + else + g_assert_cmpint (match_result2, ==, NM_MATCH_SPEC_NEG_MATCH); + + g_slist_free_full (specs2, g_free); + } + + g_slist_free_full (specs, g_free); +} +#define do_test_match_spec_match_config(spec, v_maj, v_min, v_mic, expected) \ + _do_test_match_spec_match_config (__FILE__, __LINE__, (""spec), NM_ENCODE_VERSION ((v_maj), (v_min), (v_mic)), (v_maj), (v_min), (v_mic), (expected)) + +static void +test_nm_match_spec_match_config (void) +{ + do_test_match_spec_match_config ("", 1, 2, 3, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version:1.2.3", 1, 2, 2, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version:1.2.3", 1, 2, 3, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version:1.2.3", 1, 2, 4, NM_MATCH_SPEC_NO_MATCH); + + do_test_match_spec_match_config ("nm-version:1.2", 1, 1, 2, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version:1.2", 1, 2, 0, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version:1.2", 1, 2, 2, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version:1.2", 1, 2, 3, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version:1.2", 1, 2, 4, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version:1.2", 1, 3, 0, NM_MATCH_SPEC_NO_MATCH); + + do_test_match_spec_match_config ("nm-version-min:1.2.3", 0, 2, 30, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2.3", 1, 1, 1, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2.3", 1, 2, 2, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2.3", 1, 2, 3, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2.3", 1, 2, 5, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2.3", 1, 3, 0, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2.3", 1, 3, 30, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2.3", 1, 4, 30, NM_MATCH_SPEC_NO_MATCH); + + do_test_match_spec_match_config ("nm-version-min:1.2", 0, 2, 30, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2", 1, 1, 1, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2", 1, 2, 0, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2", 1, 2, 3, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2", 1, 2, 5, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2", 1, 3, 0, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2", 1, 3, 30, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2", 1, 4, 30, NM_MATCH_SPEC_MATCH); + + do_test_match_spec_match_config ("nm-version-min:1", 0, 2, 30, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1", 1, 1, 1, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1", 1, 2, 0, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1", 1, 2, 3, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1", 1, 2, 5, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1", 1, 3, 0, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1", 1, 3, 30, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1", 1, 4, 30, NM_MATCH_SPEC_MATCH); + + + do_test_match_spec_match_config ("nm-version-max:1.2.3", 0, 2, 30, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 1, 1, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 2, 0, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 2, 1, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 2, 2, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 2, 3, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 2, 5, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 3, 0, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 3, 30, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 4, 30, NM_MATCH_SPEC_NO_MATCH); + + do_test_match_spec_match_config ("nm-version-max:1.2", 0, 2, 30, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2", 1, 1, 1, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2", 1, 2, 0, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2", 1, 2, 3, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2", 1, 2, 5, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2", 1, 3, 0, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2", 1, 3, 30, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2", 1, 4, 30, NM_MATCH_SPEC_NO_MATCH); + + do_test_match_spec_match_config ("nm-version-max:1", 0, 2, 30, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1", 1, 1, 1, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1", 1, 2, 0, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1", 1, 2, 3, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1", 1, 2, 5, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1", 1, 3, 0, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1", 1, 3, 30, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1", 1, 4, 30, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1", 2, 4, 30, NM_MATCH_SPEC_NO_MATCH); + + do_test_match_spec_match_config ("except:nm-version:1.4.8", 1, 6, 0, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.6,except:nm-version:1.4.8", 1, 6, 0, NM_MATCH_SPEC_MATCH); + + do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 2, 0, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 2, 0, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 2, 15, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 2, 16, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 2, 17, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 2, 20, NM_MATCH_SPEC_MATCH); + + do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 3, 0, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 4, 0, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 4, 5, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 4, 6, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 4, 7, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 4, 8, NM_MATCH_SPEC_NEG_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 4, 9, NM_MATCH_SPEC_MATCH); + + do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 5, 0, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 6, 0, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 6, 5, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 7, 7, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 8, 8, NM_MATCH_SPEC_MATCH); +} + +/*******************************************/ + NMTST_DEFINE (); int @@ -796,6 +938,7 @@ main (int argc, char **argv) g_test_add_func ("/general/connection-sort/autoconnect-priority", test_connection_sort_autoconnect_priority); g_test_add_func ("/general/nm_match_spec_interface_name", test_nm_match_spec_interface_name); + g_test_add_func ("/general/nm_match_spec_match_config", test_nm_match_spec_match_config); return g_test_run (); } From da0ded49279cce454c9aefeccd6943e7d58f3475 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 1 Oct 2015 14:00:01 +0200 Subject: [PATCH 4/4] config: drop global-dns.enable option in favor of .config.enable No longer support disabling the global-dns configuration via the "enable" option. Instead, the user can put the entire dns-configuration in one separate snippet, and disable it altogether with ".config.enable". --- man/NetworkManager.conf.xml.in | 8 ------ src/nm-config-data.c | 2 +- src/nm-config.c | 32 ++++++++++++++++++++--- src/nm-config.h | 3 ++- src/tests/config/Makefile.am | 1 - src/tests/config/global-dns-disabled.conf | 8 ------ src/tests/config/global-dns-invalid.conf | 1 - src/tests/config/test-config.c | 7 ----- 8 files changed, 32 insertions(+), 30 deletions(-) delete mode 100644 src/tests/config/global-dns-disabled.conf diff --git a/man/NetworkManager.conf.xml.in b/man/NetworkManager.conf.xml.in index 0fccc84dc6..f7bcd1a359 100644 --- a/man/NetworkManager.conf.xml.in +++ b/man/NetworkManager.conf.xml.in @@ -642,14 +642,6 @@ ipv6.ip6-privacy=1 connection-specific configuration. - - enable - - - Whether the global DNS configuration should be used. - - - searches diff --git a/src/nm-config-data.c b/src/nm-config-data.c index a9b9891e46..66b1da5916 100644 --- a/src/nm-config-data.c +++ b/src/nm-config-data.c @@ -731,7 +731,7 @@ load_global_dns (GKeyFile *keyfile, gboolean internal) : NM_CONFIG_KEYFILE_GROUPPREFIX_GLOBAL_DNS_DOMAIN; domain_prefix_len = strlen (domain_prefix); - if (!keyfile || !nm_config_keyfile_get_boolean (keyfile, group, NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_ENABLE, FALSE)) + if (!nm_config_keyfile_has_global_dns_config (keyfile, internal)) return NULL; conf = g_malloc0 (sizeof (NMGlobalDnsConfig)); diff --git a/src/nm-config.c b/src/nm-config.c index f8c4ee817d..f070ff9756 100644 --- a/src/nm-config.c +++ b/src/nm-config.c @@ -1066,6 +1066,34 @@ _keyfile_serialize_section (GKeyFile *keyfile, const char *group) return g_string_free (str, FALSE); } +gboolean +nm_config_keyfile_has_global_dns_config (GKeyFile *keyfile, gboolean internal) +{ + gs_strfreev char **groups = NULL; + guint g; + const char *prefix; + + if (!keyfile) + return FALSE; + if (g_key_file_has_group (keyfile, + internal + ? NM_CONFIG_KEYFILE_GROUP_GLOBAL_DNS + : NM_CONFIG_KEYFILE_GROUP_INTERN_GLOBAL_DNS)) + return TRUE; + + groups = g_key_file_get_groups (keyfile, NULL); + if (!groups) + return FALSE; + + prefix = internal ? NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_GLOBAL_DNS_DOMAIN : NM_CONFIG_KEYFILE_GROUPPREFIX_GLOBAL_DNS_DOMAIN; + + for (g = 0; groups[g]; g++) { + if (g_str_has_prefix (groups[g], prefix)) + return TRUE; + } + return FALSE; +} + /** * intern_config_read: * @filename: the filename where to store the internal config @@ -1219,7 +1247,7 @@ out: * deletion of options from user configuration may cause the * internal options to appear again. */ - if (nm_config_keyfile_get_boolean (keyfile_conf, NM_CONFIG_KEYFILE_GROUP_GLOBAL_DNS, NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_ENABLE, FALSE)) { + if (nm_config_keyfile_has_global_dns_config (keyfile_conf, FALSE)) { if (g_key_file_remove_group (keyfile_intern, NM_CONFIG_KEYFILE_GROUP_INTERN_GLOBAL_DNS, NULL)) needs_rewrite = TRUE; for (g = 0; groups && groups[g]; g++) { @@ -1497,8 +1525,6 @@ nm_config_set_global_dns (NMConfig *self, NMGlobalDnsConfig *global_dns, GError goto done; /* Set new values */ - g_key_file_set_string (keyfile, NM_CONFIG_KEYFILE_GROUP_INTERN_GLOBAL_DNS, NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_ENABLE, "yes"); - nm_config_keyfile_set_string_list (keyfile, NM_CONFIG_KEYFILE_GROUP_INTERN_GLOBAL_DNS, "searches", nm_global_dns_config_get_searches (global_dns), -1); diff --git a/src/nm-config.h b/src/nm-config.h index 59a3e854b2..eb195138bd 100644 --- a/src/nm-config.h +++ b/src/nm-config.h @@ -63,7 +63,6 @@ G_BEGIN_DECLS #define NM_CONFIG_KEYFILE_GROUP_IFNET "ifnet" #define NM_CONFIG_KEYFILE_KEY_LOGGING_BACKEND "backend" -#define NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_ENABLE "enable" #define NM_CONFIG_KEYFILE_KEY_CONFIG_ENABLE "enable" #define NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS ".was" #define NM_CONFIG_KEYFILE_KEY_IFNET_AUTO_REFRESH "auto_refresh" @@ -145,6 +144,8 @@ void nm_config_keyfile_set_string_list (GKeyFile *keyfile, const char *key, const char *const* strv, gssize len); +gboolean nm_config_keyfile_has_global_dns_config (GKeyFile *keyfile, gboolean internal); + GSList *nm_config_get_match_spec (const GKeyFile *keyfile, const char *group, const char *key, gboolean *out_has_key); void _nm_config_sort_groups (char **groups, gsize ngroups); diff --git a/src/tests/config/Makefile.am b/src/tests/config/Makefile.am index 4f3d7805d8..80f923c46e 100644 --- a/src/tests/config/Makefile.am +++ b/src/tests/config/Makefile.am @@ -30,7 +30,6 @@ TESTS = test-config EXTRA_DIST = \ NetworkManager.conf \ bad.conf \ - global-dns-disabled.conf \ global-dns-invalid.conf \ conf.d/00-overrides.conf \ conf.d/10-more.conf \ diff --git a/src/tests/config/global-dns-disabled.conf b/src/tests/config/global-dns-disabled.conf deleted file mode 100644 index 53ccd832e2..0000000000 --- a/src/tests/config/global-dns-disabled.conf +++ /dev/null @@ -1,8 +0,0 @@ -[global-dns] -enable=no -searches=foo.com -options=timeout:5 - -[global-dns-domain-*] -servers=1.2.3.4 -options=myoption diff --git a/src/tests/config/global-dns-invalid.conf b/src/tests/config/global-dns-invalid.conf index 10ecc9b04c..e490f609cc 100644 --- a/src/tests/config/global-dns-invalid.conf +++ b/src/tests/config/global-dns-invalid.conf @@ -1,7 +1,6 @@ # Invalid configuration, since there isn't a default domain section [global-dns] -enable=yes searches=foo.com options=timeout:5 diff --git a/src/tests/config/test-config.c b/src/tests/config/test-config.c index 5eee306a9e..ed6f875740 100644 --- a/src/tests/config/test-config.c +++ b/src/tests/config/test-config.c @@ -305,13 +305,6 @@ test_config_global_dns (void) g_object_unref (config); - /* Check that a file without "enable=yes" gives a NULL configuration */ - config = setup_config (NULL, SRCDIR "/global-dns-disabled.conf", "", NULL, - "/no/such/dir", "", NULL); - dns = nm_config_data_get_global_dns_config (nm_config_get_data_orig (config)); - g_assert (!dns); - g_object_unref (config); - /* Check that a file without a default domain section gives a NULL configuration */ config = setup_config (NULL, SRCDIR "/global-dns-invalid.conf", "", NULL, "/no/such/dir", "", NULL);