\- simple tool to migrate files between Lustre OSTs
.SH SYNOPSIS
.B lfs_migrate
+.RB [ -c <stripe_count> ]
.RB [ -h ]
.RB [ -l ]
.RB [ -n ]
+.RB [ -q ]
.RB [ -R ]
.RB [ -s ]
.RB [ -y ]
or OST index of a new file).
.SH OPTIONS
.TP
+.B \\-c <stripe_count>
+Restripe file using the specified stripe count. This option may not be
+specified at the same time as the -R option.
+.TP
.B \\-h
Display help information.
.TP
.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 option.
.TP
.B \\-s
skip file data comparison after migrate. Default is to compare migrated file
To rebalance all files within
.IR /mnt/lustre/dir :
.IP
-lfs_migrate /mnt/lustre/file
+lfs_migrate /mnt/lustre/dir
.PP
To migrate files within the
.I /test
usage() {
cat -- <<USAGE 1>&2
-usage: lfs_migrate [-h] [-l] [-n] [-R] [-s] [-y] [file|dir ...]
+usage: lfs_migrate [-c <stripe_count>] [-h] [-l] [-n] [-q] [-R] [-s] [-y]
+ [file|dir ...]
+ -c <stripe_count>
+ restripe file using the specified stripe count
-h show this usage message
-l migrate files with hard links (skip by default)
-n only print the names of files to be migrated
-s skip file data comparison after migrate
-y answer 'y' to usage question
+The -c <stripe_count> option may not be specified at the same time as
+the -R option.
+
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/file
+e.g.: lfs_migrate /mnt/lustre/dir
lfs find /test -O test-OST0004 -size +4G | lfs_migrate -y
USAGE
exit 1
}
OPT_CHECK=y
+OPT_STRIPE_COUNT=""
-while getopts "chlnqRsy" opt $*; do
+while getopts "c:hlnqRsy" opt $*; do
case $opt in
- c) echo "'-c' option deprecated, checking enabled by default" 1>&2;;
+ c) OPT_STRIPE_COUNT=$OPTARG;;
l) OPT_NLINK=y;;
n) OPT_DRYRUN=n; OPT_YES=y;;
q) ECHO=:;;
done
shift $((OPTIND - 1))
+if [ "$OPT_STRIPE_COUNT" -a "$OPT_RESTRIPE" ]; then
+ echo ""
+ echo "$(basename $0) error: The -c <stripe_count> option may not" 1>&2
+ echo "be specified at the same time as the -R option." 1>&2
+ exit 1
+fi
+
if [ -z "$OPT_YES" ]; then
echo ""
echo "lfs_migrate is currently NOT SAFE for moving in-use files." 1>&2
# (i.e. before the file data, so that it preserves striping)
# then we don't need to do this getstripe/mktemp stuff.
UNLINK="-u"
- COUNT=$($LFS getstripe -c "$OLDNAME" 2> /dev/null)
+
+ [ "$OPT_STRIPE_COUNT" ] && COUNT=$OPT_STRIPE_COUNT ||
+ COUNT=$($LFS getstripe -c "$OLDNAME" \
+ 2> /dev/null)
SIZE=$($LFS getstripe -S "$OLDNAME" 2> /dev/null)
+
[ -z "$COUNT" -o -z "$SIZE" ] && UNLINK=""
fi
NEWNAME=$(mktemp $UNLINK "$OLDNAME.tmp.XXXXXX")
}
run_test 56v "check 'lfs find -mdt match with lfs getstripe -M' ======="
+# Get and check the actual stripe count of one file.
+# Usage: check_stripe_count <file> <expected_stripe_count>
+check_stripe_count() {
+ local file=$1
+ local expected=$2
+ local actual
+
+ [[ -z "$file" || -z "$expected" ]] &&
+ error "check_stripe_count: invalid argument!"
+
+ local cmd="$GETSTRIPE -c $file"
+ actual=$($cmd) || error "$cmd failed"
+ actual=${actual%% *}
+
+ if [[ $actual -ne $expected ]]; then
+ [[ $expected -eq -1 ]] ||
+ error "$cmd wrong: found $actual, expected $expected"
+ [[ $actual -eq $OSTCOUNT ]] ||
+ error "$cmd wrong: found $actual, expected $OSTCOUNT"
+ fi
+}
+
+test_56w() {
+ TDIR=$DIR/${tdir}w
+
+ rm -rf $TDIR || error "remove $TDIR failed"
+ setup_56 $NUMFILES $NUMDIRS "-c $OSTCOUNT"
+
+ local stripe_size
+ stripe_size=$($GETSTRIPE -S -d $TDIR) ||
+ error "$GETSTRIPE -S -d $TDIR failed"
+ stripe_size=${stripe_size%% *}
+
+ local file_size=$((stripe_size * OSTCOUNT))
+ local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
+ local required_space=$((file_num * file_size))
+ local free_space=$($LCTL get_param -n lov.$LOVNAME.kbytesavail)
+ [[ $free_space -le $((required_space / 1024)) ]] &&
+ skip_env "need at least $required_space bytes free space," \
+ "have $free_space kbytes" && return
+
+ local dd_bs=65536
+ local dd_count=$((file_size / dd_bs))
+
+ # write data into the files
+ local i
+ local j
+ local file
+ for i in $(seq 1 $NUMFILES); do
+ file=$TDIR/file$i
+ yes | dd bs=$dd_bs count=$dd_count of=$file >/dev/null 2>&1 ||
+ error "write data into $file failed"
+ done
+ for i in $(seq 1 $NUMDIRS); do
+ for j in $(seq 1 $NUMFILES); do
+ file=$TDIR/dir$i/file$j
+ yes | dd bs=$dd_bs count=$dd_count of=$file \
+ >/dev/null 2>&1 ||
+ error "write data into $file failed"
+ done
+ done
+
+ local expected=-1
+ [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
+
+ # lfs_migrate file
+ local cmd="$LFS_MIGRATE -y -c $expected $TDIR/file1"
+ echo "$cmd"
+ eval $cmd || error "$cmd failed"
+
+ check_stripe_count $TDIR/file1 $expected
+
+ # lfs_migrate dir
+ cmd="$LFS_MIGRATE -y -c $expected $TDIR/dir1"
+ echo "$cmd"
+ eval $cmd || error "$cmd failed"
+
+ for j in $(seq 1 $NUMFILES); do
+ check_stripe_count $TDIR/dir1/file$j $expected
+ done
+
+ # lfs_migrate works with lfs find
+ cmd="$LFIND -stripe_count $OSTCOUNT -type f $TDIR |
+ $LFS_MIGRATE -y -c $expected"
+ echo "$cmd"
+ eval $cmd || error "$cmd failed"
+
+ for i in $(seq 2 $NUMFILES); do
+ check_stripe_count $TDIR/file$i $expected
+ done
+ for i in $(seq 2 $NUMDIRS); do
+ for j in $(seq 1 $NUMFILES); do
+ check_stripe_count $TDIR/dir$i/file$j $expected
+ done
+ done
+}
+run_test 56w "check lfs_migrate -c stripe_count works"
+
test_57a() {
# note test will not do anything if MDS is not local
remote_mds_nodsh && skip "remote MDS with nodsh" && return
[ ! -f "$TUNEFS" ] && export TUNEFS=$(which tunefs.lustre)
export CHECKSTAT="${CHECKSTAT:-"checkstat -v"} "
export LUSTRE_RMMOD=${LUSTRE_RMMOD:-$LUSTRE/scripts/lustre_rmmod}
- [ ! -f "$LUSTRE_RMMOD" ] && export LUSTRE_RMMOD=$(which lustre_rmmod 2> /dev/null)
+ [ ! -f "$LUSTRE_RMMOD" ] &&
+ export LUSTRE_RMMOD=$(which lustre_rmmod 2> /dev/null)
+ export LFS_MIGRATE=${LFS_MIGRATE:-$LUSTRE/scripts/lfs_migrate}
+ [ ! -f "$LFS_MIGRATE" ] &&
+ export LFS_MIGRATE=$(which lfs_migrate 2> /dev/null)
export FSTYPE=${FSTYPE:-"ldiskfs"}
export NAME=${NAME:-local}
export LGSSD=${LGSSD:-"$LUSTRE/utils/gss/lgssd"}