block: print mountpoint if already mounted
[project/fstools.git] / block.c
diff --git a/block.c b/block.c
index 71ffd0b..e674521 100644 (file)
--- a/block.c
+++ b/block.c
@@ -29,6 +29,8 @@
 #include <sys/mount.h>
 #include <sys/wait.h>
 
+#include <linux/fs.h>
+
 #include <uci.h>
 #include <uci_blob.h>
 
@@ -147,18 +149,6 @@ struct mount_flag {
        int32_t flag;
 };
 
-#ifndef MS_DIRSYNC
-#      define MS_DIRSYNC               (1 << 7)
-#endif
-
-#ifndef MS_RELATIME
-#      define MS_RELATIME              (1 << 21)
-#endif
-
-#ifndef MS_STRICTATIME
-#      define MS_STRICTATIME   (1 << 24)
-#endif
-
 static const struct mount_flag mount_flags[] = {
        { "sync",               MS_SYNCHRONOUS  },
        { "async",              ~MS_SYNCHRONOUS },
@@ -180,6 +170,10 @@ static const struct mount_flag mount_flags[] = {
        { "relatime",           MS_RELATIME     },
        { "norelatime",         ~MS_RELATIME    },
        { "strictatime",        MS_STRICTATIME  },
+       { "acl",                MS_POSIXACL     },
+       { "noacl",              ~MS_POSIXACL    },
+       { "nouser_xattr",       MS_NOUSER       },
+       { "user_xattr",         ~MS_NOUSER      },
 };
 
 static char *blobmsg_get_strdup(struct blob_attr *attr)
@@ -470,6 +464,16 @@ static int config_load(char *cfg)
 static struct blkid_struct_probe* _probe_path(char *path)
 {
        struct blkid_struct_probe *pr;
+       char tmppath[64];
+
+       /* skip ubi device if ubiblock device is present */
+       if (path[5] == 'u' && path[6] == 'b' && path[7] == 'i' &&
+           path[8] >= '0' && path[8] <= '9' ) {
+               snprintf(tmppath, sizeof(tmppath), "/dev/ubiblock%s", path + 8);
+               list_for_each_entry(pr, &devices, list)
+                       if (!strcasecmp(pr->dev, tmppath))
+                               return NULL;
+       }
 
        pr = malloc(sizeof(*pr));
 
@@ -512,7 +516,7 @@ static void cache_load(int mtd)
        if (mtd) {
                _cache_load("/dev/mtdblock*");
                _cache_load("/dev/ubiblock*");
-               _cache_load("/dev/ubi?*_?*");
+               _cache_load("/dev/ubi[0-9]*");
        }
        _cache_load("/dev/mmcblk*");
        _cache_load("/dev/sd*");
@@ -584,9 +588,10 @@ static struct blkid_struct_probe* find_block_info(char *uuid, char *label, char
 static char* find_mount_point(char *block)
 {
        FILE *fp = fopen("/proc/mounts", "r");
-       static char line[256];
+       static char line[256], *saveptr;
        int len = strlen(block);
        char *point = NULL;
+       struct stat s;
 
        if(!fp)
                return NULL;
@@ -608,6 +613,32 @@ static char* find_mount_point(char *block)
 
        fclose(fp);
 
+       if (point)
+               return point;
+
+       if (stat(block, &s))
+               return NULL;
+
+       if (!S_ISBLK(s.st_mode))
+               return NULL;
+
+       fp = fopen("/proc/self/mountinfo", "r");
+       if(!fp)
+               return NULL;
+
+       while (fgets(line, sizeof(line), fp)) {
+               strtok_r(line, " \t", &saveptr);
+               strtok_r(NULL, " \t", &saveptr);
+               if (atoi(strtok_r(NULL, ":", &saveptr)) == major(s.st_rdev) &&
+                   atoi(strtok_r(NULL, " \t", &saveptr)) == minor(s.st_rdev)) {
+                       strtok_r(NULL, " \t", &saveptr);
+                       point = strtok_r(NULL, " \t", &saveptr);
+                       break;
+               }
+       }
+
+       fclose(fp);
+
        return point;
 }
 
@@ -628,31 +659,37 @@ static void check_filesystem(struct blkid_struct_probe *pr)
        pid_t pid;
        struct stat statbuf;
        const char *e2fsck = "/usr/sbin/e2fsck";
+       const char *dosfsck = "/usr/sbin/dosfsck";
+       const char *ckfs;
 
        /* UBIFS does not need stuff like fsck */
        if (!strncmp(pr->id->name, "ubifs", 5))
                return;
 
-       if (strncmp(pr->id->name, "ext", 3)) {
+       if (!strncmp(pr->id->name, "vfat", 4)) {
+               ckfs = dosfsck;
+       } else if (!strncmp(pr->id->name, "ext", 3)) {
+               ckfs = e2fsck;
+       } else {
                ULOG_ERR("check_filesystem: %s is not supported\n", pr->id->name);
                return;
        }
 
-       if (stat(e2fsck, &statbuf) < 0) {
-               ULOG_ERR("check_filesystem: %s not found\n", e2fsck);
+       if (stat(ckfs, &statbuf) < 0) {
+               ULOG_ERR("check_filesystem: %s not found\n", ckfs);
                return;
        }
 
        pid = fork();
        if (!pid) {
-               execl(e2fsck, e2fsck, "-p", pr->dev, NULL);
+               execl(ckfs, ckfs, "-p", pr->dev, NULL);
                exit(-1);
        } else if (pid > 0) {
                int status;
 
                waitpid(pid, &status, 0);
                if (WEXITSTATUS(status))
-                       ULOG_ERR("check_filesystem: %s returned %d\n", e2fsck, WEXITSTATUS(status));
+                       ULOG_ERR("check_filesystem: %s returned %d\n", ckfs, WEXITSTATUS(status));
        }
 }
 
@@ -690,6 +727,7 @@ static int mount_device(struct blkid_struct_probe *pr, int hotplug)
 {
        struct mount *m;
        char *device;
+       char *mp;
 
        if (!pr)
                return -1;
@@ -709,8 +747,9 @@ static int mount_device(struct blkid_struct_probe *pr, int hotplug)
        if (hotplug && !auto_mount)
                return -1;
 
-       if (find_mount_point(pr->dev)) {
-               ULOG_ERR("%s is already mounted\n", pr->dev);
+       mp = find_mount_point(pr->dev);
+       if (mp) {
+               ULOG_ERR("%s is already mounted on %s\n", pr->dev, mp);
                return -1;
        }
 
@@ -743,7 +782,7 @@ static int mount_device(struct blkid_struct_probe *pr, int hotplug)
        }
 
        if (anon_mount) {
-               char target[] = "/mnt/mmcblk123";
+               char target[32];
                int err = 0;
 
                snprintf(target, sizeof(target), "/mnt/%s", device);
@@ -1267,7 +1306,7 @@ static int main_info(int argc, char **argv)
                        ULOG_ERR("failed to stat %s\n", argv[i]);
                        continue;
                }
-               if (!S_ISBLK(s.st_mode)) {
+               if (!S_ISBLK(s.st_mode) && !(S_ISCHR(s.st_mode) && major(s.st_rdev) == 250)) {
                        ULOG_ERR("%s is not a block device\n", argv[i]);
                        continue;
                }