trace: use standard POSIX header for basename()
[project/procd.git] / system.c
index bd3f76c49583aa2d807b7c0676a2711a0b996839..21ec3cdc07a2e1b1b17a292bb4a6b5ab0d478069 100644 (file)
--- a/system.c
+++ b/system.c
@@ -20,6 +20,7 @@
 #include <sys/types.h>
 #include <sys/reboot.h>
 #include <sys/stat.h>
+#include <sys/statvfs.h>
 #include <fcntl.h>
 #include <signal.h>
 #include <unistd.h>
@@ -32,6 +33,7 @@
 #include "procd.h"
 #include "sysupgrade.h"
 #include "watchdog.h"
+#include "service/service.h"
 
 static struct blob_buf b;
 static int notify;
@@ -49,9 +51,8 @@ static const char *system_rootfs_type(void) {
        static char fstype[16] = { 0 };
        char *mountstr = NULL, *mp = "/", *pos, *tmp;
        FILE *mounts;
-       ssize_t nread;
        size_t len = 0;
-       bool found;
+       bool found = false;
 
        if (initramfs)
                return "initramfs";
@@ -60,9 +61,10 @@ static const char *system_rootfs_type(void) {
                return fstype;
 
        mounts = fopen(proc_mounts, "r");
-       while ((nread = getline(&mountstr, &len, mounts)) != -1) {
-               found = false;
+       if (!mounts)
+               return NULL;
 
+       while (getline(&mountstr, &len, mounts) != -1) {
                pos = strchr(mountstr, ' ');
                if (!pos)
                        continue;
@@ -89,8 +91,12 @@ static const char *system_rootfs_type(void) {
                         * 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.
+                        * restart searching for that instead if that's not
+                        * already the case.
                         */
+                       if (!strcmp(mp, "/rom"))
+                               break;
+
                        mp = "/rom";
                        fseek(mounts, 0, SEEK_SET);
                        continue;
@@ -101,8 +107,9 @@ static const char *system_rootfs_type(void) {
        }
 
        if (found)
-               strncpy(fstype, tmp, sizeof(fstype));
+               strncpy(fstype, tmp, sizeof(fstype) - 1);
 
+       fstype[sizeof(fstype) - 1]= '\0';
        free(mountstr);
        fclose(mounts);
 
@@ -147,6 +154,12 @@ static int system_board(struct ubus_context *ctx, struct ubus_object *obj,
                                blobmsg_add_string(&b, "system", line);
                                break;
                        }
+#elif __riscv
+                       if (!strcasecmp(key, "isa")) {
+                               snprintf(line, sizeof(line), "RISC-V (%s)", val + 2);
+                               blobmsg_add_string(&b, "system", line);
+                               break;
+                       }
 #else
                        if (!strcasecmp(key, "system type") ||
                            !strcasecmp(key, "processor") ||
@@ -308,6 +321,12 @@ static int system_board(struct ubus_context *ctx, struct ubus_object *obj,
        return UBUS_STATUS_OK;
 }
 
+static unsigned long
+kscale(unsigned long b, unsigned long bs)
+{
+       return (b * (unsigned long long) bs + 1024/2) / 1024;
+}
+
 static int system_info(struct ubus_context *ctx, struct ubus_object *obj,
                 struct ubus_request_data *req, const char *method,
                 struct blob_attr *msg)
@@ -321,6 +340,12 @@ static int system_info(struct ubus_context *ctx, struct ubus_object *obj,
        char *key, *val;
        unsigned long long available, cached;
        FILE *f;
+       int i;
+       struct statvfs s;
+       const char *fslist[] = {
+               "/",    "root",
+               "/tmp", "tmp",
+       };
 
        if (sysinfo(&info))
                return UBUS_STATUS_UNKNOWN_ERROR;
@@ -380,6 +405,23 @@ static int system_info(struct ubus_context *ctx, struct ubus_object *obj,
        blobmsg_add_u64(&b, "cached", cached);
        blobmsg_close_table(&b, c);
 
+       for (i = 0; i < sizeof(fslist) / sizeof(fslist[0]); i += 2) {
+               if (statvfs(fslist[i], &s))
+                       continue;
+
+               c = blobmsg_open_table(&b, fslist[i+1]);
+
+               if (!s.f_frsize)
+                       s.f_frsize = s.f_bsize;
+
+               blobmsg_add_u64(&b, "total", kscale(s.f_blocks, s.f_frsize));
+               blobmsg_add_u64(&b, "free",  kscale(s.f_bfree, s.f_frsize));
+               blobmsg_add_u64(&b, "used", kscale(s.f_blocks - s.f_bfree, s.f_frsize));
+               blobmsg_add_u64(&b, "avail", kscale(s.f_bavail, s.f_frsize));
+
+               blobmsg_close_table(&b, c);
+       }
+
        c = blobmsg_open_table(&b, "swap");
        blobmsg_add_u64(&b, "total",
                        (uint64_t)info.mem_unit * (uint64_t)info.totalswap);
@@ -776,6 +818,8 @@ static int sysupgrade(struct ubus_context *ctx, struct ubus_object *obj,
                return UBUS_STATUS_NOT_SUPPORTED;
        }
 
+       service_stop_all();
+
        sysupgrade_exec_upgraded(blobmsg_get_string(tb[SYSUPGRADE_PREFIX]),
                                 blobmsg_get_string(tb[SYSUPGRADE_PATH]),
                                 tb[SYSUPGRADE_BACKUP] ? blobmsg_get_string(tb[SYSUPGRADE_BACKUP]) : NULL,