From fa7cacd7dfb4bac196791003798bc80cbfabeb10 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 20 Apr 2016 17:46:41 +0200 Subject: [PATCH] manager: fix wrongly removing DNS configuration on shutdown When NetworkManager exits, it must preserve the DNS configuration of devices that are left up. Fixes: 9498ea507eb1d5042736c4351337e91b9c13bdf6 (cherry picked from commit 2158d6a5a868ae0d274c45b05425f76ba3e677d7) --- src/devices/nm-device.c | 7 ++++++- src/devices/nm-device.h | 2 +- src/nm-manager.c | 15 +++++++++++++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 348145a0e3..08cf6dce43 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -2600,12 +2600,14 @@ nm_device_get_enslaved (NMDevice *self) /** * nm_device_removed: * @self: the #NMDevice + * @unconfigure_ip_config: whether to clear the IP config objects + * of the device (provided, it is still not cleared at this point). * * Called by the manager when the device was removed. Releases the device from * the master in case it's enslaved. */ void -nm_device_removed (NMDevice *self) +nm_device_removed (NMDevice *self, gboolean unconfigure_ip_config) { NMDevicePrivate *priv; @@ -2618,6 +2620,9 @@ nm_device_removed (NMDevice *self) nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); } + if (!unconfigure_ip_config) + return; + /* Clean up IP configs; this does not actually deconfigure the * interface, it just clears the configuration to which policy * is reacting via NM_DEVICE_IP4_CONFIG_CHANGED/NM_DEVICE_IP6_CONFIG_CHANGED diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 2221ede12d..9f6898505c 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -385,7 +385,7 @@ gboolean nm_device_has_unmodified_applied_connection (NMDevice *self, NMSettingCompareFlags compare_flags); NMSetting * nm_device_get_applied_setting (NMDevice *dev, GType setting_type); -void nm_device_removed (NMDevice *dev); +void nm_device_removed (NMDevice *self, gboolean unconfigure_ip_config); gboolean nm_device_is_available (NMDevice *dev, NMDeviceCheckDevAvailableFlags flags); gboolean nm_device_has_carrier (NMDevice *dev); diff --git a/src/nm-manager.c b/src/nm-manager.c index a55e94c00a..e64c68af90 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -833,13 +833,13 @@ remove_device (NMManager *self, gboolean allow_unmanage) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + gboolean unmanage = FALSE; _LOGD (LOGD_DEVICE, "(%s): removing device (allow_unmanage %d, managed %d)", nm_device_get_iface (device), allow_unmanage, nm_device_get_managed (device, FALSE)); if (allow_unmanage && nm_device_get_managed (device, FALSE)) { NMActRequest *req = nm_device_get_act_request (device); - gboolean unmanage = FALSE; /* Leave activated interfaces up when quitting so their configuration * can be taken over when NM restarts. This ensures connectivity while @@ -869,7 +869,18 @@ remove_device (NMManager *self, priv->devices = g_slist_remove (priv->devices, device); if (nm_device_is_real (device)) { - nm_device_removed (device); + gboolean unconfigure_ip_config = !quitting || unmanage; + + /* When we don't unmanage the device on shutdown, we want to preserve the DNS + * configuration in resolv.conf. For that, we must leak the configuration + * in NMPolicy/NMDnsManager. We do that, by emitting the device-removed signal + * with device's ip-config object still uncleared. In that case, NMPolicy + * never learns to unconfigure the ip-config objects and does not remove them + * from DNS on shutdown (which is ugly, because we don't cleanup the memory + * properly). + * + * Control that by passing @unconfigure_ip_config. */ + nm_device_removed (device, unconfigure_ip_config); g_signal_emit (self, signals[DEVICE_REMOVED], 0, device); _notify (self, PROP_DEVICES);