From ef4b2ceb552b5e32fa2defe7a48f1aec86b82333 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 20 Apr 2011 17:25:01 +0300 Subject: fs-tests: integck: add recovery remounting function When re-mountig to recover from the emulated power-cut failure then we should do a bit less fancy things, e.g., we should not try to re-mount to R/O and R/W modes forth and back, but we should instead just unmount directly. Additionally, we should not die if mount fails because there may be a power cut emulation during mounting. Thus, create a separate function for recovering and try to recover in a loop. Signed-off-by: Artem Bityutskiy --- tests/fs-tests/integrity/integck.c | 149 ++++++++++++++++++++++++++++++++++--- 1 file changed, 137 insertions(+), 12 deletions(-) (limited to 'tests/fs-tests') diff --git a/tests/fs-tests/integrity/integck.c b/tests/fs-tests/integrity/integck.c index 0d69ee4..1816461 100644 --- a/tests/fs-tests/integrity/integck.c +++ b/tests/fs-tests/integrity/integck.c @@ -2268,15 +2268,21 @@ static int remount_tested_fs(void) flags = fsinfo.mount_flags | MS_RDONLY | MS_REMOUNT; ret = mount(fsinfo.fsdev, fsinfo.mount_point, fsinfo.fstype, flags, fsinfo.mount_opts); - if (ret) + if (ret) { + pcv("cannot remount %s R/O (1)", + fsinfo.mount_point); return -1; + } flags = fsinfo.mount_flags | MS_REMOUNT; flags &= ~((unsigned long)MS_RDONLY); ret = mount(fsinfo.fsdev, fsinfo.mount_point, fsinfo.fstype, flags, fsinfo.mount_opts); - if (ret) + if (ret) { + pcv("remounted %s R/O (1), but cannot re-mount it R/W", + fsinfo.mount_point); return -1; + } } if (um) { @@ -2284,31 +2290,47 @@ static int remount_tested_fs(void) flags = fsinfo.mount_flags | MS_RDONLY | MS_REMOUNT; ret = mount(fsinfo.fsdev, fsinfo.mount_point, fsinfo.fstype, flags, fsinfo.mount_opts); - if (ret) + if (ret) { + pcv("cannot remount %s R/O (2)", + fsinfo.mount_point); return -1; + } } - CHECK(umount(fsinfo.mount_point) != -1); + ret = umount(fsinfo.mount_point); + if (ret) { + pcv("cannot unmount %s", fsinfo.mount_point); + return -1; + } if (!um_rorw) { ret = mount(fsinfo.fsdev, fsinfo.mount_point, fsinfo.fstype, fsinfo.mount_flags, fsinfo.mount_opts); - if (ret) + if (ret) { + pcv("unmounted %s, but cannot mount it back R/W", + fsinfo.mount_point); return -1; + } } else { ret = mount(fsinfo.fsdev, fsinfo.mount_point, fsinfo.fstype, fsinfo.mount_flags | MS_RDONLY, fsinfo.mount_opts); - if (ret) + if (ret) { + pcv("unmounted %s, but cannot mount it back R/O", + fsinfo.mount_point); return -1; + } flags = fsinfo.mount_flags | MS_REMOUNT; flags &= ~((unsigned long)MS_RDONLY); ret = mount(fsinfo.fsdev, fsinfo.mount_point, fsinfo.fstype, flags, fsinfo.mount_opts); - if (ret) + if (ret) { + pcv("unmounted %s, mounted R/O, but cannot re-mount it R/W", + fsinfo.mount_point); return -1; + } } } @@ -2316,15 +2338,20 @@ static int remount_tested_fs(void) flags = fsinfo.mount_flags | MS_RDONLY | MS_REMOUNT; ret = mount(fsinfo.fsdev, fsinfo.mount_point, fsinfo.fstype, flags, fsinfo.mount_opts); - if (ret) + if (ret) { + pcv("cannot re-mount %s R/O (3)", fsinfo.mount_point); return -1; + } flags = fsinfo.mount_flags | MS_REMOUNT; flags &= ~((unsigned long)MS_RDONLY); ret = mount(fsinfo.fsdev, fsinfo.mount_point, fsinfo.fstype, flags, fsinfo.mount_opts); - if (ret) + if (ret) { + pcv("remounted %s R/O (3), but cannot re-mount it back R/W", + fsinfo.mount_point); return -1; + } } /* Restore the previous working directory */ @@ -2664,9 +2691,91 @@ static void free_fs_info(struct dir_info *dir) } } +/** + * Recover the tested file-system from an emulated power cut failure by + * unmounting it and mounting it again. + */ +static int recover_tested_fs(void) +{ + char *wd_save; + int ret; + unsigned long flags; + unsigned int 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 */ + um_rorw = rand() & 1; + rorw2 = rand() & 1; + + CHECK(umount(fsinfo.mount_point) != -1); + + if (!um_rorw) { + ret = mount(fsinfo.fsdev, fsinfo.mount_point, + fsinfo.fstype, fsinfo.mount_flags, + fsinfo.mount_opts); + if (ret) { + pcv("unmounted %s, but cannot mount it back R/W", + fsinfo.mount_point); + return -1; + } + } else { + ret = mount(fsinfo.fsdev, fsinfo.mount_point, + fsinfo.fstype, fsinfo.mount_flags | MS_RDONLY, + fsinfo.mount_opts); + if (ret) { + pcv("unmounted %s, but cannot mount it back R/O", + fsinfo.mount_point); + return -1; + } + + flags = fsinfo.mount_flags | MS_REMOUNT; + flags &= ~((unsigned long)MS_RDONLY); + ret = mount(fsinfo.fsdev, fsinfo.mount_point, + fsinfo.fstype, flags, fsinfo.mount_opts); + if (ret) { + pcv("unmounted %s, mounted R/O, but cannot re-mount it R/W", + fsinfo.mount_point); + return -1; + } + } + + if (rorw2) { + flags = fsinfo.mount_flags | MS_RDONLY | MS_REMOUNT; + ret = mount(fsinfo.fsdev, fsinfo.mount_point, fsinfo.fstype, + flags, fsinfo.mount_opts); + if (ret) { + pcv("cannot re-mount %s R/O", fsinfo.mount_point); + return -1; + } + + flags = fsinfo.mount_flags | MS_REMOUNT; + flags &= ~((unsigned long)MS_RDONLY); + ret = mount(fsinfo.fsdev, fsinfo.mount_point, fsinfo.fstype, + flags, fsinfo.mount_opts); + if (ret) { + pcv("remounted %s R/O, but cannot re-mount it back R/W", + fsinfo.mount_point); + return -1; + } + } + + /* Restore the previous working directory */ + CHECK(chdir(wd_save) == 0); + free(wd_save); + return 0; +} + int main(int argc, char *argv[]) { int ret; + unsigned long long restart_count = 0; ret = parse_opts(argc, argv); if (ret) @@ -2703,11 +2812,27 @@ int main(int argc, char *argv[]) * testing mode. Re-mount the file-system and re-start the * test. */ + if (args.verbose) + normsg("re-mount the FS and re-start - count %llu", + ++restart_count); + close_open_files(); free_fs_info(top_dir); - ret = remount_tested_fs(); - if (ret) - break; + + do { + ret = recover_tested_fs(); + if (ret) { + if (errno != EROFS) + goto out_free; + /* + * Mount may also fail due to an emulated power + * cut while mounting - keep re-starting. + */ + if (args.verbose) + normsg("could not mount, restart - count %llu", + ++restart_count); + } + } while (ret); } close_open_files(); -- cgit v1.2.3