uxc: move mountpoint of persistent config to /var/run/uxc
[project/procd.git] / system.c
index 7855659d79710c9e742b1fd00d8c674f10cf738f..c208e3ee47434d3433aaa6ead4d3f75df803c6fc 100644 (file)
--- a/system.c
+++ b/system.c
@@ -36,6 +36,7 @@
 static struct blob_buf b;
 static int notify;
 static struct ubus_context *_ctx;
+static int initramfs;
 
 enum vjson_state {
        VJSON_ERROR,
@@ -43,6 +44,78 @@ 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");
+       if (!mounts)
+               return NULL;
+
+       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) - 1);
+
+       fstype[sizeof(fstype) - 1]= '\0';
+       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)
@@ -50,6 +123,7 @@ 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;
 
@@ -165,6 +239,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");
@@ -759,6 +836,11 @@ void ubus_init_system(struct ubus_context *ctx)
        int ret;
 
        _ctx = ctx;
+
+       initramfs = !!getenv("INITRAMFS");
+       if (initramfs)
+               unsetenv("INITRAMFS");
+
        ret = ubus_add_object(ctx, &system_object);
        if (ret)
                ERROR("Failed to add object: %s\n", ubus_strerror(ret));