bonding_disable_port(bp, true);
break;
case DEV_EVENT_REMOVE:
- if (dep->hotplug) {
+ if (dep->hotplug && !dev->sys_present) {
vlist_delete(&bdev->ports, &bp->node);
return;
}
bridge_disable_member(bm, true);
break;
case DEV_EVENT_REMOVE:
- if (dep->hotplug) {
+ if (dep->hotplug && !dev->sys_present) {
vlist_delete(&bst->members, &bm->node);
return;
}
device_delete(dev);
}
-static void __device_set_present(struct device *dev, bool state)
+static void __device_set_present(struct device *dev, bool state, bool force)
{
- if (dev->present == state)
+ if (dev->present == state && !force)
return;
dev->present = state;
if (dev->disabled || dev->deferred)
state = false;
- __device_set_present(dev, state);
+ __device_set_present(dev, state, false);
}
void
D(DEVICE, "%s '%s' %s present\n", dev->type->name, dev->ifname, state ? "is now" : "is no longer" );
dev->sys_present = state;
- device_refresh_present(dev);
+ if (!state)
+ __device_set_present(dev, state, true);
+ else
+ device_refresh_present(dev);
if (!state)
safe_list_for_each(&dev->users, device_release_cb, NULL);
}
break;
case DEV_EVENT_REMOVE:
interface_set_available(iface, false);
- if (dep->dev && dep->dev->external)
+ if (dep->dev && dep->dev->external && !dep->dev->sys_present)
interface_set_main_dev(iface, NULL);
break;
case DEV_EVENT_UP:
system_device_update_state(struct device *dev, unsigned int flags, unsigned int ifindex)
{
if (dev->type == &simple_device_type) {
- bool present = ifindex > 0;
-
if (dev->external)
- present = present && (flags & IFF_UP);
+ device_set_disabled(dev, !(flags & IFF_UP));
- device_set_present(dev, present);
+ device_set_present(dev, ifindex > 0);
}
device_set_link(dev, flags & IFF_LOWER_UP ? true : false);
}