libfstools: query drivers by priority
[project/fstools.git] / libfstools / rootdisk.c
index dd00c1b4e5b4aa9b748610fa3e93d301a67101a7..ba7d8c3727ba6c67123d544344dcfa215070becb 100644 (file)
  * GNU General Public License for more details.
  */
 
-#define F2FS_MINSIZE   (100 * 1024 * 1024)
-#define _FILE_OFFSET_BITS 64
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/mount.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "libfstools.h"
-#include "volume.h"
+#include "common.h"
 
 #include <linux/loop.h>
 
 #define ROOTDEV_OVERLAY_ALIGN  (64ULL * 1024ULL)
+#define F2FS_MINSIZE           (100ULL * 1024ULL * 1024ULL)
 
 struct squashfs_super_block {
        uint32_t s_magic;
@@ -107,20 +93,6 @@ static int get_squashfs(struct squashfs_super_block *sb)
        return 0;
 }
 
-static bool rootdisk_use_f2fs(struct rootdev_volume *p)
-{
-       uint64_t size = 0;
-       bool ret = false;
-       int fd;
-
-       fd = open(rootdev, O_RDONLY);
-       if (ioctl(fd, BLKGETSIZE64, &size) == 0)
-               ret = size - p->offset > F2FS_MINSIZE;
-       close(fd);
-
-       return ret;
-}
-
 static struct volume *rootdisk_volume_find(char *name)
 {
        struct squashfs_super_block sb;
@@ -136,10 +108,6 @@ static struct volume *rootdisk_volume_find(char *name)
        if (!rootdev)
                return NULL;
 
-       if (strstr(rootdev, "mtdblock") ||
-           strstr(rootdev, "ubiblock"))
-               return NULL;
-
        if (get_squashfs(&sb))
                return NULL;
 
@@ -160,30 +128,13 @@ static struct volume *rootdisk_volume_find(char *name)
 static int rootdisk_volume_identify(struct volume *v)
 {
        struct rootdev_volume *p = container_of(v, struct rootdev_volume, v);
-       int ret = FS_NONE;
-       uint32_t magic = 0;
-       size_t n;
        FILE *f;
-
+       int ret = FS_NONE;
        f = fopen(rootdev, "r");
        if (!f)
                return ret;
 
-       fseeko(f, p->offset + 0x400, SEEK_SET);
-       n = fread(&magic, sizeof(magic), 1, f);
-       if (n != 1)
-               return -1;
-
-       if (magic == cpu_to_le32(0xF2F52010))
-               ret = FS_F2FS;
-
-       magic = 0;
-       fseeko(f, p->offset + 0x438, SEEK_SET);
-       n = fread(&magic, sizeof(magic), 1, f);
-       if (n != 1)
-               return -1;
-       if ((le32_to_cpu(magic) & 0xffff) == 0xef53)
-               ret = FS_EXT4;
+       ret = block_file_identify(f, p->offset);
 
        fclose(f);
 
@@ -231,12 +182,19 @@ static int rootdisk_create_loop(struct rootdev_volume *p)
                snprintf((char *) info.lo_file_name, sizeof(info.lo_file_name), "%s",
                         rootdev);
                info.lo_offset = p->offset;
+               info.lo_flags |= LO_FLAGS_AUTOCLEAR;
 
                if (ioctl(fd, LOOP_SET_STATUS64, &info) != 0) {
                        ioctl(fd, LOOP_CLR_FD, 0);
                        continue;
                }
 
+               /*
+                * Don't close fd. Leave it open until this process exits, to avoid
+                * the autoclear from happening too soon.
+                */
+               fd = -1;
+
                ret = 0;
                break;
        }
@@ -255,28 +213,16 @@ static int rootdisk_create_loop(struct rootdev_volume *p)
 static int rootdisk_volume_init(struct volume *v)
 {
        struct rootdev_volume *p = container_of(v, struct rootdev_volume, v);
-       char str[128];
-       int ret = 0;
 
-       if (!p->loop_name[0] && rootdisk_create_loop(p) != 0)
+       if (!p->loop_name[0] && rootdisk_create_loop(p) != 0) {
+               ULOG_ERR("unable to create loop device\n");
                return -1;
+       }
 
        v->type = BLOCKDEV;
        v->blk = p->loop_name;
 
-       switch (rootdisk_volume_identify(v)) {
-       case FS_NONE:
-               ULOG_INFO("rootdisk overlay filesystem has not been formatted yet\n");
-               if (rootdisk_use_f2fs(p))
-                       snprintf(str, sizeof(str), "mkfs.f2fs -q -l rootfs_data %s", v->blk);
-               else
-                       snprintf(str, sizeof(str), "mkfs.ext4 -q -L rootfs_data %s", v->blk);
-               ret = system(str);
-               break;
-       default:
-               break;
-       }
-       return ret;
+       return block_volume_format(v, p->offset, rootdev);
 }
 
 static struct driver rootdisk_driver = {