]> www.infradead.org Git - mtd-utils.git/commitdiff
fs-tests: integck: do not use tests_remount
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Wed, 13 Apr 2011 13:15:06 +0000 (16:15 +0300)
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Mon, 18 Apr 2011 14:44:46 +0000 (17:44 +0300)
Implement our own version of 'tests_remount()' instead of depending
on the common implementation.

Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
tests/fs-tests/integrity/integck.c

index 7a4bcdcc720150f0bf60c3aaa34d17785077382b..9bf42afbbc6c723586de3e28c026b3faa988724a 100644 (file)
@@ -67,6 +67,11 @@ static struct {
  * can_mmap: file-system supports share writable 'mmap()' operation
  * is_rootfs: the tested file-system the root file-system
  * fstype: file-system type (e.g., "ubifs")
+ * fsdev: the underlying device mounted by the tested file-system
+ * mount_opts: non-standard mount options of the tested file-system (non-standard
+ *             options are stored in string form as a comma-separated list)
+ * mount_flags: standard mount options of the tested file-system (standard
+ *              options as stored as a set of flags)
  * mount_point: tested file-system mount point path
  * test_dir: the directory on the tested file-system where we test
  */
@@ -78,6 +83,9 @@ static struct {
        unsigned int can_mmap:1;
        unsigned int is_rootfs:1;
        const char *fstype;
+       const char *fsdev;
+       const char *mount_opts;
+       unsigned long mount_flags;
        const char *mount_point;
        const char *test_dir;
 } fsinfo = {
@@ -2011,6 +2019,98 @@ static void update_test_data(void)
                do_an_operation();
 }
 
+/**
+ * Re-mount the test file-system. This function randomly select how to
+ * re-mount.
+ */
+void remount_tested_fs(void)
+{
+       char *wd_save;
+       int ret;
+       unsigned long flags;
+       unsigned int rorw1, um, um_ro, um_rorw, rorw2;
+
+       /* Save current working directory */
+       wd_save = malloc(PATH_MAX + 1);
+       CHECK(wd_save != NULL);
+       CHECK(getcwd(wd_save, PATH_MAX + 1) != NULL);
+
+       /* Temporarily change working directory to '/' */
+       CHECK(chdir("/") == 0);
+
+       /* Choose what to do */
+       rorw1 = rand() & 1;
+       um = rand() & 1;
+       um_ro = rand() & 1;
+       um_rorw = rand() & 1;
+       rorw2 = rand() & 1;
+
+       if (rorw1 + um + rorw2 == 0)
+               um = 1;
+
+       if (rorw1) {
+               flags = fsinfo.mount_flags | MS_RDONLY | MS_REMOUNT;
+               ret = mount(fsinfo.fsdev, fsinfo.mount_point, fsinfo.fstype,
+                           flags, fsinfo.mount_opts);
+               CHECK(ret == 0);
+
+               flags = fsinfo.mount_flags | MS_REMOUNT;
+               flags &= ~((unsigned long)MS_RDONLY);
+               ret = mount(fsinfo.fsdev, fsinfo.mount_point, fsinfo.fstype,
+                           flags, fsinfo.mount_opts);
+               CHECK(ret == 0);
+       }
+
+       if (um) {
+               if (um_ro) {
+                       flags = fsinfo.mount_flags | MS_RDONLY | MS_REMOUNT;
+                       ret = mount(fsinfo.fsdev, fsinfo.mount_point,
+                                   fsinfo.fstype, flags, fsinfo.mount_opts);
+                       CHECK(ret == 0);
+               }
+
+               CHECK(umount(fsinfo.mount_point) != -1);
+
+               if (!um_rorw) {
+                       ret = mount(fsinfo.fsdev, fsinfo.mount_point,
+                                   fsinfo.fstype, fsinfo.mount_flags,
+                                   fsinfo.mount_opts);
+                       CHECK(ret == 0);
+               } else {
+                       ret = mount(fsinfo.fsdev, fsinfo.mount_point,
+                                   fsinfo.fstype, fsinfo.mount_flags | MS_RDONLY,
+                                   fsinfo.mount_opts);
+                       CHECK(ret == 0);
+
+                       flags = fsinfo.mount_flags | MS_REMOUNT;
+                       flags &= ~((unsigned long)MS_RDONLY);
+                       ret = mount(fsinfo.fsdev, fsinfo.mount_point,
+                                   fsinfo.fstype, flags, fsinfo.mount_opts);
+                       CHECK(ret == 0);
+               }
+       }
+
+       if (rorw2) {
+               flags = fsinfo.mount_flags | MS_RDONLY | MS_REMOUNT;
+               ret = mount(fsinfo.fsdev, fsinfo.mount_point, fsinfo.fstype,
+                           flags, fsinfo.mount_opts);
+               CHECK(ret == 0);
+
+               flags = fsinfo.mount_flags | MS_REMOUNT;
+               flags &= ~((unsigned long)MS_RDONLY);
+               ret = mount(fsinfo.fsdev, fsinfo.mount_point, fsinfo.fstype,
+                           flags, fsinfo.mount_opts);
+               CHECK(ret == 0);
+       }
+
+       /* Restore the previous working directory */
+       CHECK(chdir(wd_save) == 0);
+       free(wd_save);
+}
+
+/*
+ * Perform the test. Returns zero on success and -1 on failure.
+ */
 static int integck(void)
 {
        int64_t rpt;
@@ -2030,7 +2130,7 @@ static int integck(void)
 
        if (fsinfo.is_rootfs) {
                close_open_files();
-               tests_remount(); /* Requires root access */
+               remount_tested_fs();
        }
 
        /* Check everything */
@@ -2043,7 +2143,7 @@ static int integck(void)
 
                if (!fsinfo.is_rootfs) {
                        close_open_files();
-                       tests_remount(); /* Requires root access */
+                       remount_tested_fs();
                }
 
                /* Check everything */
@@ -2059,6 +2159,67 @@ static int integck(void)
        return 0;
 }
 
+/*
+ * This is a helper function for 'get_tested_fs_info()'. It parses file-system
+ * mount options string, extracts standard mount options from there, and saves
+ * them in the 'fsinfo.mount_flags' variable, and non-standard mount options
+ * are saved in the 'fsinfo.mount_opts' variable. The reason for this is that
+ * we want to preserve mount options when unmounting the file-system and
+ * mounting it again. This is because we cannot pass standard mount optins
+ * (like sync, ro, etc) as a string to the 'mount()' function, because it
+ * fails. It accepts standard mount options only as flags. And only the
+ * FS-specific mount options are accepted in form of a string.
+ */
+static void parse_mount_options(const char *mount_opts)
+{
+       char *tmp, *opts, *p;
+       const char *opt;
+
+       /*
+        * We are going to use 'strtok()' which modifies the original string,
+        * so duplicate it.
+        */
+       tmp = dup_string(mount_opts);
+       p = opts = calloc(1, strlen(mount_opts) + 1);
+       CHECK(opts != NULL);
+
+       opt = strtok(tmp, ",");
+       while (opt) {
+               if (!strcmp(opt, "rw"))
+                       ;
+               else if (!strcmp(opt, "ro"))
+                       fsinfo.mount_flags |= MS_RDONLY;
+               else if (!strcmp(opt, "dirsync"))
+                       fsinfo.mount_flags |= MS_DIRSYNC;
+               else if (!strcmp(opt, "noatime"))
+                       fsinfo.mount_flags |= MS_NOATIME;
+               else if (!strcmp(opt, "nodiratime"))
+                       fsinfo.mount_flags |= MS_NODIRATIME;
+               else if (!strcmp(opt, "noexec"))
+                       fsinfo.mount_flags |= MS_NOEXEC;
+               else if (!strcmp(opt, "nosuid"))
+                       fsinfo.mount_flags |= MS_NOSUID;
+               else if (!strcmp(opt, "relatime"))
+                       fsinfo.mount_flags |= MS_RELATIME;
+               else if (!strcmp(opt, "sync"))
+                       fsinfo.mount_flags |= MS_SYNCHRONOUS;
+               else {
+                       int len = strlen(opt);
+
+                       if (p != opts)
+                               *p++ = ',';
+                       memcpy(p, opt, len);
+                       p += len;
+                       *p = '\0';
+               }
+
+               opt = strtok(NULL, ",");
+       }
+
+       free(tmp);
+       fsinfo.mount_opts = opts;
+}
+
 /*
  * Fill 'fsinfo' with information about the tested file-system.
  */
@@ -2104,6 +2265,8 @@ static void get_tested_fs_info(void)
         fclose(f);
 
        fsinfo.fstype = dup_string(mntent->mnt_type);
+       fsinfo.fsdev = strdup(mntent->mnt_fsname);
+       parse_mount_options(mntent->mnt_opts);
 
        /* Get memory page size for 'mmap()' */
        fsinfo.page_size = sysconf(_SC_PAGE_SIZE);