rework route handling, move parser code to interface-ip.c, add extra options and...
[project/netifd.git] / device.c
index 6eb730e..717993a 100644 (file)
--- a/device.c
+++ b/device.c
@@ -41,6 +41,20 @@ const struct config_param_list device_attr_list = {
        .params = dev_attrs,
 };
 
+static int __devlock = 0;
+
+void device_lock(void)
+{
+       __devlock++;
+}
+
+void device_unlock(void)
+{
+       __devlock--;
+       if (!__devlock)
+               device_free_unused(NULL);
+}
+
 static struct device *
 simple_device_create(const char *name, struct blob_attr *attr)
 {
@@ -172,6 +186,8 @@ alias_notify_device(const char *name, struct device *dev)
 {
        struct alias_device *alias;
 
+       device_lock();
+
        alias = avl_find_element(&aliases, name, alias, avl);
        if (!alias)
                return;
@@ -179,8 +195,7 @@ alias_notify_device(const char *name, struct device *dev)
        alias->cleanup = !dev;
        if (dev) {
                if (dev != alias->dep.dev) {
-                       if (alias->dep.dev)
-                               device_remove_user(&alias->dep);
+                       device_remove_user(&alias->dep);
                        strcpy(alias->dev.ifname, dev->ifname);
                        device_add_user(&alias->dep, dev);
                }
@@ -190,6 +205,8 @@ alias_notify_device(const char *name, struct device *dev)
 
        if (!dev && alias->dep.dev && !alias->dep.dev->active)
                device_remove_user(&alias->dep);
+
+       device_unlock();
 }
 
 static int set_device_state(struct device *dev, bool state)
@@ -386,7 +403,7 @@ void device_add_user(struct device_user *dep, struct device *dev)
 static void
 __device_free_unused(struct device *dev)
 {
-       if (!list_empty(&dev->users) || dev->current_config || config_init)
+       if (!list_empty(&dev->users) || dev->current_config || __devlock)
                return;
 
        device_free(dev);
@@ -396,6 +413,10 @@ void device_remove_user(struct device_user *dep)
 {
        struct device *dev = dep->dev;
 
+       if (!dep->dev)
+               return;
+
+       dep->hotplug = false;
        if (dep->claimed)
                device_release(dep);