block: try to find the root device on both / and /rom
[project/fstools.git] / block.c
diff --git a/block.c b/block.c
index 9f5cebf28f5adddbf42791fa9b6b00bff11b567b..7b2ea8fd31141d87baed7d0ca26372e1ff42daf3 100644 (file)
--- a/block.c
+++ b/block.c
@@ -33,8 +33,6 @@
 #include <sys/wait.h>
 #include <sys/sysmacros.h>
 
-#include <linux/fs.h>
-
 #include <uci.h>
 #include <uci_blob.h>
 
@@ -481,11 +479,64 @@ static int config_load(char *cfg)
        return 0;
 }
 
+static bool mtdblock_is_nand(char *mtdnum)
+{
+       char tmppath[64];
+       char buf[16];
+       FILE *fp;
+
+       snprintf(tmppath, sizeof(tmppath) - 1, "/sys/class/mtd/mtd%s/type", mtdnum);
+       fp = fopen(tmppath, "r");
+       if (!fp)
+               return false;
+
+       if (!fgets(buf, sizeof(buf), fp)) {
+               fclose(fp);
+               return false;
+       }
+       fclose(fp);
+       buf[sizeof(buf) - 1] = '\0'; /* make sure buf is 0-terminated */
+       buf[strlen(buf) - 1] = '\0'; /* strip final char (newline) */
+
+       if (strcmp(buf, "nand"))
+               return false;
+
+       /*
+        * --- CUT HERE ---
+        * Keep probing rootfs and rootfs_data in the meantime to not break
+        * devices using JFFS2 on NAND but only trigger the kernel warnings.
+        * Remove this once all devices using JFFS2 and squashfs directly on
+        * NAND have been converted to UBI.
+        */
+       snprintf(tmppath, sizeof(tmppath) - 1, "/sys/class/mtd/mtd%s/name", mtdnum);
+       fp = fopen(tmppath, "r");
+       if (!fp)
+               return false;
+
+       if (!fgets(buf, sizeof(buf), fp)) {
+               fclose(fp);
+               return false;
+       }
+       fclose(fp);
+       buf[sizeof(buf) - 1] = '\0'; /* make sure buf is 0-terminated */
+       buf[strlen(buf) - 1] = '\0'; /* strip final char (newline) */
+
+       /* only return true if name differs from 'rootfs' and 'rootfs_data' */
+       if (strcmp(buf, "rootfs") && strcmp(buf, "rootfs_data"))
+               return true;
+
+       /* --- CUT HERE --- */
+       return false;
+}
+
 static struct probe_info* _probe_path(char *path)
 {
        struct probe_info *pr, *epr;
        char tmppath[64];
 
+       if (!strncmp(path, "/dev/mtdblock", 13) && mtdblock_is_nand(path + 13))
+               return NULL;
+
        pr = probe_path(path);
        if (!pr)
                return NULL;
@@ -883,15 +934,34 @@ static int exec_mount(const char *source, const char *target,
        return err;
 }
 
+static const char * const ntfs_fs[] = { "ntfs3", "ntfs-3g", "antfs", "ntfs" };
+
 static int handle_mount(const char *source, const char *target,
                         const char *fstype, struct mount *m)
 {
-       int i, err;
        size_t mount_opts_len;
        char *mount_opts = NULL, *ptr;
+       const char * const *filesystems;
+       int err = -EINVAL;
+       size_t count;
+       int i;
 
-       err = mount(source, target, fstype, m ? m->flags : 0,
-                   (m && m->options) ? m->options : "");
+       if (!strcmp(fstype, "ntfs")) {
+               filesystems = ntfs_fs;
+               count = ARRAY_SIZE(ntfs_fs);
+       } else {
+               filesystems = &fstype;
+               count = 1;
+       }
+
+       for (i = 0; i < count; i++) {
+               const char *fs = filesystems[i];
+
+               err = mount(source, target, fs, m ? m->flags : 0,
+                           (m && m->options) ? m->options : "");
+               if (!err || errno != ENODEV)
+                       break;
+       }
 
        /* Requested file system type is not available in kernel,
           attempt to call mount helper. */
@@ -928,7 +998,13 @@ static int handle_mount(const char *source, const char *target,
                }
 
                /* ... and now finally invoke the external mount program */
-               err = exec_mount(source, target, fstype, mount_opts);
+               for (i = 0; i < count; i++) {
+                       const char *fs = filesystems[i];
+
+                       err = exec_mount(source, target, fs, mount_opts);
+                       if (!err)
+                               break;
+               }
        }
 
        free(mount_opts);
@@ -1321,14 +1397,14 @@ static int find_block_ubi_RO(libubi_t libubi, char *name, char *part, int plen)
 }
 #endif
 
-static int find_root_dev(char *buf, int len)
+static int find_dev(const char *path, char *buf, int len)
 {
        DIR *d;
        dev_t root;
        struct stat s;
        struct dirent *e;
 
-       if (stat("/", &s))
+       if (stat(path, &s))
                return -1;
 
        if (!(d = opendir("/dev")))
@@ -1350,6 +1426,15 @@ static int find_root_dev(char *buf, int len)
        return -1;
 }
 
+static int find_root_dev(char *buf, int len)
+{
+       int err = find_dev("/", buf, len);
+       if (err)
+           err = find_dev("/rom", buf, len);
+
+       return err;
+}
+
 static int test_fs_support(const char *name)
 {
        char line[128], *p;
@@ -1570,6 +1655,11 @@ static int main_extroot(int argc, char **argv)
        /* enable LOG_INFO messages */
        ulog_threshold(LOG_INFO);
 
+       /* try the currently mounted overlay if exists */
+       err = mount_extroot("/tmp/overlay");
+       if (!err)
+           return err;
+
        /*
         * Look for "rootfs_data". We will want to mount it and check for
         * extroot configuration.