Browse Source

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>
Daniel Golle 2 years ago
parent
commit
3a9d9102aa
1 changed files with 67 additions and 2 deletions
  1. 67 2
      uxc.c

+ 67 - 2
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]))