diff options
| author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2011-04-13 16:15:06 +0300 | 
|---|---|---|
| committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2011-04-18 17:44:46 +0300 | 
| commit | 437f5669965286484ae7f9e771f3a3f34e31ded1 (patch) | |
| tree | 1b1cb46b6071ba82acda6b38a1cc3dc446833d37 /tests | |
| parent | 08cfd9d7cacc3c0b97530ad7e13fa8db75e99947 (diff) | |
fs-tests: integck: do not use tests_remount
Implement our own version of 'tests_remount()' instead of depending
on the common implementation.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/fs-tests/integrity/integck.c | 167 | 
1 files changed, 165 insertions, 2 deletions
| diff --git a/tests/fs-tests/integrity/integck.c b/tests/fs-tests/integrity/integck.c index 7a4bcdc..9bf42af 100644 --- a/tests/fs-tests/integrity/integck.c +++ b/tests/fs-tests/integrity/integck.c @@ -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 */ @@ -2060,6 +2160,67 @@ static int integck(void)  }  /* + * 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.   */  static void get_tested_fs_info(void) @@ -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); | 
