mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-09 02:28:18 +02:00
core: fix the reporting of failed slaves
If nm_device_enslave_slave() failed, the slave would log that it was waiting for the master to activate (even if the master was already active). Fix it to log an error and fail its activation instead.
This commit is contained in:
parent
a1f16cd4d9
commit
a4dcd66698
2 changed files with 75 additions and 58 deletions
|
|
@ -348,6 +348,10 @@ static void nm_device_queued_ip_config_change_clear (NMDevice *self);
|
||||||
static void update_ip_config (NMDevice *self);
|
static void update_ip_config (NMDevice *self);
|
||||||
static void device_ip_changed (NMPlatform *platform, int ifindex, gpointer platform_object, NMPlatformReason reason, gpointer user_data);
|
static void device_ip_changed (NMPlatform *platform, int ifindex, gpointer platform_object, NMPlatformReason reason, gpointer user_data);
|
||||||
|
|
||||||
|
static void nm_device_slave_notify_enslave (NMDevice *dev, gboolean success);
|
||||||
|
static void nm_device_slave_notify_release (NMDevice *dev, gboolean master_failed);
|
||||||
|
|
||||||
|
|
||||||
static const char const *platform_ip_signals[] = {
|
static const char const *platform_ip_signals[] = {
|
||||||
NM_PLATFORM_IP4_ADDRESS_ADDED,
|
NM_PLATFORM_IP4_ADDRESS_ADDED,
|
||||||
NM_PLATFORM_IP4_ADDRESS_CHANGED,
|
NM_PLATFORM_IP4_ADDRESS_CHANGED,
|
||||||
|
|
@ -945,10 +949,9 @@ nm_device_enslave_slave (NMDevice *dev, NMDevice *slave, NMConnection *connectio
|
||||||
|
|
||||||
g_warn_if_fail (info->enslaved == FALSE);
|
g_warn_if_fail (info->enslaved == FALSE);
|
||||||
success = NM_DEVICE_GET_CLASS (dev)->enslave_slave (dev, slave, connection);
|
success = NM_DEVICE_GET_CLASS (dev)->enslave_slave (dev, slave, connection);
|
||||||
if (success) {
|
|
||||||
info->enslaved = TRUE;
|
info->enslaved = success;
|
||||||
nm_device_slave_notify_enslaved (info->slave, TRUE, FALSE);
|
nm_device_slave_notify_enslave (info->slave, success);
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure the device's hardware address is up-to-date; it often changes
|
/* Ensure the device's hardware address is up-to-date; it often changes
|
||||||
* when slaves change.
|
* when slaves change.
|
||||||
|
|
@ -974,7 +977,7 @@ nm_device_enslave_slave (NMDevice *dev, NMDevice *slave, NMConnection *connectio
|
||||||
* nm_device_release_one_slave:
|
* nm_device_release_one_slave:
|
||||||
* @dev: the master device
|
* @dev: the master device
|
||||||
* @slave: the slave device to release
|
* @slave: the slave device to release
|
||||||
* @failed: %TRUE if the release was unexpected, ie the master failed
|
* @master_failed: %TRUE if the release was unexpected, ie the master failed
|
||||||
*
|
*
|
||||||
* If @dev is capable of enslaving other devices (ie it's a bridge, bond, team,
|
* If @dev is capable of enslaving other devices (ie it's a bridge, bond, team,
|
||||||
* etc) then this function releases the previously enslaved @slave.
|
* etc) then this function releases the previously enslaved @slave.
|
||||||
|
|
@ -983,7 +986,7 @@ nm_device_enslave_slave (NMDevice *dev, NMDevice *slave, NMConnection *connectio
|
||||||
* other devices, or if @slave was never enslaved.
|
* other devices, or if @slave was never enslaved.
|
||||||
*/
|
*/
|
||||||
static gboolean
|
static gboolean
|
||||||
nm_device_release_one_slave (NMDevice *dev, NMDevice *slave, gboolean failed)
|
nm_device_release_one_slave (NMDevice *dev, NMDevice *slave, gboolean master_failed)
|
||||||
{
|
{
|
||||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev);
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev);
|
||||||
SlaveInfo *info;
|
SlaveInfo *info;
|
||||||
|
|
@ -1000,7 +1003,7 @@ nm_device_release_one_slave (NMDevice *dev, NMDevice *slave, gboolean failed)
|
||||||
success = NM_DEVICE_GET_CLASS (dev)->release_slave (dev, slave);
|
success = NM_DEVICE_GET_CLASS (dev)->release_slave (dev, slave);
|
||||||
g_warn_if_fail (success);
|
g_warn_if_fail (success);
|
||||||
}
|
}
|
||||||
nm_device_slave_notify_enslaved (info->slave, FALSE, failed);
|
nm_device_slave_notify_release (info->slave, master_failed);
|
||||||
|
|
||||||
priv->slaves = g_slist_remove (priv->slaves, info);
|
priv->slaves = g_slist_remove (priv->slaves, info);
|
||||||
free_slave_info (info);
|
free_slave_info (info);
|
||||||
|
|
@ -1361,64 +1364,82 @@ nm_device_master_release_slaves (NMDevice *self, gboolean failed)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nm_device_slave_notify_enslaved:
|
* nm_device_slave_notify_enslave:
|
||||||
* @dev: the slave device
|
* @dev: the slave device
|
||||||
* @enslaved: %TRUE if the device is now enslaved, %FALSE if released
|
* @success: whether the enslaving operation succeeded
|
||||||
* @master_failed: if released, indicates whether the release was unexpected,
|
|
||||||
* ie the master device failed.
|
|
||||||
*
|
*
|
||||||
* Notifies a slave that it has been enslaved or released. If released, provides
|
* Notifies a slave that either it has been enslaved, or else its master tried
|
||||||
* information on whether the release was expected or not, and thus whether the
|
* to enslave it and failed.
|
||||||
* slave should fail it's activation or gracefully deactivate.
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
nm_device_slave_notify_enslaved (NMDevice *dev,
|
nm_device_slave_notify_enslave (NMDevice *dev, gboolean success)
|
||||||
gboolean enslaved,
|
|
||||||
gboolean master_failed)
|
|
||||||
{
|
{
|
||||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev);
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev);
|
||||||
NMConnection *connection = nm_device_get_connection (dev);
|
NMConnection *connection = nm_device_get_connection (dev);
|
||||||
|
|
||||||
if (enslaved) {
|
g_assert (priv->master);
|
||||||
g_assert (priv->master);
|
g_warn_if_fail (priv->enslaved == FALSE);
|
||||||
g_warn_if_fail (priv->enslaved == FALSE);
|
g_warn_if_fail (priv->state == NM_DEVICE_STATE_IP_CONFIG);
|
||||||
g_warn_if_fail (priv->state == NM_DEVICE_STATE_IP_CONFIG);
|
|
||||||
|
|
||||||
|
if (success) {
|
||||||
nm_log_info (LOGD_DEVICE,
|
nm_log_info (LOGD_DEVICE,
|
||||||
"Activation (%s) connection '%s' enslaved, continuing activation",
|
"Activation (%s) connection '%s' enslaved, continuing activation",
|
||||||
nm_device_get_iface (dev),
|
nm_device_get_iface (dev),
|
||||||
nm_connection_get_id (connection));
|
nm_connection_get_id (connection));
|
||||||
|
|
||||||
/* Now that we're enslaved, proceed with activation. Remember, slaves
|
|
||||||
* don't have any IP configuration, so they skip directly to SECONDARIES.
|
|
||||||
*/
|
|
||||||
priv->enslaved = TRUE;
|
priv->enslaved = TRUE;
|
||||||
priv->ip4_state = IP_DONE;
|
|
||||||
priv->ip6_state = IP_DONE;
|
|
||||||
nm_device_queue_state (dev, NM_DEVICE_STATE_SECONDARIES, NM_DEVICE_STATE_REASON_NONE);
|
|
||||||
} else {
|
} else {
|
||||||
NMDeviceState new_state = NM_DEVICE_STATE_DISCONNECTED;
|
nm_log_warn (LOGD_DEVICE,
|
||||||
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
|
"Activation (%s) connection '%s' could not be enslaved",
|
||||||
|
nm_device_get_iface (dev),
|
||||||
|
nm_connection_get_id (connection));
|
||||||
|
}
|
||||||
|
|
||||||
if ( priv->state > NM_DEVICE_STATE_DISCONNECTED
|
priv->ip4_state = IP_DONE;
|
||||||
&& priv->state <= NM_DEVICE_STATE_ACTIVATED) {
|
priv->ip6_state = IP_DONE;
|
||||||
if (master_failed) {
|
nm_device_queue_state (dev,
|
||||||
new_state = NM_DEVICE_STATE_FAILED;
|
success ? NM_DEVICE_STATE_SECONDARIES : NM_DEVICE_STATE_FAILED,
|
||||||
reason = NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED;
|
NM_DEVICE_STATE_REASON_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
nm_log_warn (LOGD_DEVICE,
|
/**
|
||||||
"Activation (%s) connection '%s' master failed",
|
* nm_device_slave_notify_release:
|
||||||
nm_device_get_iface (dev),
|
* @dev: the slave device
|
||||||
nm_connection_get_id (connection));
|
* @master_failed: indicates whether the release was unexpected,
|
||||||
} else {
|
* ie the master device failed.
|
||||||
nm_log_dbg (LOGD_DEVICE,
|
*
|
||||||
"Activation (%s) connection '%s' master deactivated",
|
* Notifies a slave that it has been released, and whether this was expected
|
||||||
nm_device_get_iface (dev),
|
* or not.
|
||||||
nm_connection_get_id (connection));
|
*/
|
||||||
}
|
void
|
||||||
|
nm_device_slave_notify_release (NMDevice *dev, gboolean master_failed)
|
||||||
|
{
|
||||||
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev);
|
||||||
|
NMConnection *connection = nm_device_get_connection (dev);
|
||||||
|
NMDeviceState new_state;
|
||||||
|
NMDeviceStateReason reason;
|
||||||
|
|
||||||
nm_device_queue_state (dev, new_state, reason);
|
if ( priv->state > NM_DEVICE_STATE_DISCONNECTED
|
||||||
|
&& priv->state <= NM_DEVICE_STATE_ACTIVATED) {
|
||||||
|
if (master_failed) {
|
||||||
|
new_state = NM_DEVICE_STATE_FAILED;
|
||||||
|
reason = NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED;
|
||||||
|
|
||||||
|
nm_log_warn (LOGD_DEVICE,
|
||||||
|
"Activation (%s) connection '%s' master failed",
|
||||||
|
nm_device_get_iface (dev),
|
||||||
|
nm_connection_get_id (connection));
|
||||||
|
} else {
|
||||||
|
new_state = NM_DEVICE_STATE_DISCONNECTED;
|
||||||
|
reason = NM_DEVICE_STATE_REASON_NONE;
|
||||||
|
|
||||||
|
nm_log_dbg (LOGD_DEVICE,
|
||||||
|
"Activation (%s) connection '%s' master deactivated",
|
||||||
|
nm_device_get_iface (dev),
|
||||||
|
nm_connection_get_id (connection));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nm_device_queue_state (dev, new_state, reason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3505,6 +3526,8 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data)
|
||||||
/* Clear the activation source ID now that this stage has run */
|
/* Clear the activation source ID now that this stage has run */
|
||||||
activation_source_clear (self, FALSE, 0);
|
activation_source_clear (self, FALSE, 0);
|
||||||
|
|
||||||
|
priv->ip4_state = priv->ip6_state = IP_WAIT;
|
||||||
|
|
||||||
iface = nm_device_get_iface (self);
|
iface = nm_device_get_iface (self);
|
||||||
nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 3 of 5 (IP Configure Start) started...", iface);
|
nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 3 of 5 (IP Configure Start) started...", iface);
|
||||||
nm_device_state_changed (self, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE);
|
nm_device_state_changed (self, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE);
|
||||||
|
|
@ -3514,20 +3537,19 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data)
|
||||||
if (ifindex && !nm_platform_link_is_up (ifindex))
|
if (ifindex && !nm_platform_link_is_up (ifindex))
|
||||||
nm_platform_link_set_up (ifindex);
|
nm_platform_link_set_up (ifindex);
|
||||||
|
|
||||||
priv->ip4_state = priv->ip6_state = IP_WAIT;
|
|
||||||
|
|
||||||
/* If the device is a slave, then we don't do any IP configuration but we
|
/* If the device is a slave, then we don't do any IP configuration but we
|
||||||
* use the IP config stage to indicate to the master we're ready for
|
* use the IP config stage to indicate to the master we're ready for
|
||||||
* enslavement. Either the master has already enslaved us, in which case
|
* enslavement. If the master is already activating, it will have tried to
|
||||||
* our state transition to SECONDARIES is already queued courtesy of
|
* enslave us when we changed state to IP_CONFIG, causing us to queue a
|
||||||
* nm_device_slave_notify_enslaved(), or the master is still activating,
|
* transition to SECONDARIES (or FAILED if the enslavement failed), with
|
||||||
* in which case we postpone activation here until the master enslaves us,
|
* our IP states set to IP_DONE either way. If the master isn't yet
|
||||||
* which calls nm_device_slave_notify_enslaved().
|
* activating, then they'll still be in IP_WAIT. Either way, we bail out
|
||||||
|
* of IP config here.
|
||||||
*/
|
*/
|
||||||
master = nm_active_connection_get_master (NM_ACTIVE_CONNECTION (priv->act_request));
|
master = nm_active_connection_get_master (NM_ACTIVE_CONNECTION (priv->act_request));
|
||||||
if (master) {
|
if (master) {
|
||||||
master_device = nm_active_connection_get_device (master);
|
master_device = nm_active_connection_get_device (master);
|
||||||
if (master_device && priv->enslaved == FALSE) {
|
if (priv->ip4_state == IP_WAIT && priv->ip6_state == IP_WAIT) {
|
||||||
nm_log_info (LOGD_DEVICE, "Activation (%s) connection '%s' waiting on master '%s'",
|
nm_log_info (LOGD_DEVICE, "Activation (%s) connection '%s' waiting on master '%s'",
|
||||||
nm_device_get_iface (self),
|
nm_device_get_iface (self),
|
||||||
nm_connection_get_id (nm_device_get_connection (self)),
|
nm_connection_get_id (nm_device_get_connection (self)),
|
||||||
|
|
|
||||||
|
|
@ -250,11 +250,6 @@ gboolean nm_device_master_add_slave (NMDevice *dev, NMDevice *slave);
|
||||||
GSList * nm_device_master_get_slaves (NMDevice *dev);
|
GSList * nm_device_master_get_slaves (NMDevice *dev);
|
||||||
gboolean nm_device_is_master (NMDevice *dev);
|
gboolean nm_device_is_master (NMDevice *dev);
|
||||||
|
|
||||||
/* Slave */
|
|
||||||
void nm_device_slave_notify_enslaved (NMDevice *dev,
|
|
||||||
gboolean enslaved,
|
|
||||||
gboolean master_failed);
|
|
||||||
|
|
||||||
NMActRequest * nm_device_get_act_request (NMDevice *dev);
|
NMActRequest * nm_device_get_act_request (NMDevice *dev);
|
||||||
NMConnection * nm_device_get_connection (NMDevice *dev);
|
NMConnection * nm_device_get_connection (NMDevice *dev);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue