From: Daniel Golle Date: Sat, 24 Jul 2021 22:51:37 +0000 (+0100) Subject: uxc: resolve volume UUIDs by name of UCI fstab section X-Git-Url: http://git.openwrt.org/?p=project%2Fprocd.git;a=commitdiff_plain;h=3a9d9102aa29cd3522a457d6e961454dabdee7cc uxc: resolve volume UUIDs by name of UCI fstab section Allow identifying volumes which are required for a container to start by their UCI section name in /etc/config/fstab, which is also where 'uvol' puts the volume name. Using filesystem UUID instead is still possible as well. Signed-off-by: Daniel Golle --- diff --git a/uxc.c b/uxc.c index b801d7f..5b39e90 100644 --- a/uxc.c +++ b/uxc.c @@ -82,6 +82,7 @@ static struct option long_options[] = { AVL_TREE(runtime, avl_strcmp, false, NULL); static struct blob_buf conf; static struct blob_attr *blockinfo; +static struct blob_attr *fstabinfo; static struct ubus_context *ctx; static int usage(void) { @@ -701,7 +702,7 @@ static const struct blobmsg_policy block_info_policy[__BLOCK_INFO_MAX] = { /* check if device 'devname' is mounted according to blockd */ -static int checkblock(char *uuid) +static int checkblock(const char *uuid) { struct blob_attr *tb[__BLOCK_INFO_MAX]; struct blob_attr *cur; @@ -720,6 +721,52 @@ static int checkblock(char *uuid) return 1; } +enum { + UCI_FSTAB_UUID, + UCI_FSTAB_ANONYMOUS, + __UCI_FSTAB_MAX, +}; + +static const struct blobmsg_policy uci_fstab_policy[__UCI_FSTAB_MAX] = { + [UCI_FSTAB_UUID] = { .name = "uuid", .type = BLOBMSG_TYPE_STRING }, + [UCI_FSTAB_ANONYMOUS] = { .name = ".anonymous", .type = BLOBMSG_TYPE_BOOL }, +}; + +static const char *resolveuuid(const char *volname) +{ + struct blob_attr *tb[__UCI_FSTAB_MAX]; + struct blob_attr *cur; + const char *mntname; + char *tmpvolname, *replc; + int rem, res; + + blobmsg_for_each_attr(cur, fstabinfo, rem) { + blobmsg_parse(uci_fstab_policy, __UCI_FSTAB_MAX, tb, blobmsg_data(cur), blobmsg_len(cur)); + + if (!tb[UCI_FSTAB_UUID]) + continue; + + if (tb[UCI_FSTAB_ANONYMOUS] && blobmsg_get_bool(tb[UCI_FSTAB_ANONYMOUS])) + continue; + + mntname = blobmsg_name(cur); + if (!mntname) + continue; + + tmpvolname = strdup(volname); + while ((replc = strchr(tmpvolname, '-'))) + *replc = '_'; + + res = strcmp(tmpvolname, mntname); + free(tmpvolname); + + if (!res) + return blobmsg_get_string(tb[UCI_FSTAB_UUID]); + }; + + return volname; +}; + /* check status of each required volume */ static int checkvolumes(struct blob_attr *volumes) { @@ -727,7 +774,7 @@ static int checkvolumes(struct blob_attr *volumes) int rem; blobmsg_for_each_attr(cur, volumes, rem) { - if (checkblock(blobmsg_get_string(cur))) + if (checkblock(resolveuuid(blobmsg_get_string(cur)))) return 1; } @@ -739,10 +786,16 @@ static void block_cb(struct ubus_request *req, int type, struct blob_attr *msg) blockinfo = blob_memdup(blobmsg_data(msg)); } +static void fstab_cb(struct ubus_request *req, int type, struct blob_attr *msg) +{ + fstabinfo = blob_memdup(blobmsg_data(msg)); +} + static int uxc_boot(void) { struct blob_attr *cur, *tb[__CONF_MAX]; struct runtime_state *s; + static struct blob_buf req; int rem, ret = 0; char *name; unsigned int id; @@ -755,6 +808,18 @@ static int uxc_boot(void) if (ret) return ENXIO; + ret = ubus_lookup_id(ctx, "uci", &id); + if (ret) + return ENOENT; + + blob_buf_init(&req, 0); + blobmsg_add_string(&req, "config", "fstab"); + blobmsg_add_string(&req, "type", "mount"); + + ret = ubus_invoke(ctx, id, "get", req.head, fstab_cb, NULL, 3000); + if (ret) + return ENXIO; + blobmsg_for_each_attr(cur, blob_data(conf.head), rem) { blobmsg_parse(conf_policy, __CONF_MAX, tb, blobmsg_data(cur), blobmsg_len(cur)); if (!tb[CONF_NAME] || !tb[CONF_PATH] || !tb[CONF_AUTOSTART] || !blobmsg_get_bool(tb[CONF_AUTOSTART]))