From 194b14e39899e8f3a73b1a151ed5384ecbf80149 Mon Sep 17 00:00:00 2001 From: Mikhail Efremov Date: Mon, 31 Mar 2014 20:29:05 +0400 Subject: [PATCH 1/3] core: don't generate a connection for unmanaged devices --- src/nm-manager.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/nm-manager.c b/src/nm-manager.c index 9d08b898e9..9300050ece 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1751,6 +1751,7 @@ add_device (NMManager *self, NMDevice *device, gboolean generate_con) char *path; static guint32 devcount = 0; const GSList *unmanaged_specs; + gboolean unmanaged = FALSE; NMConnection *connection = NULL; gboolean enabled = FALSE; RfKillType rtype; @@ -1847,15 +1848,17 @@ add_device (NMManager *self, NMDevice *device, gboolean generate_con) nm_log_info (LOGD_CORE, "(%s): exported as %s", iface, path); g_free (path); + unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings); + unmanaged = nm_device_spec_match_list (device, unmanaged_specs); + /* Don't generate a connection e.g. for devices NM just created, or * for the loopback */ - if (generate_con) + if (generate_con && !unmanaged) connection = get_existing_connection (self, device); /* Start the device if it's supposed to be managed */ - unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings); if ( !manager_sleeping (self) - && !nm_device_spec_match_list (device, unmanaged_specs)) { + && !unmanaged) { nm_device_set_manager_managed (device, TRUE, connection ? NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED : From 6c299bc19be01a0ed0e4c89f1b8141fdfc338818 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 31 Mar 2014 21:45:54 -0500 Subject: [PATCH 2/3] core: convert unmanaged bits to flags Instead of tracking unmanaged-ness in a couple variables (and because I'd like to add one for user-unmanaged later) let's do it in a single flags variable, and consolidate setting of the unmanaged states in one place. --- src/devices/nm-device-generic.c | 2 +- src/devices/nm-device.c | 128 +++++++++++++++++++++----------- src/devices/nm-device.h | 31 ++++++-- src/nm-manager.c | 50 +++++++------ 4 files changed, 139 insertions(+), 72 deletions(-) diff --git a/src/devices/nm-device-generic.c b/src/devices/nm-device-generic.c index 1c4c8affe1..b82c2b1223 100644 --- a/src/devices/nm-device-generic.c +++ b/src/devices/nm-device-generic.c @@ -127,7 +127,7 @@ nm_device_generic_new (NMPlatformLink *platform_device) static void nm_device_generic_init (NMDeviceGeneric *self) { - nm_device_set_default_unmanaged (NM_DEVICE (self), TRUE); + nm_device_set_initial_unmanaged_flag (NM_DEVICE (self), NM_UNMANAGED_DEFAULT, TRUE); } static void diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 0906da3ebe..6f33366a88 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -221,9 +221,8 @@ typedef struct { guint hw_addr_len; char * physical_port_id; - gboolean manager_managed; /* whether managed by NMManager or not */ - gboolean default_unmanaged; /* whether unmanaged by default */ - gboolean is_nm_owned; /* whether the device is a device owned and created by NM */ + NMUnmanagedFlags unmanaged_flags; + gboolean is_nm_owned; /* whether the device is a device owned and created by NM */ DeleteOnDeactivateData *delete_on_deactivate_data; /* data for scheduled cleanup when deleting link (g_idle_add) */ guint32 ip4_address; @@ -5038,7 +5037,7 @@ _device_activate (NMDevice *self, NMActRequest *req) delete_on_deactivate_unschedule (self); /* Move default unmanaged devices to DISCONNECTED state here */ - if (priv->default_unmanaged && priv->state == NM_DEVICE_STATE_UNMANAGED) { + if (nm_device_get_default_unmanaged (self) && priv->state == NM_DEVICE_STATE_UNMANAGED) { nm_device_state_changed (self, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NOW_MANAGED); @@ -6715,7 +6714,8 @@ nm_device_state_changed (NMDevice *device, if (old_state == NM_DEVICE_STATE_UNMANAGED) { nm_log_dbg (LOGD_DEVICE, "(%s): device not yet available for transition to DISCONNECTED", nm_device_get_iface (device)); - } else if (old_state > NM_DEVICE_STATE_UNAVAILABLE && priv->default_unmanaged) + } else if ( old_state > NM_DEVICE_STATE_UNAVAILABLE + && nm_device_get_default_unmanaged (device)) nm_device_queue_state (device, NM_DEVICE_STATE_UNMANAGED, NM_DEVICE_STATE_REASON_NONE); } break; @@ -6730,7 +6730,8 @@ nm_device_state_changed (NMDevice *device, priv->queued_act_request = NULL; _device_activate (device, queued_req); g_object_unref (queued_req); - } else if (old_state > NM_DEVICE_STATE_DISCONNECTED && priv->default_unmanaged) + } else if ( old_state > NM_DEVICE_STATE_DISCONNECTED + && nm_device_get_default_unmanaged (device)) nm_device_queue_state (device, NM_DEVICE_STATE_UNMANAGED, NM_DEVICE_STATE_REASON_NONE); break; case NM_DEVICE_STATE_ACTIVATED: @@ -7115,79 +7116,120 @@ nm_device_queued_ip_config_change_clear (NMDevice *self) } } +/** + * nm_device_get_managed(): + * @device: the #NMDevice + * + * Returns: %TRUE if the device is managed + */ gboolean nm_device_get_managed (NMDevice *device) { NMDevicePrivate *priv; + gboolean managed; g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); priv = NM_DEVICE_GET_PRIVATE (device); - if (!priv->manager_managed) - return FALSE; - else if (priv->default_unmanaged) - return (priv->state != NM_DEVICE_STATE_UNMANAGED); - else - return TRUE; + /* Return the composite of all managed flags. However, if the device + * is a default-unmanaged device, and would be managed except for the + * default-unmanaged flag (eg, only NM_UNMANAGED_DEFAULT is set) then + * the device is managed whenever it's not in the UNMANAGED state. + */ + managed = !(priv->unmanaged_flags & ~NM_UNMANAGED_DEFAULT); + if (managed && (priv->unmanaged_flags & NM_UNMANAGED_DEFAULT)) + managed = (priv->state != NM_DEVICE_STATE_UNMANAGED); + + return managed; } -static void -nm_device_set_managed_internal (NMDevice *device, - gboolean managed, - NMDeviceStateReason reason) +/** + * nm_device_get_default_unmanaged(): + * @device: the #NMDevice + * + * Returns: %TRUE if the device is by default unmanaged + */ +gboolean +nm_device_get_default_unmanaged (NMDevice *device) { - nm_log_dbg (LOGD_DEVICE, "(%s): now %s", - nm_device_get_iface (device), - managed ? "managed" : "unmanaged"); + return nm_device_get_unmanaged_flag (device, NM_UNMANAGED_DEFAULT); +} - g_object_notify (G_OBJECT (device), NM_DEVICE_MANAGED); - - if (managed) - nm_device_state_changed (device, NM_DEVICE_STATE_UNAVAILABLE, reason); - else - nm_device_state_changed (device, NM_DEVICE_STATE_UNMANAGED, reason); +/** + * nm_device_get_unmanaged_flag(): + * @device: the #NMDevice + * + * Returns: %TRUE if the device is unmanaged for @flag. + */ +gboolean +nm_device_get_unmanaged_flag (NMDevice *device, NMUnmanagedFlags flag) +{ + return NM_DEVICE_GET_PRIVATE (device)->unmanaged_flags & flag; } void -nm_device_set_manager_managed (NMDevice *device, - gboolean managed, - NMDeviceStateReason reason) +nm_device_set_unmanaged (NMDevice *device, + NMUnmanagedFlags flag, + gboolean unmanaged, + NMDeviceStateReason reason) { NMDevicePrivate *priv; gboolean was_managed, now_managed; g_return_if_fail (NM_IS_DEVICE (device)); + g_return_if_fail (flag <= NM_UNMANAGED_LAST); priv = NM_DEVICE_GET_PRIVATE (device); was_managed = nm_device_get_managed (device); - priv->manager_managed = managed; + if (unmanaged) + priv->unmanaged_flags |= flag; + else + priv->unmanaged_flags &= ~flag; now_managed = nm_device_get_managed (device); - if (was_managed != now_managed) - nm_device_set_managed_internal (device, now_managed, reason); + if (was_managed != now_managed) { + nm_log_dbg (LOGD_DEVICE, "(%s): now %s", + nm_device_get_iface (device), + unmanaged ? "unmanaged" : "managed"); + + g_object_notify (G_OBJECT (device), NM_DEVICE_MANAGED); + + if (unmanaged) + nm_device_state_changed (device, NM_DEVICE_STATE_UNMANAGED, reason); + else + nm_device_state_changed (device, NM_DEVICE_STATE_UNAVAILABLE, reason); + } } +/** + * nm_device_set_initial_unmanaged_flag(): + * @device: the #NMDevice + * @flag: an #NMUnmanagedFlag + * @unmanaged: %TRUE or %FALSE to set or clear @flag + * + * Like nm_device_set_unmanaged() but must be set before the device is exported + * and does not trigger state changes. Should only be used when initializing + * a device. + */ void -nm_device_set_default_unmanaged (NMDevice *device, - gboolean default_unmanaged) +nm_device_set_initial_unmanaged_flag (NMDevice *device, + NMUnmanagedFlags flag, + gboolean unmanaged) { NMDevicePrivate *priv; - gboolean was_managed, now_managed; g_return_if_fail (NM_IS_DEVICE (device)); + g_return_if_fail (flag <= NM_UNMANAGED_LAST); priv = NM_DEVICE_GET_PRIVATE (device); + g_return_if_fail (priv->path == NULL); - was_managed = nm_device_get_managed (device); - priv->default_unmanaged = default_unmanaged; - now_managed = nm_device_get_managed (device); - - if (was_managed != now_managed) - nm_device_set_managed_internal (device, now_managed, - default_unmanaged ? NM_DEVICE_STATE_REASON_NOW_UNMANAGED : - NM_DEVICE_STATE_REASON_NOW_MANAGED); + if (unmanaged) + priv->unmanaged_flags |= flag; + else + priv->unmanaged_flags &= ~flag; } /** @@ -7301,7 +7343,7 @@ nm_device_connection_is_available (NMDevice *device, NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); gboolean available = FALSE; - if (priv->default_unmanaged && (priv->state == NM_DEVICE_STATE_UNMANAGED)) { + if (nm_device_get_default_unmanaged (device) && (priv->state == NM_DEVICE_STATE_UNMANAGED)) { /* default-unmanaged devices in UNMANAGED state have no available connections * so we must manually check whether the connection is available here. */ diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 47d7856f34..6a6a4e165a 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -295,12 +295,33 @@ void nm_device_set_enabled (NMDevice *device, gboolean enabled); RfKillType nm_device_get_rfkill_type (NMDevice *device); +/** + * NMUnmanagedFlags: + * @NM_UNMANAGED_NONE: placeholder value + * @NM_UNMANAGED_DEFAULT: %TRUE when unmanaged by default (ie, Generic devices) + * @NM_UNMANAGED_INTERNAL: %TRUE when unmanaged by internal decision (ie, for + * devices in unmanaged specs or when NM is sleeping) + */ +typedef enum { + NM_UNMANAGED_NONE = 0x00, + NM_UNMANAGED_DEFAULT = 0x01, + NM_UNMANAGED_INTERNAL = 0x02, + + /* Boundary value */ + __NM_UNMANAGED_LAST, + NM_UNMANAGED_LAST = __NM_UNMANAGED_LAST - 1, +} NMUnmanagedFlags; + gboolean nm_device_get_managed (NMDevice *device); -void nm_device_set_manager_managed (NMDevice *device, - gboolean managed, - NMDeviceStateReason reason); -void nm_device_set_default_unmanaged (NMDevice *device, - gboolean default_unmanaged); +gboolean nm_device_get_default_unmanaged (NMDevice *device); +gboolean nm_device_get_unmanaged_flag (NMDevice *device, NMUnmanagedFlags flag); +void nm_device_set_unmanaged (NMDevice *device, + NMUnmanagedFlags flag, + gboolean unmanaged, + NMDeviceStateReason reason); +void nm_device_set_initial_unmanaged_flag (NMDevice *device, + NMUnmanagedFlags flag, + gboolean unmanaged); gboolean nm_device_get_is_nm_owned (NMDevice *device); gboolean nm_device_set_is_nm_owned (NMDevice *device, diff --git a/src/nm-manager.c b/src/nm-manager.c index 9300050ece..3857da6c3f 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -758,7 +758,7 @@ remove_device (NMManager *manager, NMDevice *device, gboolean quitting) NMActRequest *req = nm_device_get_act_request (device); if (!req || !nm_active_connection_get_assumed (NM_ACTIVE_CONNECTION (req))) - nm_device_set_manager_managed (device, FALSE, NM_DEVICE_STATE_REASON_REMOVED); + nm_device_set_unmanaged (device, NM_UNMANAGED_INTERNAL, TRUE, NM_DEVICE_STATE_REASON_REMOVED); } } @@ -1199,13 +1199,14 @@ system_unmanaged_devices_changed_cb (NMSettings *settings, unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings); for (iter = priv->devices; iter; iter = g_slist_next (iter)) { NMDevice *device = NM_DEVICE (iter->data); - gboolean managed; + gboolean unmanaged; - managed = !nm_device_spec_match_list (device, unmanaged_specs); - nm_device_set_manager_managed (device, - managed, - managed ? NM_DEVICE_STATE_REASON_NOW_MANAGED : - NM_DEVICE_STATE_REASON_NOW_UNMANAGED); + unmanaged = nm_device_spec_match_list (device, unmanaged_specs); + nm_device_set_unmanaged (device, + NM_UNMANAGED_INTERNAL, + unmanaged, + unmanaged ? NM_DEVICE_STATE_REASON_NOW_UNMANAGED : + NM_DEVICE_STATE_REASON_NOW_MANAGED); } } @@ -1751,7 +1752,7 @@ add_device (NMManager *self, NMDevice *device, gboolean generate_con) char *path; static guint32 devcount = 0; const GSList *unmanaged_specs; - gboolean unmanaged = FALSE; + gboolean user_unmanaged, sleeping; NMConnection *connection = NULL; gboolean enabled = FALSE; RfKillType rtype; @@ -1842,27 +1843,30 @@ add_device (NMManager *self, NMDevice *device, gboolean generate_con) nm_log_info (LOGD_HW, "(%s): new %s device (driver: '%s' ifindex: %d)", iface, type_desc, driver, nm_device_get_ifindex (device)); + unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings); + user_unmanaged = nm_device_spec_match_list (device, unmanaged_specs); + sleeping = manager_sleeping (self); + nm_device_set_initial_unmanaged_flag (device, NM_UNMANAGED_INTERNAL, sleeping || user_unmanaged); + path = g_strdup_printf ("/org/freedesktop/NetworkManager/Devices/%d", devcount++); nm_device_set_path (device, path); nm_dbus_manager_register_object (priv->dbus_mgr, path, device); nm_log_info (LOGD_CORE, "(%s): exported as %s", iface, path); g_free (path); - unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings); - unmanaged = nm_device_spec_match_list (device, unmanaged_specs); - /* Don't generate a connection e.g. for devices NM just created, or - * for the loopback */ - if (generate_con && !unmanaged) + * for the loopback, or when we're sleeping. */ + if (generate_con && !user_unmanaged && !sleeping) connection = get_existing_connection (self, device); - /* Start the device if it's supposed to be managed */ - if ( !manager_sleeping (self) - && !unmanaged) { - nm_device_set_manager_managed (device, - TRUE, - connection ? NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED : - NM_DEVICE_STATE_REASON_NOW_MANAGED); + /* Start the device if it's supposed to be managed. Note that this will + * manage default-unmanaged devices if they have a generated connection. + */ + if (nm_device_get_managed (device) || connection) { + nm_device_state_changed (device, + NM_DEVICE_STATE_UNAVAILABLE, + connection ? NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED : + NM_DEVICE_STATE_REASON_NOW_MANAGED); } nm_settings_device_added (priv->settings, device); @@ -3604,7 +3608,7 @@ do_sleep_wake (NMManager *self) NMDevice *device = iter->data; if (!nm_device_is_software (device)) - nm_device_set_manager_managed (device, FALSE, NM_DEVICE_STATE_REASON_SLEEPING); + nm_device_set_unmanaged (device, NM_UNMANAGED_INTERNAL, TRUE, NM_DEVICE_STATE_REASON_SLEEPING); } } else { nm_log_info (LOGD_SUSPEND, "waking up and re-enabling..."); @@ -3644,9 +3648,9 @@ do_sleep_wake (NMManager *self) g_object_set (G_OBJECT (device), NM_DEVICE_AUTOCONNECT, TRUE, NULL); if (nm_device_spec_match_list (device, unmanaged_specs)) - nm_device_set_manager_managed (device, FALSE, NM_DEVICE_STATE_REASON_NOW_UNMANAGED); + nm_device_set_unmanaged (device, NM_UNMANAGED_INTERNAL, TRUE, NM_DEVICE_STATE_REASON_NOW_UNMANAGED); else - nm_device_set_manager_managed (device, TRUE, NM_DEVICE_STATE_REASON_NOW_MANAGED); + nm_device_set_unmanaged (device, NM_UNMANAGED_INTERNAL, FALSE, NM_DEVICE_STATE_REASON_NOW_MANAGED); } } From de5c91ea0f3870a922acbda228ccc4e62041c4cd Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 1 Apr 2014 14:45:00 -0500 Subject: [PATCH 3/3] core: split user managed preference (unmanaged specs) out from internal management We'll want to track internal management separately in the future, so split out user management (eg, whether the device has been explicitly marked unmanaged by the user). --- src/devices/nm-device.h | 6 ++++-- src/nm-manager.c | 14 +++++--------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 6a6a4e165a..a253fd425c 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -299,13 +299,15 @@ RfKillType nm_device_get_rfkill_type (NMDevice *device); * NMUnmanagedFlags: * @NM_UNMANAGED_NONE: placeholder value * @NM_UNMANAGED_DEFAULT: %TRUE when unmanaged by default (ie, Generic devices) - * @NM_UNMANAGED_INTERNAL: %TRUE when unmanaged by internal decision (ie, for - * devices in unmanaged specs or when NM is sleeping) + * @NM_UNMANAGED_INTERNAL: %TRUE when unmanaged by internal decision (ie, + * because NM is sleeping or not managed for some other reason) + * @NM_UNMANAGED_USER: %TRUE when unmanaged by user decision (via unmanaged-specs) */ typedef enum { NM_UNMANAGED_NONE = 0x00, NM_UNMANAGED_DEFAULT = 0x01, NM_UNMANAGED_INTERNAL = 0x02, + NM_UNMANAGED_USER = 0x04, /* Boundary value */ __NM_UNMANAGED_LAST, diff --git a/src/nm-manager.c b/src/nm-manager.c index 3857da6c3f..ea0663f5be 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1203,7 +1203,7 @@ system_unmanaged_devices_changed_cb (NMSettings *settings, unmanaged = nm_device_spec_match_list (device, unmanaged_specs); nm_device_set_unmanaged (device, - NM_UNMANAGED_INTERNAL, + NM_UNMANAGED_USER, unmanaged, unmanaged ? NM_DEVICE_STATE_REASON_NOW_UNMANAGED : NM_DEVICE_STATE_REASON_NOW_MANAGED); @@ -1845,8 +1845,10 @@ add_device (NMManager *self, NMDevice *device, gboolean generate_con) unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings); user_unmanaged = nm_device_spec_match_list (device, unmanaged_specs); + nm_device_set_initial_unmanaged_flag (device, NM_UNMANAGED_USER, user_unmanaged); + sleeping = manager_sleeping (self); - nm_device_set_initial_unmanaged_flag (device, NM_UNMANAGED_INTERNAL, sleeping || user_unmanaged); + nm_device_set_initial_unmanaged_flag (device, NM_UNMANAGED_INTERNAL, sleeping); path = g_strdup_printf ("/org/freedesktop/NetworkManager/Devices/%d", devcount++); nm_device_set_path (device, path); @@ -3594,7 +3596,6 @@ static void do_sleep_wake (NMManager *self) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - const GSList *unmanaged_specs; GSList *iter; if (manager_sleeping (self)) { @@ -3613,8 +3614,6 @@ do_sleep_wake (NMManager *self) } else { nm_log_info (LOGD_SUSPEND, "waking up and re-enabling..."); - unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings); - /* Ensure rfkill state is up-to-date since we don't respond to state * changes during sleep. */ @@ -3647,10 +3646,7 @@ do_sleep_wake (NMManager *self) g_object_set (G_OBJECT (device), NM_DEVICE_AUTOCONNECT, TRUE, NULL); - if (nm_device_spec_match_list (device, unmanaged_specs)) - nm_device_set_unmanaged (device, NM_UNMANAGED_INTERNAL, TRUE, NM_DEVICE_STATE_REASON_NOW_UNMANAGED); - else - nm_device_set_unmanaged (device, NM_UNMANAGED_INTERNAL, FALSE, NM_DEVICE_STATE_REASON_NOW_MANAGED); + nm_device_set_unmanaged (device, NM_UNMANAGED_INTERNAL, FALSE, NM_DEVICE_STATE_REASON_NOW_MANAGED); } }