From 818352a0342358f4c62465aa5b3590b8e5fb924d Mon Sep 17 00:00:00 2001 From: Gris Ge Date: Tue, 26 Sep 2023 15:00:32 +0800 Subject: [PATCH 1/2] emit DNS CONFIG_CHANGED signal even dns=none Instruct the `NMDnsManager` to emit `CONFIG_CHANGED` signal even `dns=none` or failed to modify `/etc/resolv.conf`. The `NMPolicy` will only update hostname when DNS is managed. Signed-off-by: Gris Ge (cherry picked from commit a847ba807572c3ef3682e833432f2f93e9d519a0) (cherry picked from commit d10f20fd01a7bb3225c7e38ed80449e19156344b) (cherry picked from commit e0f3a91a95d45f729bd42956617aafb84e26a47b) (cherry picked from commit cd9ebfd2bb76b99b861af1272f5ef9bb0d279008) --- src/core/dns/nm-dns-manager.c | 12 +++++++++++- src/core/dns/nm-dns-manager.h | 2 ++ src/core/nm-policy.c | 10 ++++++---- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/core/dns/nm-dns-manager.c b/src/core/dns/nm-dns-manager.c index 416a9bf915..2d5f1245b3 100644 --- a/src/core/dns/nm-dns-manager.c +++ b/src/core/dns/nm-dns-manager.c @@ -1907,7 +1907,7 @@ plugin_skip:; } /* signal that DNS resolution configs were changed */ - if ((do_update || caching || force_emit) && result == SR_SUCCESS) + if ((caching || force_emit) && result == SR_SUCCESS) g_signal_emit(self, signals[CONFIG_CHANGED], 0); nm_clear_pointer(&priv->config_variant, g_variant_unref); @@ -1923,6 +1923,16 @@ plugin_skip:; return TRUE; } +gboolean +nm_dns_manager_is_unmanaged(NMDnsManager *self) +{ + NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE(self); + + return NM_IN_SET(priv->rc_manager, + NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED, + NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE); +} + /*****************************************************************************/ gboolean diff --git a/src/core/dns/nm-dns-manager.h b/src/core/dns/nm-dns-manager.h index b41bf1ccf2..b697b3e380 100644 --- a/src/core/dns/nm-dns-manager.h +++ b/src/core/dns/nm-dns-manager.h @@ -148,4 +148,6 @@ char *nmtst_dns_create_resolv_conf(const char *const *searches, const char *const *nameservers, const char *const *options); +gboolean nm_dns_manager_is_unmanaged(NMDnsManager *self); + #endif /* __NETWORKMANAGER_DNS_MANAGER_H__ */ diff --git a/src/core/nm-policy.c b/src/core/nm-policy.c index 0b7c9eddca..d9e7643fa2 100644 --- a/src/core/nm-policy.c +++ b/src/core/nm-policy.c @@ -2563,11 +2563,13 @@ dns_config_changed(NMDnsManager *dns_manager, gpointer user_data) if (priv->updating_dns) return; - nm_manager_for_each_device (priv->manager, device, tmp_lst) { - nm_device_clear_dns_lookup_data(device, "DNS configuration changed"); - } + if (!nm_dns_manager_is_unmanaged(dns_manager)) { + nm_manager_for_each_device (priv->manager, device, tmp_lst) { + nm_device_clear_dns_lookup_data(device, "DNS configuration changed"); + } - update_system_hostname(self, "DNS configuration changed"); + update_system_hostname(self, "DNS configuration changed"); + } } static void -- 2.41.0 From 206d974bfbd3f0496d2263ec8a12ee58ce085b0e Mon Sep 17 00:00:00 2001 From: Gris Ge Date: Wed, 18 Oct 2023 15:03:13 +0800 Subject: [PATCH 2/2] dispatch `dns-change` dispatcher event Introducing new dispatcher event -- `dns-change` which will be emitted when DNS configuration changed(even in `dns=none` mode). This is to solve two use cases: * Invoke dispatch script for DNS changes triggered by the global DNS API. * Do not invoke [OpenShift resolv-prepender][1] for non-DNS changes. Bug reference: https://issues.redhat.com/browse/RHEL-1671 [1]: https://github.com/openshift/machine-config-operator/blob/master/templates/common/on-prem/files/resolv-prepender.yaml Signed-off-by: Gris Ge (cherry picked from commit a1db61ebc9712d1faf2ef8f1b2cb14cd819346d3) (cherry picked from commit 3cdce71b95cea11bf409d9353c35a4dea6f33984) (cherry picked from commit 9ae535c61a5116179ba2f775458427b93518ac49) (cherry picked from commit e74a349e1e88e06436a6809b92faa249910daabd) --- man/NetworkManager-dispatcher.xml | 5 +- src/core/nm-dispatcher.c | 51 ++++++++++++++++--- src/core/nm-dispatcher.h | 5 +- src/core/nm-policy.c | 2 + src/libnm-core-aux-extern/nm-dispatcher-api.h | 1 + src/nm-dispatcher/nm-dispatcher-utils.c | 8 ++- 6 files changed, 60 insertions(+), 12 deletions(-) diff --git a/man/NetworkManager-dispatcher.xml b/man/NetworkManager-dispatcher.xml index 4a603b1566..8a3c0b46ed 100644 --- a/man/NetworkManager-dispatcher.xml +++ b/man/NetworkManager-dispatcher.xml @@ -68,8 +68,9 @@ device an operation just happened on, and second the action. For device actions, the interface is the name of the kernel interface suitable for IP configuration. Thus it is either VPN_IP_IFACE, DEVICE_IP_IFACE, or DEVICE_IFACE, as applicable. - For the hostname action the device name is always "none" - and for connectivity-change it is empty. + For the hostname action the device name is always "none". + For connectivity-change it is empty. + For dns-change it is empty. The actions are: diff --git a/src/core/nm-dispatcher.c b/src/core/nm-dispatcher.c index d3529ee4de..a0ce4de80d 100644 --- a/src/core/nm-dispatcher.c +++ b/src/core/nm-dispatcher.c @@ -49,6 +49,8 @@ } \ G_STMT_END +static gboolean nm_dispatcher_need_device(NMDispatcherAction action); + /*****************************************************************************/ struct NMDispatcherCallId { @@ -465,7 +467,8 @@ static const char *action_table[] = {[NM_DISPATCHER_ACTION_HOSTNAME] = NMD_ [NM_DISPATCHER_ACTION_DHCP_CHANGE_4] = NMD_ACTION_DHCP4_CHANGE, [NM_DISPATCHER_ACTION_DHCP_CHANGE_6] = NMD_ACTION_DHCP6_CHANGE, [NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE] = - NMD_ACTION_CONNECTIVITY_CHANGE}; + NMD_ACTION_CONNECTIVITY_CHANGE, + [NM_DISPATCHER_ACTION_DNS_CHANGE] = NMD_ACTION_DNS_CHANGE}; static const char * action_to_string(NMDispatcherAction action) @@ -526,9 +529,7 @@ _dispatcher_call(NMDispatcherAction action, if (G_UNLIKELY(!request_id)) request_id = ++gl.request_id_counter; - /* All actions except 'hostname' and 'connectivity-change' require a device */ - if (action == NM_DISPATCHER_ACTION_HOSTNAME - || action == NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE) { + if (!nm_dispatcher_need_device(action)) { _LOG2D(request_id, log_ifname, log_con_uuid, @@ -588,9 +589,8 @@ _dispatcher_call(NMDispatcherAction action, g_variant_builder_init(&vpn_ip4_props, G_VARIANT_TYPE_VARDICT); g_variant_builder_init(&vpn_ip6_props, G_VARIANT_TYPE_VARDICT); - /* hostname and connectivity-change actions don't send device data */ - if (action != NM_DISPATCHER_ACTION_HOSTNAME - && action != NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE) { + /* hostname, DNS and connectivity-change actions don't send device data */ + if (nm_dispatcher_need_device(action)) { fill_device_props(device, &device_props, &device_proxy_props, @@ -921,6 +921,30 @@ nm_dispatcher_call_connectivity(NMConnectivityState connectivity_state, out_call_id); } +/** + * nm_dispatcher_call_dns_change(): + * + * This method does not block the caller. + * + * Returns: %TRUE if the action was dispatched, %FALSE on failure + */ +gboolean +nm_dispatcher_call_dns_change(void) +{ + return _dispatcher_call(NM_DISPATCHER_ACTION_DNS_CHANGE, + FALSE, + NULL, + NULL, + NULL, + FALSE, + NM_CONNECTIVITY_UNKNOWN, + NULL, + NULL, + NULL, + NULL, + NULL); +} + void nm_dispatcher_call_cancel(NMDispatcherCallId *call_id) { @@ -933,3 +957,16 @@ nm_dispatcher_call_cancel(NMDispatcherCallId *call_id) _LOG3D(call_id, "cancelling dispatcher callback action"); call_id->callback = NULL; } + +/* All actions except 'hostname', 'connectivity-change' and 'dns-change' require + * a device */ +static gboolean +nm_dispatcher_need_device(NMDispatcherAction action) +{ + if (action == NM_DISPATCHER_ACTION_HOSTNAME + || action == NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE + || action == NM_DISPATCHER_ACTION_DNS_CHANGE) { + return FALSE; + } + return TRUE; +} diff --git a/src/core/nm-dispatcher.h b/src/core/nm-dispatcher.h index 73e0599a75..50d50e9a6a 100644 --- a/src/core/nm-dispatcher.h +++ b/src/core/nm-dispatcher.h @@ -21,7 +21,8 @@ typedef enum { NM_DISPATCHER_ACTION_VPN_DOWN, NM_DISPATCHER_ACTION_DHCP_CHANGE_4, NM_DISPATCHER_ACTION_DHCP_CHANGE_6, - NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE + NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE, + NM_DISPATCHER_ACTION_DNS_CHANGE, } NMDispatcherAction; #define NM_DISPATCHER_ACTION_DHCP_CHANGE_X(IS_IPv4) \ @@ -68,6 +69,8 @@ gboolean nm_dispatcher_call_connectivity(NMConnectivityState state, gpointer user_data, NMDispatcherCallId **out_call_id); +gboolean nm_dispatcher_call_dns_change(void); + void nm_dispatcher_call_cancel(NMDispatcherCallId *call_id); #endif /* __NM_DISPATCHER_H__ */ diff --git a/src/core/nm-policy.c b/src/core/nm-policy.c index d9e7643fa2..9316325c68 100644 --- a/src/core/nm-policy.c +++ b/src/core/nm-policy.c @@ -2570,6 +2570,8 @@ dns_config_changed(NMDnsManager *dns_manager, gpointer user_data) update_system_hostname(self, "DNS configuration changed"); } + + nm_dispatcher_call_dns_change(); } static void diff --git a/src/libnm-core-aux-extern/nm-dispatcher-api.h b/src/libnm-core-aux-extern/nm-dispatcher-api.h index 7776c84f9a..d19caa0bb5 100644 --- a/src/libnm-core-aux-extern/nm-dispatcher-api.h +++ b/src/libnm-core-aux-extern/nm-dispatcher-api.h @@ -33,6 +33,7 @@ #define NMD_ACTION_DHCP4_CHANGE "dhcp4-change" #define NMD_ACTION_DHCP6_CHANGE "dhcp6-change" #define NMD_ACTION_CONNECTIVITY_CHANGE "connectivity-change" +#define NMD_ACTION_DNS_CHANGE "dns-change" typedef enum { DISPATCH_RESULT_UNKNOWN = 0, diff --git a/src/nm-dispatcher/nm-dispatcher-utils.c b/src/nm-dispatcher/nm-dispatcher-utils.c index 74ea4e4001..f8a4c28000 100644 --- a/src/nm-dispatcher/nm-dispatcher-utils.c +++ b/src/nm-dispatcher/nm-dispatcher-utils.c @@ -453,8 +453,12 @@ nm_dispatcher_utils_construct_envp(const char *action, items = g_ptr_array_new_with_free_func(g_free); - /* Hostname and connectivity changes don't require a device nor contain a connection */ - if (NM_IN_STRSET(action, NMD_ACTION_HOSTNAME, NMD_ACTION_CONNECTIVITY_CHANGE)) + /* Hostname, dns and connectivity changes don't require a device nor contain + * a connection */ + if (NM_IN_STRSET(action, + NMD_ACTION_HOSTNAME, + NMD_ACTION_CONNECTIVITY_CHANGE, + NMD_ACTION_DNS_CHANGE)) goto done; /* Connection properties */ -- 2.41.0