X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fscripts%2Flfs_migrate;h=e9c8aaeddec4a9f7efac364ad6740accb4cb3293;hb=2c5b57ca3aaf1d27a24bce028220355a005dde3d;hp=065287933b031dea63893c2a5687c354ed7a9b94;hpb=d6fea82d1431ec972c2661fa31223fb62498d953;p=fs%2Flustre-release.git diff --git a/lustre/scripts/lfs_migrate b/lustre/scripts/lfs_migrate old mode 100644 new mode 100755 index 0652879..e9c8aae --- a/lustre/scripts/lfs_migrate +++ b/lustre/scripts/lfs_migrate @@ -17,10 +17,14 @@ set -e RSYNC=${RSYNC:-rsync} ECHO=echo LFS=${LFS:-lfs} +LFS_SIZE_OPT="-s" usage() { cat -- <&2 -usage: lfs_migrate [-h] [-l] [-n] [-R] [-s] [-y] [file|dir ...] +usage: lfs_migrate [-c ] [-h] [-l] [-n] [-q] [-R] [-s] [-y] [-0] + [file|dir ...] + -c + 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 @@ -28,32 +32,45 @@ usage: lfs_migrate [-h] [-l] [-n] [-R] [-s] [-y] [file|dir ...] -R restripe file using default directory striping -s skip file data comparison after migrate -y answer 'y' to usage question + -0 input file names on stdin are separated by a null character + +The -c 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 "chlnRqsSy" opt $*; do +while getopts "c:hlnqRsy0" 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=:;; R) OPT_RESTRIPE=y;; s) OPT_CHECK="";; y) OPT_YES=y;; + 0) OPT_NULL=y;; h|\?) usage;; esac done shift $((OPTIND - 1)) +if [ "$OPT_STRIPE_COUNT" -a "$OPT_RESTRIPE" ]; then + echo "" + echo "$(basename $0) error: The -c 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 @@ -74,12 +91,23 @@ $RSYNC --help 2>&1 | grep -q acls && RSYNC_OPTS="$RSYNC_OPTS -A" # If rsync copies lustre xattrs in the future, then we can skip lfs (bug 22189) strings $(which $RSYNC) 2>&1 | grep -q lustre && LFS=: +# rsync creates its temporary files with lenient permissions, even if +# permissions on the original files are more strict. Tighten umask here +# to avoid the brief window where unprivileged users might be able to +# access the temporary file. +umask 0077 + +# This is needed for 1.8 Interoperability and can be removed in the future +$LFS getstripe --help 2>&1 | grep -q stripe-size && LFS_SIZE_OPT="-S" + lfs_migrate() { - while read OLDNAME; do + local RSYNC_MODE=false + + while IFS='' read -d '' OLDNAME; do $ECHO -n "$OLDNAME: " # avoid duplicate stat if possible - TYPE_LINK=($(stat -c "%h %F" "$OLDNAME" || true)) + TYPE_LINK=($(LANG=C stat -c "%h %F" "$OLDNAME" || true)) # skip non-regular files, since they don't have any objects # and there is no point in trying to migrate them. @@ -104,7 +132,6 @@ lfs_migrate() { continue fi - if [ "$OPT_RESTRIPE" ]; then UNLINK="" else @@ -112,17 +139,36 @@ lfs_migrate() { # (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) - SIZE=$($LFS getstripe -s "$OLDNAME" 2> /dev/null) + + [ "$OPT_STRIPE_COUNT" ] && COUNT=$OPT_STRIPE_COUNT || + COUNT=$($LFS getstripe -c "$OLDNAME" \ + 2> /dev/null) + SIZE=$($LFS getstripe $LFS_SIZE_OPT "$OLDNAME" \ + 2> /dev/null) + [ -z "$COUNT" -o -z "$SIZE" ] && UNLINK="" + SIZE=${LFS_SIZE_OPT}${SIZE} fi + + # first try to migrate inside lustre + # if failed go back to old rsync mode + if [[ $RSYNC_MODE == false ]]; then + if $LFS migrate -c${COUNT} ${SIZE} "$OLDNAME"; then + $ECHO "done" + continue + else + echo "falling back to rsync-based migration" + RSYNC_MODE=true + fi + fi + NEWNAME=$(mktemp $UNLINK "$OLDNAME.tmp.XXXXXX") if [ $? -ne 0 -o -z "$NEWNAME" ]; then echo -e "\r$OLDNAME: can't make temp file, skipped" 1>&2 continue fi - [ "$UNLINK" ] && $LFS setstripe -c${COUNT} -s${SIZE} "$NEWNAME" + [ "$UNLINK" ] && $LFS setstripe -c${COUNT} ${SIZE} "$NEWNAME" # we use --inplace, since we created our own temp file already if ! $RSYNC -a --inplace $RSYNC_OPTS "$OLDNAME" "$NEWNAME";then @@ -145,13 +191,17 @@ lfs_migrate() { } if [ "$#" -eq 0 ]; then - lfs_migrate + if [ "$OPT_NULL" ]; then + lfs_migrate + else + tr '\n' '\0' | lfs_migrate + fi else while [ "$1" ]; do if [ -d "$1" ]; then - lfs find "$1" -type f | lfs_migrate + lfs find "$1" -type f -print0 | lfs_migrate else - echo $1 | lfs_migrate + echo -en "$1\0" | lfs_migrate fi shift done