Libuci feature help

I've written a userspace manager that gets configuration from the cloud and pushes it to the device. The manager receives this config which includes things like network interfaces and wireless interfaces. I take that information and create the package sections for the wireless interface then save, commit, and reload the network. I've gotten everything to work minus one "feature" that I am struggling with. The wireless interface section I create, I need it named the same as the wireless interface name instead of the generic name that is auto-assigned. So I create the section then immediately rename it. I then add the various options and then go to save and commit the changes. This is where the "feature" causes a second section with the same name as the originally auto-assigned section name gets created. For some reason, it shows up in "pkg->saved_delta" after the commit returns. The config file then contains the new section I created with all the options properly set and a second but empty section with the original auto-assigned name. Below is more information including a code snippet that exhibits the "feature". Is this behavior expected? If so, is there any workaround?

The contents of /tmp/.uci/wireless just before the commit is:

cat /tmp/.uci/wireless
+wireless.cfg033579='wifi-iface'
@wireless.cfg033579='home-ap-50'
wireless.home-ap-50.ifname='home-ap-50'
wireless.home-ap-50.device='wifi0'
wireless.home-ap-50.disabled='0'
wireless.home-ap-50.mode='ap'
wireless.home-ap-50.ssid='OpenWrt'
wireless.home-ap-50.network='lan'
wireless.home-ap-50.hidden='0'
wireless.home-ap-50.encryption='none'

To recreate just run the following:

struct uci_section*
openwrt_uci_add_named_section(const char* pkgname, const char* section)
{
    static struct uci_context* ctx = NULL;
    struct uci_package* p = NULL;
    struct uci_section* s = NULL;
    struct uci_ptr ptr = { 0 };

   // Allocate a new context if this is the first time through
    if (!ctx && (ctx = uci_alloc_context()) == NULL)
        return NULL;

    // Lookup package
    p = uci_lookup_package(ctx, pkgname);

    // Load package if it wasn't already loaded
    if (!p && uci_load(ctx, pkgname, &p))
        return NULL;

    // Check if the section already exists and return immediately
    s = uci_lookup_section(p->ctx, p, section);
    if (s != NULL)
        return s;

    // Add new section; note: section is not named
    ret = uci_add_section(p->ctx, p, type, &s);
    if (ret != UCI_OK)
        return NULL;

    // Rename section from its auto-assigned name
    ptr.p = p;
    ptr.s = s;
    ptr.value = name;
    ret = uci_rename(p->ctx, &ptr);
    if (ret != UCI_OK)
        return NULL;

    // Save the section
    if (uci_save(p->ctx, p) != UCI_OK)
        return NULL;

    // Commit the config (note: writes out to package file)
    if (uci_commit(p->ctx, &p, true) != UCI_OK)
        return NULL;

    return s;

}

Kevin Mahoney

See http://lists.infradead.org/pipermail/openwrt-devel/2020-March/022488.html

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.