X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fnetifd.git;a=blobdiff_plain;f=device.c;h=6929177cd59caee5c4feb233aaf9370c773e64e2;hp=ccf66d7b17288178c112ad2f87454c1da1e076a7;hb=e8a8f555aac97b47bd036264b598affec66f96d5;hpb=f1b77140237f2f6e7f6b755b5a60ab212782456e diff --git a/device.c b/device.c index ccf66d7..6929177 100644 --- a/device.c +++ b/device.c @@ -141,8 +141,11 @@ int device_claim(struct device_user *dep) ret = dev->set_state(dev, true); if (ret == 0) device_broadcast_event(dev, DEV_EVENT_UP); - else + else { + D(DEVICE, "claim device %s failed: %d\n", dev->ifname, ret); dev->active = 0; + dep->claimed = false; + } return ret; } @@ -203,6 +206,7 @@ int device_init(struct device *dev, const struct device_type *type, const char * if (ret < 0) return ret; + system_if_clear_state(dev); device_check_state(dev); return 0; @@ -259,6 +263,7 @@ void device_cleanup(struct device *dev) continue; dep->cb(dep, DEV_EVENT_REMOVE); + device_release(dep); } device_delete(dev); @@ -288,7 +293,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) + if (!list_empty(&dev->users) || dev->current_config || config_init) return; device_free(dev); @@ -335,21 +340,23 @@ device_init_pending(void) enum dev_change_type device_reload_config(struct device *dev, struct blob_attr *attr) { - struct blob_attr *tb[__DEV_ATTR_MAX], *tb1[__DEV_ATTR_MAX]; - - blobmsg_parse(dev_attrs, __DEV_ATTR_MAX, tb, - blob_data(attr), blob_len(attr)); - if (dev->config) - blobmsg_parse(dev_attrs, __DEV_ATTR_MAX, tb1, - blob_data(dev->config), blob_len(dev->config)); - else - memset(tb1, 0, sizeof(tb1)); + struct blob_attr *tb[__DEV_ATTR_MAX]; + const struct config_param_list *cfg = dev->type->config_params; - if (!config_diff(tb, tb1, &device_attr_list, NULL)) + if (config_check_equal(dev->config, attr, cfg)) return DEV_CONFIG_NO_CHANGE; - device_init_settings(dev, tb); - return DEV_CONFIG_APPLIED; + if (cfg == &device_attr_list) { + memset(tb, 0, sizeof(tb)); + + if (dev->config) + blobmsg_parse(dev_attrs, __DEV_ATTR_MAX, tb, + blob_data(attr), blob_len(attr)); + + device_init_settings(dev, tb); + return DEV_CONFIG_APPLIED; + } else + return DEV_CONFIG_RECREATE; } static enum dev_change_type @@ -375,8 +382,9 @@ device_replace(struct device *dev, struct device *odev) device_set_present(odev, false); list_for_each_entry_safe(dep, tmp, &odev->users, list) { - device_remove_user(dep); - device_add_user(dep, dev); + device_release(dep); + list_move_tail(&dep->list, &dev->users); + dep->dev = dev; } device_free(odev); @@ -417,7 +425,6 @@ device_create(const char *name, const struct device_type *type, struct device *odev = NULL, *dev; enum dev_change_type change; - D(DEVICE, "Create new device '%s' (%s)\n", name, type->name); config = config_memdup(config); if (!config) return NULL; @@ -445,7 +452,8 @@ device_create(const char *name, const struct device_type *type, device_delete(odev); break; } - } + } else + D(DEVICE, "Create new device '%s' (%s)\n", name, type->name); dev = type->create(config); if (!dev)