summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Golle2021-07-24 22:51:37 +0000
committerDaniel Golle2021-07-24 23:52:06 +0000
commit3a9d9102aa29cd3522a457d6e961454dabdee7cc (patch)
treee391d9488537d0af938387ff6deb620d1b66ca3d
parent772292e0a37f42e9c6b3fdbe4d9f8e675db5d1d4 (diff)
downloadprocd-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.c69
1 files changed, 67 insertions, 2 deletions
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]))