connectivity: merge branch 'th/fix-fake-connectivity-state'

https://github.com/NetworkManager/NetworkManager/pull/89
This commit is contained in:
Thomas Haller 2018-04-12 08:23:29 +02:00
commit 3b5a522ef6
4 changed files with 63 additions and 40 deletions

View File

@ -180,6 +180,7 @@ enum {
REMOVED,
RECHECK_AUTO_ACTIVATE,
RECHECK_ASSUME,
CONNECTIVITY_CHANGED,
LAST_SIGNAL,
};
static guint signals[LAST_SIGNAL] = { 0 };
@ -631,6 +632,8 @@ static void _set_mtu (NMDevice *self, guint32 mtu);
static void _commit_mtu (NMDevice *self, const NMIP4Config *config);
static void _cancel_activation (NMDevice *self);
static void concheck_update_state (NMDevice *self, NMConnectivityState state, gboolean is_periodic);
/*****************************************************************************/
NM_UTILS_LOOKUP_STR_DEFINE_STATIC (queued_state_to_string, NMDeviceState,
@ -2389,6 +2392,9 @@ nm_device_check_connectivity_update_interval (NMDevice *self)
if (!new_interval) {
/* this will cancel any potentially pending timeout. */
concheck_periodic_schedule_do (self, 0);
/* also update the fake connectivity state. */
concheck_update_state (self, NM_CONNECTIVITY_FAKE, TRUE);
return;
}
@ -2418,6 +2424,10 @@ concheck_update_state (NMDevice *self, NMConnectivityState state, gboolean is_pe
/* If the connectivity check is disabled and we obtain a fake
* result, make an optimistic guess. */
if (priv->state == NM_DEVICE_STATE_ACTIVATED) {
/* FIXME: the fake connectivity state depends on the availablility of
* a default route. However, we have no mechanism that rechecks the
* value if a device route appears/disappears after the device
* was activated. */
if (nm_device_get_best_default_route (self, AF_UNSPEC))
state = NM_CONNECTIVITY_FULL;
else
@ -2457,6 +2467,7 @@ concheck_update_state (NMDevice *self, NMConnectivityState state, gboolean is_pe
priv->connectivity_state = state;
_notify (self, PROP_CONNECTIVITY);
g_signal_emit (self, signals[CONNECTIVITY_CHANGED], 0);
if ( priv->state == NM_DEVICE_STATE_ACTIVATED
&& !nm_device_sys_iface_state_is_external (self)) {
@ -2499,7 +2510,8 @@ concheck_cb (NMConnectivity *connectivity,
GError *error,
gpointer user_data)
{
gs_unref_object NMDevice *self = NULL;
_nm_unused gs_unref_object NMDevice *self_keep_alive = NULL;
NMDevice *self;
NMDevicePrivate *priv;
NMDeviceConnectivityHandle *handle;
NMDeviceConnectivityHandle *other_handle;
@ -2511,20 +2523,24 @@ concheck_cb (NMConnectivity *connectivity,
nm_assert (NM_IS_DEVICE (handle->self));
handle->c_handle = NULL;
self = g_object_ref (handle->self);
_LOGT (LOGD_CONCHECK, "connectivity: complete check (seq:%llu, state:%s%s%s%s)",
(long long unsigned) handle->seq,
nm_connectivity_state_to_string (state),
NM_PRINT_FMT_QUOTED (error, ", error: ", error->message, "", ""));
self = handle->self;
if (nm_utils_error_is_cancelled (error, FALSE)) {
/* the only place where we nm_connectivity_check_cancel(@c_handle), is
* from inside concheck_handle_event(). This is a recursive call,
* nothing to do. */
_LOGT (LOGD_CONCHECK, "connectivity: complete check (seq:%llu, obsoleted by later request returning)",
(long long unsigned) handle->seq);
return;
}
self_keep_alive = g_object_ref (self);
_LOGT (LOGD_CONCHECK, "connectivity: complete check (seq:%llu, state:%s%s%s%s)",
(long long unsigned) handle->seq,
nm_connectivity_state_to_string (state),
NM_PRINT_FMT_QUOTED (error, ", error: ", error->message, "", ""));
/* we keep NMConnectivity instance alive. It cannot be disposing. */
nm_assert (!nm_utils_error_is_cancelled (error, TRUE));
@ -15739,4 +15755,12 @@ nm_device_class_init (NMDeviceClass *klass)
G_SIGNAL_RUN_FIRST,
0, NULL, NULL, NULL,
G_TYPE_NONE, 0);
signals[CONNECTIVITY_CHANGED] =
g_signal_new (NM_DEVICE_CONNECTIVITY_CHANGED,
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
0, NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}

View File

@ -135,6 +135,7 @@ nm_device_state_reason_check (NMDeviceStateReason reason)
#define NM_DEVICE_STATE_CHANGED "state-changed"
#define NM_DEVICE_LINK_INITIALIZED "link-initialized"
#define NM_DEVICE_AUTOCONNECT_ALLOWED "autoconnect-allowed"
#define NM_DEVICE_CONNECTIVITY_CHANGED "connectivity-changed"
#define NM_DEVICE_STATISTICS_REFRESH_RATE_MS "refresh-rate-ms"
#define NM_DEVICE_STATISTICS_TX_BYTES "tx-bytes"

View File

@ -631,9 +631,7 @@ _dispatcher_call (NMDispatcherAction action,
if (!device_dhcp6_props)
device_dhcp6_props = g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0));
#if WITH_CONCHECK
connectivity_state_string = nm_connectivity_state_to_string (connectivity_state);
#endif
/* Send the action to the dispatcher */
if (blocking) {

View File

@ -1142,26 +1142,6 @@ _nm_state_to_string (NMState state)
}
}
static void
set_state (NMManager *self, NMState state)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
if (priv->state == state)
return;
priv->state = state;
_LOGI (LOGD_CORE, "NetworkManager state is now %s", _nm_state_to_string (state));
_notify (self, PROP_STATE);
nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self),
&interface_info_manager,
&signal_info_state_changed,
"(u)",
(guint32) priv->state);
}
static NMState
find_best_device_state (NMManager *manager)
{
@ -1232,26 +1212,38 @@ nm_manager_update_metered (NMManager *self)
}
static void
nm_manager_update_state (NMManager *manager)
nm_manager_update_state (NMManager *self)
{
NMManagerPrivate *priv;
NMState new_state = NM_STATE_DISCONNECTED;
g_return_if_fail (NM_IS_MANAGER (manager));
g_return_if_fail (NM_IS_MANAGER (self));
priv = NM_MANAGER_GET_PRIVATE (manager);
priv = NM_MANAGER_GET_PRIVATE (self);
if (manager_sleeping (manager))
if (manager_sleeping (self))
new_state = NM_STATE_ASLEEP;
else
new_state = find_best_device_state (manager);
new_state = find_best_device_state (self);
if ( new_state >= NM_STATE_CONNECTED_LOCAL
&& priv->connectivity_state == NM_CONNECTIVITY_FULL) {
new_state = NM_STATE_CONNECTED_GLOBAL;
}
set_state (manager, new_state);
if (priv->state == new_state)
return;
priv->state = new_state;
_LOGI (LOGD_CORE, "NetworkManager state is now %s", _nm_state_to_string (new_state));
_notify (self, PROP_STATE);
nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self),
&interface_info_manager,
&signal_info_state_changed,
"(u)",
(guint32) priv->state);
}
static void
@ -2512,7 +2504,6 @@ device_realized (NMDevice *device,
static void
device_connectivity_changed (NMDevice *device,
GParamSpec *pspec,
NMManager *self)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
@ -2520,11 +2511,20 @@ device_connectivity_changed (NMDevice *device,
NMConnectivityState state;
NMDevice *dev;
c_list_for_each_entry (dev, &priv->devices_lst_head, devices_lst) {
state = nm_device_get_connectivity_state (dev);
if (state > best_state)
best_state = nm_device_get_connectivity_state (device);
if (best_state < NM_CONNECTIVITY_FULL) {
c_list_for_each_entry (dev, &priv->devices_lst_head, devices_lst) {
state = nm_device_get_connectivity_state (dev);
if (state <= best_state)
continue;
best_state = state;
if (best_state >= NM_CONNECTIVITY_FULL) {
/* it doesn't get better than this. */
break;
}
}
}
nm_assert (best_state <= NM_CONNECTIVITY_FULL);
if (best_state != priv->connectivity_state) {
priv->connectivity_state = best_state;
@ -2646,7 +2646,7 @@ add_device (NMManager *self, NMDevice *device, GError **error)
G_CALLBACK (device_realized),
self);
g_signal_connect (device, "notify::" NM_DEVICE_CONNECTIVITY,
g_signal_connect (device, NM_DEVICE_CONNECTIVITY_CHANGED,
G_CALLBACK (device_connectivity_changed),
self);