system: make rootfs type accessible through board call
authorDaniel Golle <daniel@makrotopia.org>
Fri, 13 Aug 2021 01:23:03 +0000 (02:23 +0100)
committerDaniel Golle <daniel@makrotopia.org>
Fri, 13 Aug 2021 03:42:28 +0000 (04:42 +0100)
Knowing the type of the root filesystem can be useful, e.g. for the
attended sysupgrade clients.
As the previously introduced 'initramfs' flag is covered the the new
'rootfs_type' being 'initramfs', remove the old flag which should have
any users yet.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
system.c

index 83aea423ec6aaceedca54e42aea18ce90d7ddfa1..bd3f76c49583aa2d807b7c0676a2711a0b996839 100644 (file)
--- a/system.c
+++ b/system.c
@@ -44,6 +44,74 @@ enum vjson_state {
        VJSON_SUCCESS,
 };
 
+static const char *system_rootfs_type(void) {
+       const char proc_mounts[] = "/proc/self/mounts";
+       static char fstype[16] = { 0 };
+       char *mountstr = NULL, *mp = "/", *pos, *tmp;
+       FILE *mounts;
+       ssize_t nread;
+       size_t len = 0;
+       bool found;
+
+       if (initramfs)
+               return "initramfs";
+
+       if (fstype[0])
+               return fstype;
+
+       mounts = fopen(proc_mounts, "r");
+       while ((nread = getline(&mountstr, &len, mounts)) != -1) {
+               found = false;
+
+               pos = strchr(mountstr, ' ');
+               if (!pos)
+                       continue;
+
+               tmp = pos + 1;
+               pos = strchr(tmp, ' ');
+               if (!pos)
+                       continue;
+
+               *pos = '\0';
+               if (strcmp(tmp, mp))
+                       continue;
+
+               tmp = pos + 1;
+               pos = strchr(tmp, ' ');
+               if (!pos)
+                       continue;
+
+               *pos = '\0';
+
+               if (!strcmp(tmp, "overlay")) {
+                       /*
+                        * there is no point in parsing overlay option string for
+                        * lowerdir, as that can point to "/" being a previous
+                        * overlay mount (after firstboot or sysuprade config
+                        * restore). Hence just assume the lowerdir is "/rom" and
+                        * restart searching for that instead.
+                        */
+                       mp = "/rom";
+                       fseek(mounts, 0, SEEK_SET);
+                       continue;
+               }
+
+               found = true;
+               break;
+       }
+
+       if (found)
+               strncpy(fstype, tmp, sizeof(fstype));
+
+       free(mountstr);
+       fclose(mounts);
+
+       if (found)
+               return fstype;
+       else
+               return NULL;
+}
+
 static int system_board(struct ubus_context *ctx, struct ubus_object *obj,
                  struct ubus_request_data *req, const char *method,
                  struct blob_attr *msg)
@@ -51,14 +119,12 @@ static int system_board(struct ubus_context *ctx, struct ubus_object *obj,
        void *c;
        char line[256];
        char *key, *val, *next;
+       const char *rootfs_type = system_rootfs_type();
        struct utsname utsname;
        FILE *f;
 
        blob_buf_init(&b, 0);
 
-       if (initramfs)
-               blobmsg_add_u8(&b, "initramfs", 1);
-
        if (uname(&utsname) >= 0)
        {
                blobmsg_add_string(&b, "kernel", utsname.release);
@@ -169,6 +235,9 @@ static int system_board(struct ubus_context *ctx, struct ubus_object *obj,
                fclose(f);
        }
 
+       if (rootfs_type)
+               blobmsg_add_string(&b, "rootfs_type", rootfs_type);
+
        if ((f = fopen("/etc/openwrt_release", "r")) != NULL)
        {
                c = blobmsg_open_table(&b, "release");