From 390778edec75c647a3648dc9e533548ca6eca8be Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 30 May 2016 16:43:39 +0200 Subject: [PATCH] config,dns: support Reload flags to specify that only parts should be reloaded Support 3 new flags for Reload: - 0x01 (CONF): reload the configuration from disk - 0x02 (DNS_RC): write DNS configuration to resolv.conf - 0x04 (DNS_FULL): restart DNS plugin Omitting all flags is the same as reloading everything, thus SIGHUP. (cherry picked from commit 0acee9722072c99b552d6030f88d307a0acaea79) --- introspection/nm-manager.xml | 23 +++++++++++++++++++++-- man/NetworkManager.conf.xml | 4 ++++ man/NetworkManager.xml | 5 +++++ src/dns-manager/nm-dns-manager.c | 8 ++++++-- src/nm-config-data.h | 26 ++++++++++++++++++++++++-- src/nm-config.c | 10 ++++++++-- src/nm-manager.c | 27 +++++++++++++++++++++------ 7 files changed, 89 insertions(+), 14 deletions(-) diff --git a/introspection/nm-manager.xml b/introspection/nm-manager.xml index ba898a78c8..ea368ba331 100644 --- a/introspection/nm-manager.xml +++ b/introspection/nm-manager.xml @@ -5,8 +5,27 @@ diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml index 8127f5b7fc..ee9b5679f3 100644 --- a/man/NetworkManager.conf.xml +++ b/man/NetworkManager.conf.xml @@ -78,6 +78,10 @@ This file is not intended to be modified by the user, but it is read last and can shadow user configuration from NetworkManager.conf. + + Certain settings from the configuration can be reloaded at runtime either by sending SIGHUP signal or via + D-Bus' Reload call. + diff --git a/man/NetworkManager.xml b/man/NetworkManager.xml index d7f09ef401..0714d002d4 100644 --- a/man/NetworkManager.xml +++ b/man/NetworkManager.xml @@ -462,6 +462,11 @@ + + An alternative to a signal to reload configuration is the Reload D-Bus call. + It allows for more fine-grained selection of what to reload, it only returns + after the reload is complete, and it is guarded by PolicyKit. + diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c index b753954823..114b33d6c0 100644 --- a/src/dns-manager/nm-dns-manager.c +++ b/src/dns-manager/nm-dns-manager.c @@ -1610,17 +1610,21 @@ config_changed_cb (NMConfig *config, if (NM_FLAGS_ANY (changes, NM_CONFIG_CHANGE_DNS_MODE | NM_CONFIG_CHANGE_RC_MANAGER | - NM_CONFIG_CHANGE_CAUSE_SIGHUP)) { + NM_CONFIG_CHANGE_CAUSE_SIGHUP | + NM_CONFIG_CHANGE_CAUSE_DNS_FULL)) { /* reload the resolv-conf mode also on SIGHUP (when DNS_MODE didn't change). * The reason is, that the configuration also depends on whether resolv.conf * is immutable, thus, without the configuration changing, we always want to * re-configure the mode. */ init_resolv_conf_mode (self, - NM_FLAGS_HAS (changes, NM_CONFIG_CHANGE_CAUSE_SIGHUP)); + NM_FLAGS_ANY (changes, NM_CONFIG_CHANGE_CAUSE_SIGHUP + | NM_CONFIG_CHANGE_CAUSE_DNS_FULL)); } if (NM_FLAGS_ANY (changes, NM_CONFIG_CHANGE_CAUSE_SIGHUP | NM_CONFIG_CHANGE_CAUSE_SIGUSR1 | + NM_CONFIG_CHANGE_CAUSE_DNS_RC | + NM_CONFIG_CHANGE_CAUSE_DNS_FULL | NM_CONFIG_CHANGE_DNS_MODE | NM_CONFIG_CHANGE_RC_MANAGER | NM_CONFIG_CHANGE_GLOBAL_DNS_CONFIG)) { diff --git a/src/nm-config-data.h b/src/nm-config-data.h index 4fe07eb4b8..017d362996 100644 --- a/src/nm-config-data.h +++ b/src/nm-config-data.h @@ -44,7 +44,26 @@ G_BEGIN_DECLS #define NM_CONFIG_DATA_NO_AUTO_DEFAULT "no-auto-default" #define NM_CONFIG_DATA_DNS_MODE "dns" -typedef enum { /**/ +/* The flags for Reload. Currently these are internal defines, + * only their numeric value matters and must be stable as + * they are public API! Also, the enum must fit in uint32. */ +enum { /*< skip >*/ + NM_MANAGER_RELOAD_FLAGS_NONE = 0, + + /* reload the configuration from disk */ + NM_MANAGER_RELOAD_FLAGS_CONF = (1LL << 0), + + /* write DNS configuration to resolv.conf */ + NM_MANAGER_RELOAD_FLAGS_DNS_RC = (1LL << 1), + + /* restart the DNS plugin (includes DNS_RC) */ + NM_MANAGER_RELOAD_FLAGS_DNS_FULL = (1LL << 2), + + _NM_MANAGER_RELOAD_FLAGS_ALL, + NM_MANAGER_RELOAD_FLAGS_ALL = ((_NM_MANAGER_RELOAD_FLAGS_ALL - 1) << 1) - 1, +}; + +typedef enum { /*< flags >*/ NM_CONFIG_GET_VALUE_NONE = 0, /* use g_key_file_get_value() instead of g_key_file_get_string(). */ @@ -73,8 +92,11 @@ typedef enum { /*< flags >*/ NM_CONFIG_CHANGE_CAUSE_SIGUSR2 = (1L << 2), NM_CONFIG_CHANGE_CAUSE_NO_AUTO_DEFAULT = (1L << 3), NM_CONFIG_CHANGE_CAUSE_SET_VALUES = (1L << 4), + NM_CONFIG_CHANGE_CAUSE_CONF = (1L << 5), + NM_CONFIG_CHANGE_CAUSE_DNS_RC = (1L << 6), + NM_CONFIG_CHANGE_CAUSE_DNS_FULL = (1L << 7), - NM_CONFIG_CHANGE_CAUSES = ((1L << 5) - 1), + NM_CONFIG_CHANGE_CAUSES = ((1L << 8) - 1), /************************************************************************** * Following flags describe which property of the configuration changed: diff --git a/src/nm-config.c b/src/nm-config.c index 7875a38f55..b2a9b863d3 100644 --- a/src/nm-config.c +++ b/src/nm-config.c @@ -1666,7 +1666,7 @@ nm_config_reload (NMConfig *self, NMConfigChangeFlags reload_flags) priv = NM_CONFIG_GET_PRIVATE (self); - if (reload_flags != NM_CONFIG_CHANGE_CAUSE_SIGHUP) { + if (!NM_FLAGS_ANY (reload_flags, NM_CONFIG_CHANGE_CAUSE_SIGHUP | NM_CONFIG_CHANGE_CAUSE_CONF)) { /* unless SIGHUP is specified, we don't reload the configuration from disc. */ _set_config_data (self, NULL, reload_flags); return; @@ -1712,6 +1712,9 @@ nm_config_reload (NMConfig *self, NMConfigChangeFlags reload_flags) NM_UTILS_FLAGS2STR_DEFINE (nm_config_change_flags_to_string, NMConfigChangeFlags, + NM_UTILS_FLAGS2STR (NM_CONFIG_CHANGE_CAUSE_CONF, "CONF"), + NM_UTILS_FLAGS2STR (NM_CONFIG_CHANGE_CAUSE_DNS_RC, "DNS_RC"), + NM_UTILS_FLAGS2STR (NM_CONFIG_CHANGE_CAUSE_DNS_FULL, "DNS_FULL"), NM_UTILS_FLAGS2STR (NM_CONFIG_CHANGE_CAUSE_SIGHUP, "SIGHUP"), NM_UTILS_FLAGS2STR (NM_CONFIG_CHANGE_CAUSE_SIGUSR1, "SIGUSR1"), NM_UTILS_FLAGS2STR (NM_CONFIG_CHANGE_CAUSE_SIGUSR2, "SIGUSR2"), @@ -1752,7 +1755,10 @@ _set_config_data (NMConfig *self, NMConfigData *new_data, NMConfigChangeFlags re changes |= changes_diff; } - if ( NM_IN_SET (reload_flags, NM_CONFIG_CHANGE_CAUSE_NO_AUTO_DEFAULT, NM_CONFIG_CHANGE_CAUSE_SET_VALUES) + if ( NM_IN_SET (reload_flags, + NM_CONFIG_CHANGE_CAUSE_NO_AUTO_DEFAULT, + NM_CONFIG_CHANGE_CAUSE_SET_VALUES, + NM_CONFIG_CHANGE_CAUSE_CONF) && !new_data) { /* no relevant changes that should be propagated. Return silently. */ return; diff --git a/src/nm-manager.c b/src/nm-manager.c index 9c0d0fa9de..61cfa155d8 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -471,6 +471,7 @@ _reload_auth_cb (NMAuthChain *chain, guint32 flags; NMAuthSubject *subject; char s_buf[60]; + NMConfigChangeFlags reload_type = NM_CONFIG_CHANGE_NONE; g_assert (context); @@ -490,10 +491,25 @@ _reload_auth_cb (NMAuthChain *chain, ret_error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED, "Not authorized to reload configuration"); - } else if (flags != 0) { - ret_error = g_error_new_literal (NM_MANAGER_ERROR, - NM_MANAGER_ERROR_INVALID_ARGUMENTS, - "Invalid flags for reload"); + } else { + if (NM_FLAGS_ANY (flags, ~NM_MANAGER_RELOAD_FLAGS_ALL)) { + /* invalid flags */ + } else if (flags == 0) + reload_type = NM_CONFIG_CHANGE_CAUSE_SIGHUP; + else { + if (NM_FLAGS_HAS (flags, NM_MANAGER_RELOAD_FLAGS_CONF)) + reload_type |= NM_CONFIG_CHANGE_CAUSE_CONF; + if (NM_FLAGS_HAS (flags, NM_MANAGER_RELOAD_FLAGS_DNS_RC)) + reload_type |= NM_CONFIG_CHANGE_CAUSE_DNS_RC; + if (NM_FLAGS_HAS (flags, NM_MANAGER_RELOAD_FLAGS_DNS_FULL)) + reload_type |= NM_CONFIG_CHANGE_CAUSE_DNS_FULL; + } + + if (reload_type == NM_CONFIG_CHANGE_NONE) { + ret_error = g_error_new_literal (NM_MANAGER_ERROR, + NM_MANAGER_ERROR_INVALID_ARGUMENTS, + "Invalid flags for reload"); + } } nm_audit_log_control_op (NM_AUDIT_OP_RELOAD, @@ -506,8 +522,7 @@ _reload_auth_cb (NMAuthChain *chain, goto out; } - nm_config_reload (priv->config, NM_CONFIG_CHANGE_CAUSE_SIGHUP); - + nm_config_reload (priv->config, reload_type); g_dbus_method_invocation_return_value (context, NULL); out: