From 128137adfc539dd2dd92040c14a63ff27f969820 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Thu, 19 Dec 2019 04:51:41 -0700 Subject: [PATCH] LU-13090 utils: fix lfs_migrate -p for file with pool If "lfs_migrate -p " is run to migrate a file with an existing pool, the given pool is overridden by the existing pool from the file during migration. Fix this to use the OST pool requested by the user. Don't print a warning about deprecated -n option if --dry-run is used. If a pool is specified, use it with "lfs df" to find OST free space. Change temp filename to work better with new DNE "crush" hash. Don't return an error if falling back to rsync and no links are found. Add test for "lfs_migrate -p" and update man page and usage to match. Clean up debug-level helpers in test-framework.sh. Test-Parameters: trivial testlist=ost-pools Signed-off-by: Andreas Dilger Change-Id: Ief69a620fc969aeff24ec0633a3314c3b83ebbe5 Reviewed-on: https://review.whamcloud.com/37067 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Emoly Liu Reviewed-by: Jian Yu Reviewed-by: Oleg Drokin --- lustre/doc/lfs_migrate.1 | 6 ++++- lustre/scripts/lfs_migrate | 59 ++++++++++++++++++++++-------------------- lustre/tests/ost-pools.sh | 27 +++++++++++++++++++ lustre/tests/test-framework.sh | 48 ++++++++++++++++++++-------------- 4 files changed, 91 insertions(+), 49 deletions(-) diff --git a/lustre/doc/lfs_migrate.1 b/lustre/doc/lfs_migrate.1 index 1c23476..c706ceb 100644 --- a/lustre/doc/lfs_migrate.1 +++ b/lustre/doc/lfs_migrate.1 @@ -8,6 +8,7 @@ .RB [ --dry-run | -n ] .RB [ --help | -h ] .RB [ --no-rsync | --rsync ] +.RB [ --pool | -p \fI \fR] .RB [ --quiet | -q ] .RB [ --restripe | -R ] .RB [ --stripe-count | -c \fI \fR] @@ -103,7 +104,10 @@ When \fB-A \fRis set, only consider OSTs with free space greater than the \fImin_free \fRvalue to be available for migration. The value is specified in KB. If this option is not set, a default of 256MB is used. .TP -.B \\--quiet|-q +.BR \\--pool | -q \fI +Migrate files to specified pool. +.TP +.BR \\--quiet | -q Run quietly (don't print filenames or status). .TP .B \\--rsync diff --git a/lustre/scripts/lfs_migrate b/lustre/scripts/lfs_migrate index eec337d..939349c 100755 --- a/lustre/scripts/lfs_migrate +++ b/lustre/scripts/lfs_migrate @@ -47,8 +47,8 @@ usage() { cat -- <&2 usage: lfs_migrate [--dry-run|-n] [--help|-h] [--no-rsync|--rsync] [--quiet|-q] [--auto-stripe|-A [-C ] - [--min-free|-M ] [--max-free|-X ]] - [--stripe-count|-c ] + [--min-free|-M ] [--max-free|-X ]] + [--pool|-p ] [--stripe-count|-c ] [--stripe-size|-S ] [-D] [-h] [-n] [-S] [--restripe|-R] [--skip|-s] [--verbose|-v] [--yes|-y] [-0] @@ -67,6 +67,7 @@ usage: lfs_migrate [--dry-run|-n] [--help|-h] [--no-rsync|--rsync] [--quiet|-q] use in the migration --no-rsync do not fall back to rsync mode even if lfs migrate fails -n only print the names of files to be migrated + -p use the specified OST pool for the destination file -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 @@ -116,6 +117,7 @@ OPT_NO_RSYNC=false OPT_NO_DIRECT=false OPT_NULL=false OPT_PASSTHROUGH=() +OPT_POOL="" OPT_RESTRIPE=false OPT_YES=false LFS_OPT_DIRECTIO="" @@ -134,8 +136,10 @@ while [ -n "$*" ]; do case "$arg" in -h|--help) usage;; -l|--link) ;; # maintained backward compatibility for now - -n|--dry-run) OPT_DRYRUN=true; OPT_YES=true + -n) OPT_DRYRUN=true; OPT_YES=true echo "$PROG: -n deprecated, use --dry-run or --non-block" 1>&2;; + --dry-run) OPT_DRYRUN=true; OPT_YES=true;; + -p|--pool) OPT_POOL="$arg $2"; OPT_LAYOUT+="$OPT_POOL "; shift;; -q|--quiet) ECHO=:;; -R|--restripe) OPT_RESTRIPE=true;; -s|--skip) OPT_CHECK=false;; @@ -149,7 +153,7 @@ while [ -n "$*" ]; do --no-rsync) OPT_NO_RSYNC=true;; --copy|--yaml|--file) # these options have files as arguments, pass both through - OPT_LAYOUT+="$arg $2"; shift;; + OPT_LAYOUT+="$arg $2 "; shift;; --auto-stripe|-A) OPT_AUTOSTRIPE=true;; -C) OPT_CAP="$2"; shift;; -D) LFS_OPT_DIRECTIO="-D";; @@ -246,21 +250,18 @@ function calc_stripe() ost_min_kb=$avail fi fi - done < <($LFS df $OLDNAME | awk '/OST/ { print $4 }') - # Once this script supports pools, the lfs df command above - # should also include the -p option to restrict the - # listed OSTs to the correct pool. + done < <($LFS df $OPT_POOL $OLDNAME | awk '/OST/ { print $4 }') if [ $ost_max_count -eq 0 ]; then - echo "no OSTs with sufficient available space" >&2 + # no OSTs with enough space, stripe over all of them + echo "-1" "0" return fi if (( ost_min_kb == (1 << 62) )); then echo "warning: unable to determine minimum OST size, " \ "object size not capped" >&2 - obj_max_kb=0 - echo "$stripe_count" "$obj_max_kb" + echo "$stripe_count" "0" return fi @@ -295,7 +296,7 @@ lfs_migrate() { local stripe_count="$OPT_STRIPE_COUNT" local parent_count="" local parent_size="" - local stripe_pool + local stripe_pool="${OPT_POOL#-p }" local mirror_count local layout local fid @@ -380,8 +381,9 @@ lfs_migrate() { # striping) then we don't need this getstripe stuff. UNLINK="-u" - stripe_pool=$($LFS getstripe -p "$OLDNAME" 2> /dev/null) - mirror_count=$($LFS getstripe -N "$OLDFILE" 2> /dev/null) + [ -n "$OPT_POOL" ] || + stripe_pool=$($LFS getstripe -p "$OLDNAME" 2>/dev/null) + mirror_count=$($LFS getstripe -N "$OLDFILE" 2>/dev/null) if $OPT_AUTOSTRIPE; then local filekb=$((${nlink_type[$nlink_idx_size]} / @@ -392,11 +394,11 @@ lfs_migrate() { [ -z "$stripe_count" ] && exit 1 [ $stripe_count -lt 1 ] && stripe_count=1 else - [ "$OPT_STRIPE_COUNT" ] && stripe_count=$OPT_STRIPE_COUNT || + [ -n "$stripe_count" ] || stripe_count=$($LFS getstripe -c "$OLDNAME" \ 2> /dev/null) fi - [ -z "$stripe_size" ] && + [ -n "$stripe_size" ] || stripe_size=$($LFS getstripe -S "$OLDNAME" 2> /dev/null) [ -z "$stripe_count" -o -z "$stripe_size" ] && UNLINK="" @@ -434,12 +436,13 @@ lfs_migrate() { continue fi - [ -n "$stripe_count" ] && stripe_count="-c $stripe_count" - [ -n "$stripe_size" ] && stripe_size="-S $stripe_size" - [ -n "$stripe_pool" ] && stripe_pool="-p $stripe_pool" - [ -n "$mirror_count" ] && mirror_count="-N $mirror_count" - layout="$stripe_count $stripe_size $stripe_pool $mirror_count \ - $OPT_LAYOUT" + layout="${OPT_PASSTHROUGH[@]} " + [ -n "$stripe_count" ] && layout+="-c $stripe_count " + [ -n "$stripe_size" ] && layout+="-S $stripe_size " + [ -z "$OPT_POOL" -a -n "$stripe_pool" ] && + layout+="-p $stripe_pool " + [ -n "$mirror_count" ] && layout+="-N $mirror_count " + layout+="$OPT_LAYOUT" # detect other hard links and store them on a global # list so we don't re-migrate them @@ -463,8 +466,7 @@ lfs_migrate() { # first try to migrate via Lustre tools, then fall back to rsync if ! $OPT_RSYNC; then - if $LFS migrate "${OPT_PASSTHROUGH[@]}" $layout \ - "$OLDNAME"; then + if $LFS migrate $layout "$OLDNAME"; then $ECHO "done" # no-op if hlinks empty for 1-link files for link in ${hlinks[*]}; do @@ -480,15 +482,16 @@ lfs_migrate() { fi fi - NEWNAME=$(mktemp $UNLINK "$OLDNAME-lfs_migrate.tmp.XXXXXX") + local olddir=$(dirname $OLDNAME) + local oldfile=$(basename $OLDNAME) + NEWNAME=$(mktemp $UNLINK "$olddir/.$oldfile.XXXXXX") if [ $? -ne 0 -o -z "$NEWNAME" ]; then echo -e "\r$OLDNAME: cannot make temp file, skipped" 1>&2 continue fi if [ "$UNLINK" ]; then - if ! $LFS setstripe "${OPT_PASSTHROUGH[@]}" $layout \ - "$NEWNAME"; then + if ! $LFS setstripe $layout "$NEWNAME"; then echo -e "\r$NEWNAME: setstripe failed, exiting" 1>&2 exit 2 fi @@ -524,7 +527,7 @@ lfs_migrate() { # of 1 (all other links will point to the new inode). # This flag indicates that even paths with a link count of # 1 are potentially part of a link set. - [ ${#hlinks[*]} -gt 1 ] && RSYNC_WITH_HLINKS=true + (( ${#hlinks[*]} == 1 )) || RSYNC_WITH_HLINKS=true done } diff --git a/lustre/tests/ost-pools.sh b/lustre/tests/ost-pools.sh index fecd8fc..dde786e 100755 --- a/lustre/tests/ost-pools.sh +++ b/lustre/tests/ost-pools.sh @@ -1558,6 +1558,33 @@ test_27() { } run_test 27 "Race pool_list and pool_remove" +test_28() { + create_pool_nofail $POOL + create_pool_nofail $POOL2 + add_pool $POOL $TGT_ALL "$TGT_UUID" + add_pool $POOL2 $TGT_ALL "$TGT_UUID" + + start_full_debug_logging + #$LFS setstripe -E 4M -c 1 -p $POOL -E 16M -c 2 $DIR/$tfile + $LFS setstripe -c 1 -p $POOL $DIR/$tfile + dd if=/dev/urandom of=$DIR/$tfile bs=1M count=1 seek=16 + local csum=$(cksum $DIR/$tfile) + $LFS getstripe $DIR/$tfile + local pool="$($LFS getstripe -p $DIR/$tfile)" + [[ "$pool" == "$POOL" ]] || + error "$tfile is in '$pool', not created on $POOL" + $LFS_MIGRATE -y -p $POOL2 $DIR/$tfile || + error "migrate $tfile to $POOL2 failed" + $LFS getstripe $DIR/$tfile + pool="$($LFS getstripe -p $DIR/$tfile)" + [[ "$pool" == "$POOL2" ]] || + error "$tfile is in '$pool', not migrated to $POOL2" + local csum2=$(cksum $DIR/$tfile) + [[ "$csum" == "$csum2" ]] || error "checksum error after migration" + stop_full_debug_logging +} +run_test 28 "lfs_migrate with pool name" + cd $ORIG_PWD complete $SECONDS diff --git a/lustre/tests/test-framework.sh b/lustre/tests/test-framework.sh index 27a2251..a1e75c8 100755 --- a/lustre/tests/test-framework.sh +++ b/lustre/tests/test-framework.sh @@ -1552,34 +1552,42 @@ set_debug_size () { } set_default_debug () { - local debug=${1:-"$PTLDEBUG"} - local subsys=${2:-"$SUBSYSTEM"} - local debug_size=${3:-$DEBUG_SIZE} + local debug=${1:-"$PTLDEBUG"} + local subsys=${2:-"$SUBSYSTEM"} + local debug_size=${3:-$DEBUG_SIZE} - [ -n "$debug" ] && lctl set_param debug="$debug" >/dev/null - [ -n "$subsys" ] && lctl set_param subsystem_debug="${subsys# }" >/dev/null + [ -n "$debug" ] && lctl set_param debug="$debug" >/dev/null + [ -n "$subsys" ] && lctl set_param subsystem_debug="${subsys# }" >/dev/null - [ -n "$debug_size" ] && set_debug_size $debug_size > /dev/null + [ -n "$debug_size" ] && set_debug_size $debug_size > /dev/null } set_default_debug_nodes () { local nodes="$1" + local debug="${2:-"$PTLDEBUG"}" + local subsys="${3:-"$SUBSYSTEM"}" + local debug_size="${4:-$DEBUG_SIZE}" if [[ ,$nodes, = *,$HOSTNAME,* ]]; then nodes=$(exclude_items_from_list "$nodes" "$HOSTNAME") set_default_debug fi - do_rpc_nodes "$nodes" set_default_debug \ - \\\"$PTLDEBUG\\\" \\\"$SUBSYSTEM\\\" $DEBUG_SIZE || true + [[ -z "$nodes" ]] || + do_rpc_nodes "$nodes" set_default_debug \ + \\\"$debug\\\" \\\"$subsys\\\" $debug_size || true } set_default_debug_facet () { - local facet=$1 - local node=$(facet_active_host $facet) - [ -z "$node" ] && echo "No host defined for facet $facet" && exit 1 + local facet=$1 + local debug="${2:-"$PTLDEBUG"}" + local subsys="${3:-"$SUBSYSTEM"}" + local debug_size="${4:-$DEBUG_SIZE}" + local node=$(facet_active_host $facet) - set_default_debug_nodes $node + [ -n "$node" ] || error "No host defined for facet $facet" + + set_default_debug_nodes $node "$debug" "$subsys" $debug_size } set_hostid () { @@ -6001,19 +6009,19 @@ debug_size_restore() { } start_full_debug_logging() { - debugsave - debug_size_save + debugsave + debug_size_save - local FULLDEBUG=-1 - local DEBUG_SIZE=150 + local fulldebug=-1 + local debug_size=150 + local nodes=$(comma_list $(nodes_list)) - do_nodes $(comma_list $(nodes_list)) "$LCTL set_param debug_mb=$DEBUG_SIZE" - do_nodes $(comma_list $(nodes_list)) "$LCTL set_param debug=$FULLDEBUG;" + do_nodes $nodes "$LCTL set_param debug=$fulldebug debug_mb=$debug_size" } stop_full_debug_logging() { - debug_size_restore - debugrestore + debug_size_restore + debugrestore } # prints bash call stack -- 1.8.3.1