MOUNTCONFSKIP="9 10 11 12 13 13b 14 15 18"
# bug number for skipped test:
-ALWAYS_EXCEPT=" $CONF_SANITY_EXCEPT $MOUNTCONFSKIP"
+ALWAYS_EXCEPT=" $CONF_SANITY_EXCEPT $MOUNTCONFSKIP 23"
# UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
SRCDIR=`dirname $0`
}
run_test 19b "start/stop OSTs without MDS"
-test_20a() {
+test_20() {
+ # first format the ost/mdt
+ start_ost
+ start_mds
+ mount_client $MOUNT
+ check_mount || return 43
+ rm -f $DIR/$tfile
+ remount_client ro $MOUNT || return 44
+ touch $DIR/$tfile && echo "$DIR/$tfile created incorrectly" && return 45
+ [ -e $DIR/$tfile ] && echo "$DIR/$tfile exists incorrectly" && return 46
+ remount_client rw $MOUNT || return 47
+ touch $DIR/$tfile
+ [ ! -f $DIR/$tfile ] && echo "$DIR/$tfile missing" && return 48
+ MCNT=`grep -c $MOUNT /etc/mtab`
+ [ "$MCNT" -ne 1 ] && echo "$MOUNT in /etc/mtab $MCNT times" && return 49
+ umount_client $MOUNT
+ stop_mds
+ stop_ost
+}
+run_test 20 "remount ro,rw mounts work and doesn't break /etc/mtab"
+
+test_21a() {
start_mds
start_ost
stop_ost
stop_mds
}
-run_test 20a "start mds before ost, stop ost first"
+run_test 21a "start mds before ost, stop ost first"
-test_20b() {
+test_21b() {
start_ost
start_mds
stop_mds
stop_ost
}
-run_test 20b "start ost before mds, stop mds first"
+run_test 21b "start ost before mds, stop mds first"
-test_20c() {
+test_21c() {
start_ost
start_mds
start_ost2
stop_ost2
stop_mds
}
-run_test 20c "start mds between two osts, stop mds last"
+run_test 21c "start mds between two osts, stop mds last"
-test_21() {
+test_22() {
reformat
start_mds
echo Client mount before any osts are in the logs
cleanup
}
-run_test 21 "start a client before osts (should return errs)"
+run_test 22 "start a client before osts (should return errs)"
-test_22() {
- echo this test is not working yet
- return 0
+test_23() {
setup
- # failover mds
+ # fail mds
stop mds
- # force client so that recovering mds waits
+ # force down client so that recovering mds waits for reconnect
zconf_umount `hostname` $MOUNT -f
# enter recovery on mds
start_mds
+ # try to start a new client
mount_client $MOUNT &
- local mount_pid=$?
+ MOUNT_PID=$!
sleep 5
- local mount_lustre_pid=`ps -ef | grep mount.lustre | grep -v grep | awk '{print $2}'`
- ps -ef | grep mount
- echo mount pid is ${mount_pid}, mount.lustre pid is ${mount_lustre_pid}
+ MOUNT_LUSTRE_PID=`ps -ef | grep mount.lustre | grep -v grep | awk '{print $2}'`
+ echo mount pid is ${MOUNT_PID}, mount.lustre pid is ${MOUNT_LUSTRE_PID}
+ ps --ppid $MOUNT_PID
+ ps --ppid $MOUNT_LUSTRE_PID
# why o why can't I kill these? Manual "ctrl-c" works...
- kill -2 ${mount_pid}
+ kill -TERM $MOUNT_PID
+ echo "waiting for mount to finish"
ps -ef | grep mount
- kill -2 ${mount_lustre_pid}
- ps -ef | grep mount
- sleep 5
- exit 1 # the mount process is still running??
+ wait $MOUNT_PID
+
stop_mds
stop_ost
}
-run_test 22 "interrupt client during recovery mount delay"
+run_test 23 "interrupt client during recovery mount delay"
umount_client $MOUNT
cleanup_nocli
-test_20() {
- # first format the ost/mdt
- start_ost
- start_mds
- mount_client $MOUNT
- check_mount || return 43
- rm -f $DIR/$tfile
- remount_client ro $MOUNT || return 44
- touch $DIR/$tfile && echo "$DIR/$tfile created incorrectly" && return 45
- [ -e $DIR/$tfile ] && echo "$DIR/$tfile exists incorrectly" && return 46
- remount_client rw $MOUNT || return 47
- touch $DIR/$tfile
- [ ! -f $DIR/$tfile ] && echo "$DIR/$tfile missing" && return 48
- MCNT=`grep -c $MOUNT /etc/mtab`
- [ "$MCNT" -ne 1 ] && echo "$MOUNT in /etc/mtab $MCNT times" && return 49
- umount_client $MOUNT
- stop_mds
- stop_ost
-}
-run_test 20 "remount ro,rw mounts work and doesn't break /etc/mtab"
-
equals_msg "Done"
FILE *fp;
struct mntent *mnt;
- if (force)
- return (0);
-
fp = setmntent(MOUNTED, "r");
if (fp == NULL)
return(0);
strcmp(mnt->mnt_dir, mtpt) == 0 &&
strcmp(mnt->mnt_type, type) == 0) {
endmntent(fp);
- fprintf(stderr, "%s: according to %s %s is "
- "already mounted on %s\n",
- progname, MOUNTED, spec, mtpt);
return(EEXIST);
}
}
****************************************************************************/
struct opt_map {
const char *opt; /* option name */
- int skip; /* skip in mtab option string */
+ int skip; /* don't pass this option to Lustre */
int inv; /* true if flag value should be inverted */
int mask; /* flag mask value */
};
static const struct opt_map opt_map[] = {
+ /*"optname",skip,inv,ms_mask */
/* These flags are parsed by mount, not lustre */
- { "defaults", 0, 0, 0 }, /* default options */
+ { "defaults", 1, 0, 0 }, /* default options */
+ { "remount", 1, 0, MS_REMOUNT}, /* remount with different options */
{ "rw", 1, 1, MS_RDONLY }, /* read-write */
- { "ro", 0, 0, MS_RDONLY }, /* read-only */
- { "exec", 0, 1, MS_NOEXEC }, /* permit execution of binaries */
- { "noexec", 0, 0, MS_NOEXEC }, /* don't execute binaries */
- { "suid", 0, 1, MS_NOSUID }, /* honor suid executables */
- { "nosuid", 0, 0, MS_NOSUID }, /* don't honor suid executables */
- { "dev", 0, 1, MS_NODEV }, /* interpret device files */
- { "nodev", 0, 0, MS_NODEV }, /* don't interpret devices */
- { "async", 0, 1, MS_SYNCHRONOUS}, /* asynchronous I/O */
- { "auto", 0, 0, 0 }, /* Can be mounted using -a */
- { "noauto", 0, 0, 0 }, /* Can only be mounted explicitly */
- { "nousers", 0, 1, 0 }, /* Forbid ordinary user to mount */
- { "nouser", 0, 1, 0 }, /* Forbid ordinary user to mount */
- { "noowner", 0, 1, 0 }, /* Device owner has no special privs */
- { "_netdev", 0, 0, 0 }, /* Device accessible only via network */
- /* These strings are passed through and parsed in lustre ll_options */
+ { "ro", 1, 0, MS_RDONLY }, /* read-only */
+ { "exec", 1, 1, MS_NOEXEC }, /* permit execution of binaries */
+ { "noexec", 1, 0, MS_NOEXEC }, /* don't execute binaries */
+ { "suid", 1, 1, MS_NOSUID }, /* honor suid executables */
+ { "nosuid", 1, 0, MS_NOSUID }, /* don't honor suid executables */
+ { "dev", 1, 1, MS_NODEV }, /* interpret device files */
+ { "nodev", 1, 0, MS_NODEV }, /* don't interpret devices */
+ { "async", 1, 1, MS_SYNCHRONOUS}, /* asynchronous I/O */
+ { "auto", 1, 0, 0 }, /* Can be mounted using -a */
+ { "noauto", 1, 0, 0 }, /* Can only be mounted explicitly */
+ { "nousers", 1, 1, 0 }, /* Forbid ordinary user to mount */
+ { "nouser", 1, 1, 0 }, /* Forbid ordinary user to mount */
+ { "noowner", 1, 1, 0 }, /* Device owner has no special privs */
+ { "_netdev", 1, 0, 0 }, /* Device accessible only via network */
+ /* These flags are passed through and parsed in lustre ll_options */
{ "flock", 0, 0, 0 }, /* Enable flock support */
- { "noflock", 1, 1, 0 }, /* Disable flock support */
+ { "noflock", 0, 1, 0 }, /* Disable flock support */
{ "user_xattr", 0, 0, 0 }, /* Enable get/set user xattr */
- { "nouser_xattr", 1, 1, 0 }, /* Disable user xattr */
+ { "nouser_xattr", 0, 1, 0 }, /* Disable user xattr */
{ "acl", 0, 0, 0 }, /* Enable ACL support */
- { "noacl", 1, 1, 0 }, /* Disable ACL support */
+ { "noacl", 0, 1, 0 }, /* Disable ACL support */
{ "nosvc", 0, 0, 0 }, /* Only start MGS/MGC, nothing else */
{ "exclude", 0, 0, 0 }, /* OST exclusion list */
{ "abort_recov", 0, 0, 0 }, /* Abort recovery */
};
/****************************************************************************/
-/* 1 = found, flag set
- 0 = found, no flag set
+/* 1 = found, skip
+ 0 = found, no skip
-1 = not found in above list */
static int parse_one_option(const char *check, int *flagp)
{
for (opt = &opt_map[0]; opt->opt != NULL; opt++) {
if (strncmp(check, opt->opt, strlen(opt->opt)) == 0) {
- if (!opt->mask)
- return 0;
- if (opt->inv)
- *flagp &= ~(opt->mask);
- else
- *flagp |= opt->mask;
- return 1;
+ if (opt->mask) {
+ if (opt->inv)
+ *flagp &= ~(opt->mask);
+ else
+ *flagp |= opt->mask;
+ }
+ return opt->skip;
}
}
fprintf(stderr, "%s: ignoring unknown option '%s'\n", progname,
return -1;
}
+/* Replace options with subset of Lustre-specific options, and
+ fill in mount flags */
int parse_options(char *orig_options, int *flagp)
{
char *options, *opt, *nextopt;
/* empty option */
continue;
if (parse_one_option(opt, flagp) == 0) {
- /* no mount flags set, so pass this on as an option */
+ /* pass this on as an option */
if (*options)
strcat(options, ",");
strcat(options, opt);
}
}
- /* options will always be <= orig_options */
strcpy(orig_options, options);
free(options);
return 0;
int main(int argc, char *const argv[])
{
char default_options[] = "";
- char *source, *target, *options = default_options, *optcopy;
+ char *source, *target;
+ char *options, *optcopy, *orig_options = default_options;
int i, nargs = 3, opt, rc, flags, optlen;
static struct option long_opt[] = {
{"fake", 0, 0, 'f'},
nargs++;
break;
case 'o':
- options = optarg;
+ orig_options = optarg;
nargs++;
break;
case 'v':
++verbose;
- printf("verbose: %d\n", verbose);
nargs++;
break;
default:
usage(stderr);
}
- if (verbose > 1) {
+ if (verbose) {
for (i = 0; i < argc; i++)
printf("arg[%d] = %s\n", i, argv[i]);
printf("source = %s, target = %s\n", source, target);
+ printf("options = %s\n", orig_options);
}
- if (!force && check_mtab_entry(source, target, "lustre"))
- return(EEXIST);
-
+ options = malloc(strlen(orig_options) + 1);
+ strcpy(options, orig_options);
rc = parse_options(options, &flags);
if (rc) {
fprintf(stderr, "%s: can't parse options: %s\n",
return(EINVAL);
}
+ if (!force) {
+ rc = check_mtab_entry(source, target, "lustre");
+ if (rc && !(flags & MS_REMOUNT)) {
+ fprintf(stderr, "%s: according to %s %s is "
+ "already mounted on %s\n",
+ progname, MOUNTED, source, target);
+ return(EEXIST);
+ }
+ if (!rc && (flags & MS_REMOUNT)) {
+ fprintf(stderr, "%s: according to %s %s is "
+ "not already mounted on %s\n",
+ progname, MOUNTED, source, target);
+ return(ENOENT);
+ }
+ }
+ if (flags & MS_REMOUNT)
+ nomtab++;
+
rc = access(target, F_OK);
if (rc) {
rc = errno;
fprintf(stderr, "Check the syslog for more info\n");
rc = errno;
} else if (!nomtab) {
- rc = update_mtab_entry(source, target, "lustre", options,0,0,0);
+ rc = update_mtab_entry(source, target, "lustre", orig_options,
+ 0,0,0);
}
free(optcopy);