From 60c5bc2502591f46260e11db540c0ec2adbc8db8 Mon Sep 17 00:00:00 2001 From: Steve Guminski Date: Thu, 19 Oct 2017 10:52:07 -0400 Subject: [PATCH] LU-8235 scripts: pass unrecognized options to lfs migrate Pass through any unrecognized options to the "lfs migrate" command, allowing the script to support migrate options without any special handling. Add new options "--rsync" and "--no-rsync" to specify how rsync is used as a fallback alternative for the "lfs migrate" command. The "--rsync" option forces the use of rsync instead of lfs migrate, while the "--no-rsync" option prevents falling back to rsync in the case where lfs migrate fails. Add new "--dry-run" option. The current "-n" option for a dry-run duplicates the "-n" option to designate non-block for "lfs migrate". The script's usage of "-n" is therefore deprecated, so that a future patch can instead pass it through. Add new "-v" option to increase verbosity, to help test/debug/monitor what is being done by the script. This option is also passed through to "lfs migrate". Test-Parameters: trivial Signed-off-by: Nathan Dauchy Signed-off-by: Steve Guminski Change-Id: Ia3f56bf528d2ac8155f08d93d01abd8bb9168cc4 Reviewed-on: https://review.whamcloud.com/20621 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: John L. Hammond Reviewed-by: Andreas Dilger --- lustre/doc/lfs_migrate.1 | 47 +++++--- lustre/scripts/lfs_migrate | 292 ++++++++++++++++++++++++++++++++------------- lustre/tests/sanity.sh | 216 +++++++++++++++++++++++++++++++++ 3 files changed, 460 insertions(+), 95 deletions(-) diff --git a/lustre/doc/lfs_migrate.1 b/lustre/doc/lfs_migrate.1 index 8195ea4..892c265 100644 --- a/lustre/doc/lfs_migrate.1 +++ b/lustre/doc/lfs_migrate.1 @@ -1,19 +1,19 @@ -.TH lfs_migrate 1 "Jun 16, 2017" Lustre "utilities" +.TH lfs_migrate 1 "Dec 19, 2017" Lustre "utilities" .SH NAME .B lfs_migrate \- simple tool to migrate files between Lustre OSTs .SH SYNOPSIS .B lfs_migrate -.RB [ -c ] +.RB [ --dry-run ] .RB [ -h ] -.RB [ -n ] +.RB [ --no-rsync | --rsync ] .RB [ -q ] .RB [ -R ] .RB [ -s ] -.RB [ -S ] +.RB [ -v ] .RB [ -y ] .RB [ -0 ] -.RI [ file | "directory ..." ] +.RI [ FILE | DIR ]... .br .SH DESCRIPTION .B lfs_migrate @@ -47,6 +47,17 @@ suitable for use with .BR lfs (1) " find" to locate files on specific OSTs and/or matching other file attributes. .PP +Any options and arguments not explicitly recognized by the script are passed +through to the +.B lfs migrate +command, see +.BR lfs-migrate (1). +To maintain backward compatibility, the \fI-n \fRoption is used by the script +for a dry-run, and is not passed to +.B lfs migrate +as the non-block option. To specify non-block, use the long option +.IR --non-block . +.PP The current file allocation policies on MDS dictate where the new files are placed, taking into account whether specific OSTs have been disabled on the MDS via @@ -58,30 +69,38 @@ directory (potentially changing the stripe count, stripe size, OST pool, or OST index of a new file). .SH OPTIONS .TP -.B \\-c -Restripe file using the specified stripe count. This option may not be -specified at the same time as the -R option. +.B \\--dry-run +Only print the names of files to be migrated. .TP .B \\-h Display help information. .TP -.B \\-n -Only print the names of files to be migrated. +.B \\--no-rsync +Do not fall back to using rsync if +.BR lfs (1) " migrate" " fails." +Cannot be used at the same time as \fI--rsync\fR. .TP .B \\-q Run quietly (don't print filenames or status). .TP +.B \\--rsync +Force rsync to be used instead of +.BR lfs (1) " migrate" . +May not be used at the same time as \fI--no-rsync\fR. +.TP .B \\-R Restripe file using default directory striping instead of keeping striping. -This option may not be specified at the same time as the -c or -S options. +This option may not be specified at the same time as the -c or -S options +(these options are passed through to +.BR "lfs migrate" , +and are therefore not listed here). .TP .B \\-s Skip file data comparison after migrate. Default is to compare migrated file against original to verify correctness. .TP -.B \\-S -Restripe file using the specified stripe size. This option may not be -specified at the same time as the -R option. +.B \\-v +Show verbose debug messages. .TP .B \\-y Answer 'y' to usage warning without prompting (for scripts, use with caution). diff --git a/lustre/scripts/lfs_migrate b/lustre/scripts/lfs_migrate index 0c080b7..6abc0e3 100755 --- a/lustre/scripts/lfs_migrate +++ b/lustre/scripts/lfs_migrate @@ -16,10 +16,9 @@ RSYNC=${RSYNC:-rsync} LFS_MIGRATE_RSYNC_MODE=${LFS_MIGRATE_RSYNC_MODE:-false} ECHO=echo LFS=${LFS:-lfs} -LFS_MIGRATE_RSYNC=${LFS_MIGRATE_RSYNC:-false} RSYNC_WITH_HLINKS=false LFS_MIGRATE_TMP=${TMPDIR:-/tmp} -MIGRATED_SET="$(mktemp ${LFS_MIGRATE_TMP}/lfs_migrate-$$.links.XXXXXX)" +MIGRATED_SET="$(mktemp ${LFS_MIGRATE_TMP}/lfs_migrate.links.XXXXXX)" NEWNAME="" REMOVE_FID='s/^\[[0-9a-fx:]*\] //' @@ -45,27 +44,33 @@ old_fid_in_set() { usage() { cat -- <&2 -usage: lfs_migrate [-c ] [-h] [-n] [-q] [-R] [-s] - [-S ] [-y] [-0] [file|dir ...] - -c - restripe file using the specified stripe count - -h show this usage message - -n only print the names of files to be migrated - -q run quietly (don't print filenames or status) - -R restripe file using default directory striping - -s skip file data comparison after migrate - -S - restripe file using the specified stripe size - -y answer 'y' to usage question - -0 input file names on stdin are separated by a null character +usage: lfs_migrate [--dry-run] [-h] [--no-rsync|--rsync] [-q] [-R] [-s] + [-v] [-y] [-0] [FILE|DIR...] + --dry-run only print the names of files to be migrated + -h show this usage message + --no-rsync do not fall back to rsync mode even if lfs migrate fails + -q run quietly (don't print filenames or status) + --rsync force rsync mode instead of using lfs migrate + -R restripe file using default directory striping + -s skip file data comparison after migrate + -v show verbose debug messages + -y answer 'y' to usage question + -0 input file names on stdin are separated by a null character The -c and -S options may not be specified at the same time as the -R option. +The --rsync and --no-rsync options may not be specified at the same time. + If a directory is an argument, all files in the directory are migrated. If no file/directory is given, the file list is read from standard input. -e.g.: lfs_migrate /mnt/lustre/dir +Any arguments that are not explicitly recognized by the script are passed +through to the 'lfs migrate' utility. + +Examples: + lfs_migrate /mnt/lustre/dir + lfs_migrate -p newpool /mnt/lustre/dir lfs find /test -O test-OST0004 -size +4G | lfs_migrate -y USAGE exit 1 @@ -78,35 +83,124 @@ cleanup() { trap cleanup EXIT -OPT_CHECK=y -OPT_STRIPE_COUNT="" -OPT_STRIPE_SIZE="" +OPT_CHECK=true +OPT_DEBUG=false +OPT_NO_RSYNC=false +OPT_DRYRUN=false +OPT_YES=false +OPT_RESTRIPE=false +OPT_NULL=false +OPT_PASSTHROUGH=() +STRIPE_COUNT="" +STRIPE_SIZE="" +POOL="" + +# Examine any long options and arguments. getopts does not support long +# options, so they must be stripped out and classified as either options +# for the script, or passed through to "lfs migrate". +LONG_OPT=false +SHORT_OPT=false +OPTS=() + +for f in $(seq 1 $#); do + arg=${!f} + if [ "${arg:0:2}" = "--" ]; then + SHORT_OPT=false + if [ "$arg" = "--block" ]; then + BLOCK="$arg" + OPT_YES=true + elif [ "$arg" = "--non-block" ]; then + BLOCK="$arg" + elif [ "$arg" = "--dry-run" ]; then + OPT_DRYRUN=true + OPT_YES=true + elif [ "$arg" = "--rsync" ]; then + LFS_MIGRATE_RSYNC_MODE=true + elif [ "$arg" = "--no-rsync" ]; then + OPT_NO_RSYNC=true + OPT_YES=true + else + LONG_OPT=true + OPT_PASSTHROUGH+=("$arg") + fi + elif [ "${arg:0:1}" = "-" ]; then + LONG_OPT=false + if [ "$arg" == "-b" ]; then + BLOCK="$arg" + else + SHORT_OPT=true + OPTS+=("$arg") + fi + elif $LONG_OPT; then + LONG_OPT=false + # This will prevent long options from having file name + # arguments, but allows long options with no arguments to work. + if [ -f "$arg" -o -d "$arg" ]; then + OPTS+=("$arg") + else + [ "${OPT_PASSTHROUGH[-1]}" = "--stripe-count" ] && + STRIPE_COUNT="$arg" + [ "${OPT_PASSTHROUGH[-1]}" = "--stripe-size" ] && + STRIPE_SIZE="$arg" + [ "${OPT_PASSTHROUGH[-1]}" = "--pool" ] && + POOL="$arg" + OPT_PASSTHROUGH+=("$arg") + fi + elif $SHORT_OPT; then + [ "${OPTS[-1]}" = "-c" ] && + STRIPE_COUNT="$arg" + [ "${OPTS[-1]}" = "-S" ] && + STRIPE_SIZE="$arg" + [ "${OPTS[-1]}" = "-p" ] && + POOL="$arg" + SHORT_OPT=false + OPTS+=("$arg") + else + OPTS+=("$arg") + fi +done -while getopts "c:hlnqRsS:y0" opt $*; do +# Reset the argument list to include only the short options and file names +set -- "${OPTS[@]}" + +while getopts ":hlnqRsvy0" opt $*; do case $opt in - c) OPT_STRIPE_COUNT=$OPTARG;; + h) usage;; l) ;; # maintained for backward compatibility - n) OPT_DRYRUN=n; OPT_YES=y;; + n) OPT_DRYRUN=true + OPT_YES=true + echo "$(basename $0): -n deprecated, use --dry-run instead" 1>&2 + echo "$(basename $0): to specify non-block, use --non-block instead" 1>&2;; q) ECHO=:;; - R) OPT_RESTRIPE=y;; - s) OPT_CHECK="";; - S) OPT_STRIPE_SIZE=$OPTARG;; - y) OPT_YES=y;; - 0) OPT_NULL=y;; - h|\?) usage;; + R) OPT_RESTRIPE=true;; + s) OPT_CHECK=false;; + v) OPT_DEBUG=true; ECHO=echo; OPT_PASSTHROUGH+=("-v");; + y) OPT_YES=true;; + 0) OPT_NULL=true;; + *) # Pass through any unrecognized options to 'lfs migrate' + OPT_PASSTHROUGH+=("-$OPTARG") + if [[ ${!OPTIND:0:1} != "-" && ! -f "${!OPTIND}" && + ! -d "${!OPTIND}" ]]; then + OPT_PASSTHROUGH+=("${!OPTIND}") + ((OPTIND++)) + fi;; esac done shift $((OPTIND - 1)) -if [ -n "$OPT_STRIPE_COUNT""$OPT_STRIPE_SIZE" -a "$OPT_RESTRIPE" ]; then - echo "" - echo "$(basename $0) error: The -c option and" 1>&2 - echo "-S option may not" 1>&2 - echo "be specified at the same time as the -R option." 1>&2 +if $OPT_RESTRIPE && [[ "$STRIPE_COUNT" || "$STRIPE_SIZE" ]]; then + echo "$(basename $0): Options -c and -S "\ + "may not be specified at the same time as the -R option." 1>&2 exit 1 fi -if [ -z "$OPT_YES" ]; then +if $LFS_MIGRATE_RSYNC_MODE && $OPT_NO_RSYNC; then + echo "$(basename $0): Options --rsync and --no-rsync may not be "\ + "specified at the same time." 1>&2 + exit 1 +fi + +if ! $OPT_YES; then echo "" echo "lfs_migrate is currently NOT SAFE for moving in-use files." 1>&2 echo "Use it only when you are sure migrated files are unused." 1>&2 @@ -135,33 +229,40 @@ umask 0077 lfs_migrate() { while IFS='' read -d '' OLDNAME; do local hlinks=() + local stripe_size="$STRIPE_SIZE" + local stripe_count="$STRIPE_COUNT" + local parent_count="" + local parent_size="" + + $ECHO -n "$OLDNAME: " # avoid duplicate stat if possible - local nlink_type=($(LANG=C stat -c "%h %F" "$OLDNAME" || true)) + local nlink_type=($(LANG=C stat -c "%h %F" "$OLDNAME" \ + 2> /dev/null)) # skip non-regular files, since they don't have any objects # and there is no point in trying to migrate them. if [ "${nlink_type[1]}" != "regular" ]; then - echo -e "$OLDNAME: not a regular file, skipped" + echo -e "\r\e[K$OLDNAME: not a regular file, skipped" continue fi # working out write perms is hard, let the shell do it if [ ! -w "$OLDNAME" ]; then - echo -e "$OLDNAME: no write permission, skipped" + echo -e "\r\e[K$OLDNAME: no write permission, skipped" continue fi - if [ "$OPT_DRYRUN" ]; then - echo -e "$OLDNAME: dry run, skipped" + if $OPT_DRYRUN && ! $OPT_DEBUG; then + $ECHO "dry run, skipped" continue fi # xattrs use absolute file paths, so ensure provided path is # also absolute so that the names can be compared local oldname_absolute=$(readlink -f "$OLDNAME") - if [ $? -ne 0 ]; then - echo -e "$OLDNAME: cannot resolve full path" + if [ -z "$oldname_absolute" ]; then + echo -e "\r\e[K$OLDNAME: cannot resolve full path, skipped" continue fi OLDNAME=$oldname_absolute @@ -170,14 +271,14 @@ lfs_migrate() { # should be replaced with a single call to # "lfs path2links" once that command is available. The logic # for detecting unlisted hard links could then be removed. - local fid=$(lfs path2fid "$OLDNAME" 2> /dev/null) + local fid=$($LFS path2fid "$OLDNAME" 2> /dev/null) if [ $? -ne 0 ]; then - echo -n "$OLDNAME: cannot determine FID; skipping; " + echo -n "\r\e[K$OLDNAME: cannot determine FID; skipping; " echo "is this a Lustre file system?" continue fi - if [[ ${nlink_type[0]} -gt 1 || $RSYNC_WITH_HLINKS == true ]]; then + if [[ ${nlink_type[0]} -gt 1 ]] || $RSYNC_WITH_HLINKS; then # don't migrate a hard link if it was already migrated if path_in_set "$OLDNAME"; then $ECHO -e "$OLDNAME: already migrated via another hard link" @@ -192,7 +293,7 @@ lfs_migrate() { local migrated=$(old_fid_in_set "$fid") if [ -n "$migrated" ]; then $ECHO -e "$OLDNAME: already migrated via another hard link" - if [[ $LFS_MIGRATE_RSYNC == true ]]; then + if $LFS_MIGRATE_RSYNC_MODE; then # Only the rsync case has to relink. # The lfs migrate case preserves the # inode so the links are already @@ -205,7 +306,7 @@ lfs_migrate() { fi fi - if [ "$OPT_RESTRIPE" ]; then + if $OPT_RESTRIPE; then UNLINK="" else # if rsync copies Lustre xattrs properly in the future @@ -213,22 +314,45 @@ lfs_migrate() { # then we don't need to do this getstripe/mktemp stuff. UNLINK="-u" - [ "$OPT_STRIPE_COUNT" ] && - stripe_count=$OPT_STRIPE_COUNT || - stripe_count=$($LFS getstripe -c "$OLDNAME" \ - 2> /dev/null) - [ "$OPT_STRIPE_SIZE" ] && - stripe_size=$OPT_STRIPE_SIZE || - stripe_size=$($LFS getstripe -S \ - "$OLDNAME" 2> /dev/null) - - if [ -z "$stripe_count" -o -z "$stripe_size" ]; then - UNLINK="" - echo -e "$OLDNAME: cannot determine stripe info; skipping" - continue + [ -z "$stripe_count" ] && + stripe_count=$($LFS getstripe -c "$OLDNAME" 2> /dev/null) + + [ -z "$stripe_size" ] && + stripe_size=$($LFS getstripe -S "$OLDNAME" 2> /dev/null) + + [ -z "$stripe_count" -o -z "$stripe_size" ] && UNLINK="" + fi + + if $OPT_DEBUG; then + if $OPT_RESTRIPE; then + parent_count=$($LFS getstripe -c \ + $(dirname "$OLDNAME") 2> \ + /dev/null) + parent_size=$($LFS getstripe -S \ + $(dirname "$OLDNAME") 2> \ + /dev/null) fi - stripe_size="-S$stripe_size" - stripe_count="-c$stripe_count" + + $ECHO -n "stripe" \ + "count=${stripe_count:-$parent_count}," \ + "size=${stripe_size:-$parent_size}," \ + "pool=${POOL:-not in a pool}: " + fi + + if $OPT_DRYRUN; then + $ECHO "dry run, skipped" + continue + fi + + if [[ "$stripe_count" && -z "$STRIPE_COUNT" ]]; then + stripe_count="-c $stripe_count" + else + stripe_count="" + fi + if [[ "$stripe_size" && -z "$STRIPE_SIZE" ]]; then + stripe_size="-S $stripe_size" + else + stripe_size="" fi # detect other hard links and store them on a global @@ -236,56 +360,62 @@ lfs_migrate() { local mntpoint=$(df -P "$OLDNAME" | awk 'NR==2 { print $NF; exit }') if [ -z "$mntpoint" ]; then - echo -e "$OLDNAME: cannot determine mount point; skipping" + echo -e "\r\e[K$OLDNAME: cannot determine mount point; skipped" continue fi - local hlinks=$(lfs fid2path "$mntpoint" "$fid" 2> /dev/null) + hlinks=$($LFS fid2path "$mntpoint" "$fid" 2> /dev/null) if [ $? -ne 0 ]; then - echo -n "$OLDNAME: cannot determine hard link paths" + echo -e "\r\e[K$OLDNAME: cannot determine hard link paths, skipped" continue fi hlinks+=("$OLDNAME") # first try to migrate via Lustre tools, then fall back to rsync - if [[ $LFS_MIGRATE_RSYNC == false ]]; then - if $LFS migrate "$stripe_count" "$stripe_size" "$OLDNAME"; then - $ECHO -e "$OLDNAME: done migrate" + if ! $LFS_MIGRATE_RSYNC_MODE; then + if $LFS migrate "${OPT_PASSTHROUGH[@]}" ${BLOCK} \ + ${stripe_count} ${stripe_size} "$OLDNAME" &> \ + /dev/null; then + $ECHO "done migrate" for link in ${hlinks[*]}; do add_to_set "$fid" "$link" done continue + elif $OPT_NO_RSYNC; then + echo -e "\r\e[K$OLDNAME: refusing to fall back to rsync, skipped" 1>&2 + continue else - echo -e "$OLDNAME: falling back to rsync-based migration" - LFS_MIGRATE_RSYNC=true + $ECHO -n "falling back to rsync: " + LFS_MIGRATE_RSYNC_MODE=true fi fi NEWNAME=$(mktemp $UNLINK "$OLDNAME-lfs_migrate.tmp.XXXXXX") if [ $? -ne 0 -o -z "$NEWNAME" ]; then - echo -e "$OLDNAME: can't make temp file, skipped" 1>&2 + echo -e "\r\e[K$OLDNAME: can't make temp file, skipped" 1>&2 continue fi - [ "$UNLINK" ] && $LFS setstripe ${stripe_count} \ - ${stripe_size} "$NEWNAME" + [ "$UNLINK" ] && $LFS setstripe ${OPT_PASSTHROUGH} \ + ${stripe_count} ${stripe_size} \ + "$NEWNAME" &> /dev/null # we use --inplace, since we created our own temp file already if ! $RSYNC -a --inplace $RSYNC_OPTS "$OLDNAME" "$NEWNAME";then - echo -e "$OLDNAME: copy error, exiting" 1>&2 + echo -e "\r\e[K$OLDNAME: copy error, exiting" 1>&2 exit 4 fi - if [ "$OPT_CHECK" ] && ! cmp -s "$OLDNAME" "$NEWNAME"; then - echo -e "$NEWNAME: compare failed, exiting" 1>&2 + if $OPT_CHECK && ! cmp -s "$OLDNAME" "$NEWNAME"; then + echo -e "\r\e[K$NEWNAME: compare failed, exiting" 1>&2 exit 8 fi if ! mv "$NEWNAME" "$OLDNAME"; then - echo -e "$OLDNAME: rename error, exiting" 1>&2 + echo -e "\r\e[K$OLDNAME: rename error, exiting" 1>&2 exit 12 fi - $ECHO -e "$OLDNAME: done migrate via rsync" + $ECHO "done migrate via rsync" for link in ${hlinks[*]}; do if [ "$link" != "$OLDNAME" ]; then ln -f "$OLDNAME" "$link" @@ -303,7 +433,7 @@ lfs_migrate() { } if [ "$#" -eq 0 ]; then - if [ "$OPT_NULL" ]; then + if $OPT_NULL; then lfs_migrate else tr '\n' '\0' | lfs_migrate @@ -311,11 +441,11 @@ if [ "$#" -eq 0 ]; then else while [ "$1" ]; do if [ -d "$1" ]; then - $LFS find "$1" -type f -print0 | lfs_migrate + $LFS find "$1" -type f -print0 else - echo -en "$1\0" | lfs_migrate + echo -en "$1\0" fi shift - done + done | lfs_migrate fi diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index ddae93b..abe92e9 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -5162,6 +5162,222 @@ test_56w() { } run_test 56w "check lfs_migrate -c stripe_count works" +test_56wb() { + local file1=$DIR/$tdir/file1 + local create_pool=false + local initial_pool=$($LFS getstripe -p $DIR) + local pool_list=() + local pool="" + + echo -n "Creating test dir..." + test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir" + echo "done." + + echo -n "Creating test file..." + touch $file1 || error "cannot create file" + echo "done." + + echo -n "Detecting existing pools..." + while IFS='' read thispool; do + pool_list+=("$thispool") + done < <($LFS pool_list $MOUNT | awk -F '.' 'NR>=2 { print $2 }') + + if [ ${#pool_list[@]} -gt 0 ]; then + echo "${pool_list[@]}" + for thispool in "${pool_list[@]}"; do + if [[ -z "$initial_pool" || + "$initial_pool" != "$thispool" ]]; then + pool="$thispool" + echo "Using existing pool '$pool'" + break + fi + done + else + echo "none detected." + fi + if [ -z "$pool" ]; then + pool=${POOL:-testpool} + [ "$initial_pool" = "$pool" ] && pool="testpool2" + echo -n "Creating pool '$pool'..." + create_pool=true + pool_add $pool &> /dev/null || + error "pool_add failed" + echo "done." + + echo -n "Adding target to pool..." + pool_add_targets $pool 0 0 1 &> /dev/null || + error "pool_add_targets failed" + echo "done." + fi + + echo -n "Setting pool using -p option..." + $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null || + error "migrate failed rc = $?" + echo "done." + + echo -n "Verifying test file is in pool after migrating..." + [ "$($LFS getstripe -p $file1)" = $pool ] || + error "file was not migrated to pool $pool" + echo "done." + + echo -n "Removing test file from pool '$pool'..." + $LFS migrate $file1 &> /dev/null || + error "cannot remove from pool" + [ "$($LFS getstripe -p $file1)" ] && + error "pool still set" + echo "done." + + echo -n "Setting pool using --pool option..." + $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null || + error "migrate failed rc = $?" + echo "done." + + # Clean up + rm -f $file1 + if $create_pool; then + destroy_test_pools 2> /dev/null || + error "destroy test pools failed" + fi +} +run_test 56wb "check lfs_migrate pool support" + +test_56wc() { + local file1="$DIR/$tdir/file 1" + + echo -n "Creating test dir..." + test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir" + $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null || + error "cannot set stripe" + echo "done" + + echo -n "Setting initial stripe for test file..." + $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null || + error "cannot set stripe" + [ $($LFS getstripe -S "$file1") -eq 524288 ] || + error "stripe size not set" + echo "done." + + # File currently set to -S 512K -c 1 + + # Ensure -c and -S options are rejected when -R is set + echo -n "Verifying incompatible options are detected..." + $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null && + error "incompatible -c and -R options not detected" + $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null && + error "incompatible -S and -R options not detected" + echo "done." + + # Ensure unrecognized options are passed through to 'lfs migrate' + echo -n "Verifying -S option is passed through to lfs migrate..." + $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null || + error "migration failed" + [ $($LFS getstripe -S "$file1") -eq 1048576 ] || + error "file was not restriped" + echo "done." + + # File currently set to -S 1M -c 1 + + # Ensure long options are supported + echo -n "Verifying long options supported..." + $LFS_MIGRATE -y --non-block "$file1" &> /dev/null || + error "long option without argument not supported" + $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null || + error "long option with argument not supported" + [ $($LFS getstripe -S "$file1") -eq 524288 ] || + error "file not restriped with --stripe-size option" + echo "done." + + # File currently set to -S 512K -c 1 + + if [ "$OSTCOUNT" -gt 1 ]; then + echo -n "Verifying explicit stripe count can be set..." + $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null || + error "migrate failed" + [ $($LFS getstripe -c "$file1") -eq 2 ] || + error "file not restriped to explicit count" + echo "done." + fi + + # File currently set to -S 512K -c 1 or -S 512K -c 2 + + # Ensure parent striping is used if -R is set, and no stripe + # count or size is specified + echo -n "Setting stripe for parent directory..." + $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null || + error "cannot set stripe" + echo "done." + + echo -n "Verifying restripe option uses parent stripe settings..." + $LFS_MIGRATE -y -R "$file1" &> /dev/null || + error "migrate failed" + [ $($LFS getstripe -S "$file1") -eq 1048576 ] || + error "file not restriped to parent settings" + [ $($LFS getstripe -c "$file1") -eq 1 ] || + error "file not restriped to parent settings" + echo "done." + + # File currently set to -S 1M -c 1 + + # Ensure striping is preserved if -R is not set, and no stripe + # count or size is specified + echo -n "Verifying striping size preserved when not specified..." + $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null || + error "cannot set stripe on parent directory" + $LFS_MIGRATE -y "$file1" &> /dev/null || + error "migrate failed" + [ $($LFS getstripe -S "$file1") -eq 1048576 ] || + error "file was restriped" + echo "done." + + # Ensure file name properly detected when final option has no argument + echo -n "Verifying file name properly detected..." + $LFS_MIGRATE -y "$file1" &> /dev/null || + error "file name interpreted as option argument" + echo "done." + + # Clean up + rm -f "$file1" +} +run_test 56wc "check unrecognized options for lfs_migrate are passed through" + +test_56wd() { + [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return + local file1=$DIR/$tdir/file1 + + echo -n "Creating test dir..." + test_mkdir $DIR/$tdir || error "cannot create dir" + echo "done." + + echo -n "Creating test file..." + touch $file1 + echo "done." + + # Ensure 'lfs migrate' will fail by using a non-existent option, + # and make sure rsync is not called to recover + echo -n "Make sure --no-rsync option works..." + $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 | + grep -q 'refusing to fall back to rsync' || + error "rsync was called with --no-rsync set" + echo "done." + + # Ensure rsync is called without trying 'lfs migrate' first + echo -n "Make sure --rsync option works..." + $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 | + grep -q 'falling back to rsync' && + error "lfs migrate was called with --rsync set" + echo "done." + + echo -n "Make sure --rsync and --no-rsync options are exclusive..." + $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 | + grep -q 'at the same time' || + error "--rsync and --no-rsync accepted concurrently" + echo "done." + + # Clean up + rm -f $file1 +} +run_test 56wd "check lfs_migrate --rsync and --no-rsync work" + test_56x() { check_swap_layouts_support && return 0 [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs" && return -- 1.8.3.1