From dfef19880134b040bb108b3bcf66e9e88fa8050e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 21 Jan 2013 18:16:32 -0600 Subject: [PATCH] bond: device availability shouldn't depend on carrier state Bond master carrier state follows slave carriers, so clearly we can't depend on carrier when deciding whether we can activate a bond connection which doesn't yet have any slaves. Also, when the bond's carrier goes down, we don't want to deactivate the connection because this is normal in some failover modes and could be the user reconfiguring slaves. --- src/nm-device-bond.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/nm-device-bond.c b/src/nm-device-bond.c index c6bd2b386f..4ae898d7d7 100644 --- a/src/nm-device-bond.c +++ b/src/nm-device-bond.c @@ -90,17 +90,29 @@ device_state_changed (NMDevice *device, { NMDeviceBondPrivate *priv = NM_DEVICE_BOND_GET_PRIVATE (device); - if (new_state == NM_DEVICE_STATE_UNAVAILABLE) { - /* Use NM_DEVICE_STATE_REASON_CARRIER to make sure num retries is reset */ - nm_device_queue_state (device, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_CARRIER); - } - if (new_state <= NM_DEVICE_STATE_DISCONNECTED || new_state > NM_DEVICE_STATE_ACTIVATED) { priv->ip4_waiting = FALSE; priv->ip6_waiting = FALSE; } } +static void +carrier_action (NMDeviceWired *self, NMDeviceState state, gboolean carrier) +{ + /* Carrier can't be used to signal availability of the bond master because + * the bond's carrier follows the slaves' carriers. So carrier gets + * ignored when determining whether or not the device can be activated. + * + * Second, just because all slaves have been removed or have lost carrier + * does not mean the master should be deactivated. This could be due to + * user addition/removal of slaves, and is also normal operation with some + * failover modes. + * + * For these reasons, carrier changes are effectively ignored by overriding + * the parent class' carrier handling and doing nothing. + */ +} + static void update_hw_address (NMDevice *dev) { @@ -129,6 +141,14 @@ get_generic_capabilities (NMDevice *dev) return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_NM_SUPPORTED; } +static gboolean +is_available (NMDevice *dev) +{ + if (NM_DEVICE_GET_CLASS (dev)->hw_is_up) + return NM_DEVICE_GET_CLASS (dev)->hw_is_up (dev); + return FALSE; +} + static gboolean match_bond_connection (NMDevice *device, NMConnection *connection, GError **error) { @@ -562,6 +582,7 @@ nm_device_bond_class_init (NMDeviceBondClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); + NMDeviceWiredClass *wired_class = NM_DEVICE_WIRED_CLASS (klass); g_type_class_add_private (object_class, sizeof (NMDeviceBondPrivate)); @@ -573,6 +594,7 @@ nm_device_bond_class_init (NMDeviceBondClass *klass) parent_class->get_generic_capabilities = get_generic_capabilities; parent_class->update_hw_address = update_hw_address; parent_class->get_hw_address = get_hw_address; + parent_class->is_available = is_available; parent_class->get_best_auto_connection = get_best_auto_connection; parent_class->check_connection_compatible = check_connection_compatible; parent_class->complete_connection = complete_connection; @@ -588,6 +610,8 @@ nm_device_bond_class_init (NMDeviceBondClass *klass) parent_class->state_changed = device_state_changed; + wired_class->carrier_action = carrier_action; + /* properties */ g_object_class_install_property (object_class, PROP_HW_ADDRESS,