core: fix activation of slave when master is not active, but device exists

NM fails to activate a slave if the master device already exists
but has not active connection.

One way to reproduce, create a bond master/slave configuration and
ensure that the master device exists (e.g. by activating the bond, and
killing NM without taking down the device, or externally via `ip link add`).

If you try to activate the slave it will fail with the following message
(in nmcli):
  "Error: Connection activation failed: The active connection on MASTER is not a valid master for 'SLAVE'"
although MASTER is not active.

This also triggers the following assertion:

    #0  0x0000003370c504e9 in g_logv () from /lib64/libglib-2.0.so.0
    #1  0x0000003370c5063f in g_log () from /lib64/libglib-2.0.so.0
    #2  0x000000000047646a in is_compatible_with_slave (master=0x0, slave=slave@entry=0xc4aa60) at nm-manager.c:2193
    #3  0x000000000047e289 in ensure_master_active_connection (self=self@entry=0xc8d150, subject=0x7f23b80059e0, connection=connection@entry=0xc4aa60, device=device@entry=0xcac380, master_connection=master_connection@entry=0x0,
        master_device=master_device@entry=0xc9e800, error=error@entry=0x7fffa5cc4958) at nm-manager.c:2395
    #4  0x000000000047eb4a in _internal_activate_device (self=self@entry=0xc8d150, active=active@entry=0xcc33b0, error=error@entry=0x7fffa5cc4958) at nm-manager.c:2665
    #5  0x000000000047ecf2 in _internal_activate_generic (self=self@entry=0xc8d150, active=active@entry=0xcc33b0, error=error@entry=0x7fffa5cc4958) at nm-manager.c:2712
    #6  0x000000000047ef2b in _internal_activation_auth_done (active=0xcc33b0, success=<optimized out>, error_desc=0x0, user_data1=0xc8d150, user_data2=<optimized out>) at nm-manager.c:2848
    #7  0x0000000000466fa1 in auth_done (chain=0xcef020, error=0x0, unused=<optimized out>, user_data=<optimized out>) at nm-active-connection.c:603
    #8  0x00000000004753da in auth_chain_finish (user_data=0xcef020) at nm-manager-auth.c:88
    #9  0x0000003370c492a6 in g_main_context_dispatch () from /lib64/libglib-2.0.so.0
    #10 0x0000003370c49628 in g_main_context_iterate.isra () from /lib64/libglib-2.0.so.0
    #11 0x0000003370c49a3a in g_main_loop_run () from /lib64/libglib-2.0.so.0
    #12 0x0000000000429e65 in main (argc=1, argv=0x7fffa5cc4e48) at main.c:678

Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
Thomas Haller 2014-06-11 20:35:08 +02:00 committed by Dan Williams
parent 931d793430
commit 0e266e7c16

View file

@ -2390,9 +2390,8 @@ ensure_master_active_connection (NMManager *self,
/* If we're passed a connection and a device, we require that connection
* be already activated on the device, eg returned from find_master().
*/
if (master_connection)
g_assert (device_connection == master_connection);
else if (!is_compatible_with_slave (device_connection, connection)) {
g_assert (!master_connection || master_connection == device_connection);
if (device_connection && !is_compatible_with_slave (device_connection, connection)) {
g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
"The active connection on %s is not a valid master for '%s'",
nm_device_get_iface (master_device),
@ -2404,6 +2403,7 @@ ensure_master_active_connection (NMManager *self,
if ( (master_state == NM_DEVICE_STATE_ACTIVATED)
|| nm_device_is_activating (master_device)) {
/* Device already using master_connection */
g_assert (device_connection);
return NM_ACTIVE_CONNECTION (nm_device_get_act_request (master_device));
}