diff options
| author | Daniel Golle | 2021-07-24 22:51:37 +0000 |
|---|---|---|
| committer | Daniel Golle | 2021-07-24 23:52:06 +0000 |
| commit | 3a9d9102aa29cd3522a457d6e961454dabdee7cc (patch) | |
| tree | e391d9488537d0af938387ff6deb620d1b66ca3d | |
| parent | 772292e0a37f42e9c6b3fdbe4d9f8e675db5d1d4 (diff) | |
| download | procd-3a9d9102aa29cd3522a457d6e961454dabdee7cc.tar.gz | |
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 <daniel@makrotopia.org>
| -rw-r--r-- | uxc.c | 69 |
1 files changed, 67 insertions, 2 deletions
@@ -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])) |