diff options
Diffstat (limited to 'src/devices/nm-device.c')
| -rw-r--r-- | src/devices/nm-device.c | 375 |
1 files changed, 189 insertions, 186 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 1fcf965c..2a2d276d 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -73,9 +73,64 @@ _LOG_DECLARE_SELF (NMDevice); #include "introspection/org.freedesktop.NetworkManager.Device.h" #include "introspection/org.freedesktop.NetworkManager.Device.Statistics.h" -G_DEFINE_ABSTRACT_TYPE (NMDevice, nm_device, NM_TYPE_EXPORTED_OBJECT) +/*****************************************************************************/ -#define NM_DEVICE_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMDevice, NM_IS_DEVICE) +#define DHCP_RESTART_TIMEOUT 120 +#define DHCP_NUM_TRIES_MAX 3 +#define DEFAULT_AUTOCONNECT TRUE + +/*****************************************************************************/ + +typedef void (*ActivationHandleFunc) (NMDevice *self); + +typedef struct { + ActivationHandleFunc func; + guint id; +} ActivationHandleData; + +typedef enum { + CLEANUP_TYPE_KEEP, + CLEANUP_TYPE_REMOVED, + CLEANUP_TYPE_DECONFIGURE, +} CleanupType; + +typedef enum { + IP_NONE = 0, + IP_WAIT, + IP_CONF, + IP_DONE, + IP_FAIL +} IpState; + +typedef struct { + NMDevice *slave; + gulong watch_id; + bool slave_is_enslaved; + bool configure; +} SlaveInfo; + +typedef struct { + NMDevice *device; + guint idle_add_id; + int ifindex; +} DeleteOnDeactivateData; + +typedef void (*ArpingCallback) (NMDevice *, NMIP4Config **, gboolean); + +typedef struct { + ArpingCallback callback; + NMDevice *device; + NMIP4Config **configs; +} ArpingData; + +typedef enum { + HW_ADDR_TYPE_UNSET = 0, + HW_ADDR_TYPE_PERMANENT, + HW_ADDR_TYPE_EXPLICIT, + HW_ADDR_TYPE_GENERATED, +} HwAddrType; + +/*****************************************************************************/ enum { STATE_CHANGED, @@ -136,82 +191,6 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDevice, PROP_RX_BYTES, ); -#define DEFAULT_AUTOCONNECT TRUE - -/*****************************************************************************/ - -#define PENDING_ACTION_DHCP4 "dhcp4" -#define PENDING_ACTION_DHCP6 "dhcp6" -#define PENDING_ACTION_AUTOCONF6 "autoconf6" - -#define DHCP_RESTART_TIMEOUT 120 -#define DHCP_NUM_TRIES_MAX 3 - -typedef void (*ActivationHandleFunc) (NMDevice *self); - -typedef struct { - ActivationHandleFunc func; - guint id; -} ActivationHandleData; - -typedef enum { - CLEANUP_TYPE_KEEP, - CLEANUP_TYPE_REMOVED, - CLEANUP_TYPE_DECONFIGURE, -} CleanupType; - -typedef enum { - IP_NONE = 0, - IP_WAIT, - IP_CONF, - IP_DONE, - IP_FAIL -} IpState; - -typedef struct { - NMDeviceState state; - NMDeviceStateReason reason; - guint id; -} QueuedState; - -typedef struct { - NMDevice *slave; - gulong watch_id; - bool slave_is_enslaved; - bool configure; -} SlaveInfo; - -typedef struct { - NMLogDomain log_domain; - guint timeout; - guint watch; - GPid pid; - const char *binary; - const char *address; - guint deadline; -} PingInfo; - -typedef struct { - NMDevice *device; - guint idle_add_id; - int ifindex; -} DeleteOnDeactivateData; - -typedef void (*ArpingCallback) (NMDevice *, NMIP4Config **, gboolean); - -typedef struct { - ArpingCallback callback; - NMDevice *device; - NMIP4Config **configs; -} ArpingData; - -typedef enum { - HW_ADDR_TYPE_UNSET = 0, - HW_ADDR_TYPE_PERMANENT, - HW_ADDR_TYPE_EXPLICIT, - HW_ADDR_TYPE_GENERATED, -} HwAddrType; - typedef struct _NMDevicePrivate { bool in_state_changed; @@ -220,7 +199,13 @@ typedef struct _NMDevicePrivate { NMDeviceState state; NMDeviceStateReason state_reason; - QueuedState queued_state; + struct { + guint id; + + /* The @state/@reason is only valid, when @id is set. */ + NMDeviceState state; + NMDeviceStateReason reason; + } queued_state; guint queued_ip4_config_id; guint queued_ip6_config_id; GSList *pending_actions; @@ -238,7 +223,8 @@ typedef struct _NMDevicePrivate { const guint8 hw_addr_len; /* read-only */ guint8 hw_addr_len_; }; - guint8 /*HwAddrType*/ hw_addr_type; + + HwAddrType hw_addr_type:5; bool real:1; @@ -358,7 +344,15 @@ typedef struct _NMDevicePrivate { guint num_tries_left; } dhcp4; - PingInfo gw_ping; + struct { + NMLogDomain log_domain; + guint timeout; + guint watch; + GPid pid; + const char *binary; + const char *address; + guint deadline; + } gw_ping; /* dnsmasq stuff for shared connections */ NMDnsMasqManager *dnsmasq_manager; @@ -451,6 +445,12 @@ typedef struct _NMDevicePrivate { } NMDevicePrivate; +G_DEFINE_ABSTRACT_TYPE (NMDevice, nm_device, NM_TYPE_EXPORTED_OBJECT) + +#define NM_DEVICE_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMDevice, NM_IS_DEVICE) + +/*****************************************************************************/ + static void nm_device_set_proxy_config (NMDevice *self, GHashTable *options); static gboolean nm_device_set_ip4_config (NMDevice *self, @@ -489,7 +489,7 @@ static void _set_state_full (NMDevice *self, NMDeviceState state, NMDeviceStateReason reason, gboolean quitting); - +static void queued_state_clear (NMDevice *device); static gboolean queued_ip4_config_change (gpointer user_data); static gboolean queued_ip6_config_change (gpointer user_data); static void ip_check_ping_watch_cb (GPid pid, gint status, gpointer user_data); @@ -504,36 +504,27 @@ static void _cancel_activation (NMDevice *self); /*****************************************************************************/ -#define QUEUED_PREFIX "queued state change to " - -static const char *state_table[] = { - [NM_DEVICE_STATE_UNKNOWN] = QUEUED_PREFIX "unknown", - [NM_DEVICE_STATE_UNMANAGED] = QUEUED_PREFIX "unmanaged", - [NM_DEVICE_STATE_UNAVAILABLE] = QUEUED_PREFIX "unavailable", - [NM_DEVICE_STATE_DISCONNECTED] = QUEUED_PREFIX "disconnected", - [NM_DEVICE_STATE_PREPARE] = QUEUED_PREFIX "prepare", - [NM_DEVICE_STATE_CONFIG] = QUEUED_PREFIX "config", - [NM_DEVICE_STATE_NEED_AUTH] = QUEUED_PREFIX "need-auth", - [NM_DEVICE_STATE_IP_CONFIG] = QUEUED_PREFIX "ip-config", - [NM_DEVICE_STATE_IP_CHECK] = QUEUED_PREFIX "ip-check", - [NM_DEVICE_STATE_SECONDARIES] = QUEUED_PREFIX "secondaries", - [NM_DEVICE_STATE_ACTIVATED] = QUEUED_PREFIX "activated", - [NM_DEVICE_STATE_DEACTIVATING] = QUEUED_PREFIX "deactivating", - [NM_DEVICE_STATE_FAILED] = QUEUED_PREFIX "failed", -}; - -static const char * -queued_state_to_string (NMDeviceState state) -{ - if ((gsize) state < G_N_ELEMENTS (state_table)) - return state_table[state]; - return state_table[NM_DEVICE_STATE_UNKNOWN]; -} +NM_UTILS_LOOKUP_STR_DEFINE_STATIC (queued_state_to_string, NMDeviceState, + NM_UTILS_LOOKUP_DEFAULT ( NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "???"), + NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_UNKNOWN, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "unknown"), + NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_UNMANAGED, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "unmanaged"), + NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_UNAVAILABLE, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "unavailable"), + NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_DISCONNECTED, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "disconnected"), + NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_PREPARE, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "prepare"), + NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_CONFIG, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "config"), + NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_NEED_AUTH, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "need-auth"), + NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_IP_CONFIG, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "ip-config"), + NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_IP_CHECK, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "ip-check"), + NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_SECONDARIES, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "secondaries"), + NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_ACTIVATED, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "activated"), + NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_DEACTIVATING, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "deactivating"), + NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_FAILED, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "failed"), +); static const char * state_to_string (NMDeviceState state) { - return queued_state_to_string (state) + strlen (QUEUED_PREFIX); + return queued_state_to_string (state) + NM_STRLEN (NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE); } NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_reason_to_string, NMDeviceStateReason, @@ -1932,8 +1923,9 @@ carrier_changed (NMDevice *self, gboolean carrier) } } else { if (priv->state == NM_DEVICE_STATE_UNAVAILABLE) { - if (nm_device_queued_state_peek (self) >= NM_DEVICE_STATE_DISCONNECTED) - nm_device_queued_state_clear (self); + if ( priv->queued_state.id + && priv->queued_state.state >= NM_DEVICE_STATE_DISCONNECTED) + queued_state_clear (self); } else { nm_device_queue_state (self, NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_CARRIER); @@ -1989,7 +1981,7 @@ nm_device_set_carrier (NMDevice *self, gboolean carrier) klass->carrier_changed (self, TRUE); if (nm_clear_g_source (&priv->carrier_wait_id)) { - nm_device_remove_pending_action (self, "carrier wait", TRUE); + nm_device_remove_pending_action (self, NM_PENDING_ACTION_CARRIER_WAIT, TRUE); _carrier_wait_check_queued_act_request (self); } } else if ( state <= NM_DEVICE_STATE_DISCONNECTED @@ -3921,6 +3913,9 @@ recheck_available (gpointer user_data) priv->recheck_available.unavailable_reason = NM_DEVICE_STATE_REASON_NONE; } + if (priv->recheck_available.call_id == 0) + nm_device_remove_pending_action (self, NM_PENDING_ACTION_RECHECK_AVAILABLE, TRUE); + return G_SOURCE_REMOVE; } @@ -3933,8 +3928,12 @@ nm_device_queue_recheck_available (NMDevice *self, priv->recheck_available.available_reason = available_reason; priv->recheck_available.unavailable_reason = unavailable_reason; - if (!priv->recheck_available.call_id) + if (!priv->recheck_available.call_id) { priv->recheck_available.call_id = g_idle_add (recheck_available, self); + nm_device_add_pending_action (self, NM_PENDING_ACTION_RECHECK_AVAILABLE, + FALSE /* cannot assert, because of how recheck_available() first clears + the call-id and postpones removing the pending-action. */); + } } void @@ -4971,7 +4970,7 @@ dhcp4_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release) /* Stop any ongoing DHCP transaction on this device */ nm_clear_g_signal_handler (priv->dhcp4.client, &priv->dhcp4.state_sigid); - nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE); + nm_device_remove_pending_action (self, NM_PENDING_ACTION_DHCP4, FALSE); if ( cleanup_type == CLEANUP_TYPE_DECONFIGURE || cleanup_type == CLEANUP_TYPE_REMOVED) @@ -5199,7 +5198,7 @@ dhcp4_lease_change (NMDevice *self, NMIP4Config *config) NULL, NULL); - nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE); + nm_device_remove_pending_action (self, NM_PENDING_ACTION_DHCP4, FALSE); return TRUE; } @@ -5340,7 +5339,7 @@ dhcp4_state_changed (NMDhcpClient *client, /* Ignore expiry before we even have a lease (NAK, old lease, etc) */ if (priv->ip4_state == IP_CONF) break; - /* Fall through */ + /* fall through */ case NM_DHCP_STATE_DONE: case NM_DHCP_STATE_FAIL: dhcp4_fail (self, FALSE); @@ -5424,7 +5423,7 @@ dhcp4_start (NMDevice *self, G_CALLBACK (dhcp4_state_changed), self); - nm_device_add_pending_action (self, PENDING_ACTION_DHCP4, TRUE); + nm_device_add_pending_action (self, NM_PENDING_ACTION_DHCP4, TRUE); /* DHCP devices will be notified by the DHCP manager when stuff happens */ return NM_ACT_STAGE_RETURN_POSTPONE; @@ -5726,7 +5725,7 @@ dhcp6_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release) g_clear_object (&priv->dhcp6.client); } - nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE); + nm_device_remove_pending_action (self, NM_PENDING_ACTION_DHCP6, FALSE); if (priv->dhcp6.config) { nm_exported_object_clear_and_unexport (&priv->dhcp6.config); @@ -5970,7 +5969,7 @@ dhcp6_lease_change (NMDevice *self) nm_device_get_applied_connection (self), self, NULL, NULL, NULL); - nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE); + nm_device_remove_pending_action (self, NM_PENDING_ACTION_DHCP6, FALSE); return TRUE; } @@ -6159,7 +6158,7 @@ dhcp6_state_changed (NMDhcpClient *client, */ if (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_OTHERCONF) break; - /* Otherwise, fall through */ + /* fall through */ case NM_DHCP_STATE_FAIL: dhcp6_fail (self, FALSE); break; @@ -6256,7 +6255,7 @@ dhcp6_start (NMDevice *self, gboolean wait_for_ll, NMDeviceStateReason *reason) s_ip6 = nm_connection_get_setting_ip6_config (connection); if (!nm_setting_ip_config_get_may_fail (s_ip6) || !strcmp (nm_setting_ip_config_get_method (s_ip6), NM_SETTING_IP6_CONFIG_METHOD_DHCP)) - nm_device_add_pending_action (self, PENDING_ACTION_DHCP6, TRUE); + nm_device_add_pending_action (self, NM_PENDING_ACTION_DHCP6, TRUE); if (wait_for_ll) { NMActStageReturn ret; @@ -7031,7 +7030,7 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) } if (!nm_setting_ip_config_get_may_fail (nm_connection_get_setting_ip6_config (connection))) - nm_device_add_pending_action (self, PENDING_ACTION_AUTOCONF6, TRUE); + nm_device_add_pending_action (self, NM_PENDING_ACTION_AUTOCONF6, TRUE); /* ensure link local is ready... */ ret = linklocal6_start (self); @@ -7053,7 +7052,7 @@ addrconf6_cleanup (NMDevice *self) nm_clear_g_signal_handler (priv->ndisc, &priv->ndisc_changed_id); nm_clear_g_signal_handler (priv->ndisc, &priv->ndisc_timeout_id); - nm_device_remove_pending_action (self, PENDING_ACTION_AUTOCONF6, FALSE); + nm_device_remove_pending_action (self, NM_PENDING_ACTION_AUTOCONF6, FALSE); g_clear_object (&priv->ac_ip6_config); g_clear_object (&priv->ndisc); @@ -7921,7 +7920,7 @@ activate_stage5_ip4_config_commit (NMDevice *self) arp_announce (self); - nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE); + nm_device_remove_pending_action (self, NM_PENDING_ACTION_DHCP4, FALSE); /* Enter the IP_CHECK state if this is the first method to complete */ _set_ip_state (self, AF_INET, IP_DONE); @@ -8058,8 +8057,8 @@ activate_stage5_ip6_config_commit (NMDevice *self) return; } } - nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE); - nm_device_remove_pending_action (self, PENDING_ACTION_AUTOCONF6, FALSE); + nm_device_remove_pending_action (self, NM_PENDING_ACTION_DHCP6, FALSE); + nm_device_remove_pending_action (self, NM_PENDING_ACTION_AUTOCONF6, FALSE); /* Start IPv6 forwarding if we need it */ method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); @@ -9745,7 +9744,7 @@ carrier_wait_timeout (gpointer user_data) NMDevice *self = NM_DEVICE (user_data); NM_DEVICE_GET_PRIVATE (self)->carrier_wait_id = 0; - nm_device_remove_pending_action (self, "carrier wait", TRUE); + nm_device_remove_pending_action (self, NM_PENDING_ACTION_CARRIER_WAIT, TRUE); _carrier_wait_check_queued_act_request (self); @@ -9827,7 +9826,7 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware) */ if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) { if (!nm_clear_g_source (&priv->carrier_wait_id)) - nm_device_add_pending_action (self, "carrier wait", TRUE); + nm_device_add_pending_action (self, NM_PENDING_ACTION_CARRIER_WAIT, TRUE); priv->carrier_wait_id = g_timeout_add_seconds (5, carrier_wait_timeout, self); } @@ -10336,7 +10335,7 @@ device_ipx_changed (NMPlatform *platform, priv->dad6_failed_addrs = g_slist_append (priv->dad6_failed_addrs, g_memdup (addr, sizeof (NMPlatformIP6Address))); } - /* fallthrough */ + /* fall through */ case NMP_OBJECT_TYPE_IP6_ROUTE: if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) { priv->queued_ip6_config_pending = TRUE; @@ -11241,7 +11240,9 @@ nm_device_supports_vlans (NMDevice *self) /** * nm_device_add_pending_action(): * @self: the #NMDevice to add the pending action to - * @action: a static string that identifies the action + * @action: a static string that identifies the action. The string instance must + * stay valid until the pending action is removed (that is, the string is + * not cloned, but ownership stays with the caller). * @assert_not_yet_pending: if %TRUE, assert that the @action is currently not yet pending. * Otherwise, ignore duplicate scheduling of the same action silently. * @@ -11276,7 +11277,7 @@ nm_device_add_pending_action (NMDevice *self, const char *action, gboolean asser count++; } - priv->pending_actions = g_slist_append (priv->pending_actions, g_strdup (action)); + priv->pending_actions = g_slist_prepend (priv->pending_actions, (char *) action); count++; _LOGD (LOGD_DEVICE, "add_pending_action (%d): '%s'", count, action); @@ -11290,7 +11291,7 @@ nm_device_add_pending_action (NMDevice *self, const char *action, gboolean asser /** * nm_device_remove_pending_action(): * @self: the #NMDevice to remove the pending action from - * @action: a static string that identifies the action + * @action: a string that identifies the action. * @assert_is_pending: if %TRUE, assert that the @action is pending. * If %FALSE, don't do anything if the current action is not pending and * return %FALSE. @@ -11317,7 +11318,6 @@ nm_device_remove_pending_action (NMDevice *self, const char *action, gboolean as _LOGD (LOGD_DEVICE, "remove_pending_action (%d): '%s'", count + g_slist_length (iter->next), /* length excluding 'iter' */ action); - g_free (iter->data); priv->pending_actions = g_slist_delete_link (priv->pending_actions, iter); if (priv->pending_actions == NULL) _notify (self, PROP_HAS_PENDING_ACTION); @@ -11383,8 +11383,7 @@ _cleanup_generic_pre (NMDevice *self, CleanupType cleanup_type) NULL); } - /* Clear any queued transitions */ - nm_device_queued_state_clear (self); + queued_state_clear (self); _cleanup_ip4_pre (self, cleanup_type); _cleanup_ip6_pre (self, cleanup_type); @@ -11889,8 +11888,7 @@ _set_state_full (NMDevice *self, priv->state = state; priv->state_reason = reason; - /* Clear any queued transitions */ - nm_device_queued_state_clear (self); + queued_state_clear (self); dispatcher_cleanup (self); if (priv->deactivating_cancellable) @@ -12202,33 +12200,32 @@ nm_device_state_changed (NMDevice *self, } static gboolean -queued_set_state (gpointer user_data) +queued_state_set (gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMDeviceState new_state; NMDeviceStateReason new_reason; - if (priv->queued_state.id) { - _LOGD (LOGD_DEVICE, "running queued state change to %s (id %d)", - state_to_string (priv->queued_state.state), - priv->queued_state.id); + nm_assert (priv->queued_state.id); - /* Clear queued state struct before triggering state change, since - * the state change may queue another state. - */ - priv->queued_state.id = 0; - new_state = priv->queued_state.state; - new_reason = priv->queued_state.reason; - nm_device_queued_state_clear (self); + _LOGD (LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s", + state_to_string (priv->queued_state.state), + reason_to_string (priv->queued_state.reason), + priv->queued_state.id, + "change state"); - nm_device_state_changed (self, new_state, new_reason); - nm_device_remove_pending_action (self, queued_state_to_string (new_state), TRUE); - } else { - g_warn_if_fail (priv->queued_state.state == NM_DEVICE_STATE_UNKNOWN); - g_warn_if_fail (priv->queued_state.reason == NM_DEVICE_STATE_REASON_NONE); - } - return FALSE; + /* Clear queued state struct before triggering state change, since + * the state change may queue another state. + */ + priv->queued_state.id = 0; + new_state = priv->queued_state.state; + new_reason = priv->queued_state.reason; + + nm_device_state_changed (self, new_state, new_reason); + nm_device_remove_pending_action (self, queued_state_to_string (new_state), TRUE); + + return G_SOURCE_REMOVE; } void @@ -12242,8 +12239,16 @@ nm_device_queue_state (NMDevice *self, priv = NM_DEVICE_GET_PRIVATE (self); - if (priv->queued_state.id && priv->queued_state.state == state) + if (priv->queued_state.id && priv->queued_state.state == state) { + _LOGD (LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s%s%s%s", + state_to_string (priv->queued_state.state), + reason_to_string (priv->queued_state.reason), + priv->queued_state.id, + "ignore queuing same state change", + NM_PRINT_FMT_QUOTED (priv->queued_state.reason != reason, + " (reason differs: ", reason_to_string (reason), ")", "")); return; + } /* Add pending action for the new state before clearing the queued states, so * that we don't accidently pop all pending states and reach 'startup complete' */ @@ -12251,45 +12256,41 @@ nm_device_queue_state (NMDevice *self, /* We should only ever have one delayed state transition at a time */ if (priv->queued_state.id) { - _LOGW (LOGD_DEVICE, "overwriting previously queued state change to %s (%s)", + _LOGW (LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s", state_to_string (priv->queued_state.state), - reason_to_string (priv->queued_state.reason)); - nm_device_queued_state_clear (self); + reason_to_string (priv->queued_state.reason), + priv->queued_state.id, + "replace previously queued state change"); + nm_clear_g_source (&priv->queued_state.id); + nm_device_remove_pending_action (self, queued_state_to_string (priv->queued_state.state), TRUE); } priv->queued_state.state = state; priv->queued_state.reason = reason; - priv->queued_state.id = g_idle_add (queued_set_state, self); - - _LOGD (LOGD_DEVICE, "queued state change to %s due to %s (id %d)", - state_to_string (state), reason_to_string (reason), - priv->queued_state.id); -} - -NMDeviceState -nm_device_queued_state_peek (NMDevice *self) -{ - NMDevicePrivate *priv; - - g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_STATE_UNKNOWN); - - priv = NM_DEVICE_GET_PRIVATE (self); + priv->queued_state.id = g_idle_add (queued_state_set, self); - return priv->queued_state.id ? priv->queued_state.state : NM_DEVICE_STATE_UNKNOWN; + _LOGD (LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s", + state_to_string (state), + reason_to_string (reason), + priv->queued_state.id, + "queue state change"); } -void -nm_device_queued_state_clear (NMDevice *self) +static void +queued_state_clear (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - if (priv->queued_state.id) { - _LOGD (LOGD_DEVICE, "clearing queued state transition (id %d)", - priv->queued_state.id); - nm_clear_g_source (&priv->queued_state.id); - nm_device_remove_pending_action (self, queued_state_to_string (priv->queued_state.state), TRUE); - } - memset (&priv->queued_state, 0, sizeof (priv->queued_state)); + if (!priv->queued_state.id) + return; + + _LOGD (LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s", + state_to_string (priv->queued_state.state), + reason_to_string (priv->queued_state.reason), + priv->queued_state.id, + "clear queued state change"); + nm_clear_g_source (&priv->queued_state.id); + nm_device_remove_pending_action (self, queued_state_to_string (priv->queued_state.state), TRUE); } NMDeviceState @@ -12584,7 +12585,9 @@ nm_device_hw_addr_is_explict (NMDevice *self) g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); priv = NM_DEVICE_GET_PRIVATE (self); - return !NM_IN_SET (priv->hw_addr_type, HW_ADDR_TYPE_PERMANENT, HW_ADDR_TYPE_UNSET); + return !NM_IN_SET ((HwAddrType) priv->hw_addr_type, + HW_ADDR_TYPE_PERMANENT, + HW_ADDR_TYPE_UNSET); } static gboolean @@ -13143,7 +13146,7 @@ finalize (GObject *object) g_free (priv->hw_addr); g_free (priv->hw_addr_perm); g_free (priv->hw_addr_initial); - g_slist_free_full (priv->pending_actions, g_free); + g_slist_free (priv->pending_actions); g_slist_free_full (priv->dad6_failed_addrs, g_free); g_clear_pointer (&priv->physical_port_id, g_free); g_free (priv->udi); |