diff options
Diffstat (limited to 'extras/glusterfs-defrag.in')
| -rw-r--r-- | extras/glusterfs-defrag.in | 109 | 
1 files changed, 109 insertions, 0 deletions
diff --git a/extras/glusterfs-defrag.in b/extras/glusterfs-defrag.in new file mode 100644 index 000000000..982878bdb --- /dev/null +++ b/extras/glusterfs-defrag.in @@ -0,0 +1,109 @@ +#!/bin/bash + +# Please leave 'added_bricks' as empty if you want 100% defrag. +# If you want to move data to newly added bricks, properly give +# brick info as "<hostname>:<export-dir>" form (which was given +# in 'gluster volume create' command) +# More than one brick can be given with space inbetween. + +# +# (c) 2010 Gluster Inc <http://www.gluster.com/> +# + +set -e; + +added_bricks="node1:/gfs/export1" + +CP="cp" +MV="mv" + +scan_dir() +{ +    path=$1; +    # run defrag on files first # +    find "$path" -maxdepth 1 -type f -perm +01000 -exec $0 '{}' \; + +    for subdir in $(find "$path" -maxdepth 1 -type d | sed 1d); do +        $0 "$subdir"; +    done +} + +fix_xattr() +{ +    path=$1; +    getfattr -n trusted.distribute.fix.layout "$path" 2>/dev/null; +} + +rsync_filename() +{ +    path=$1 +    dir=$(dirname "$path"); +    file=$(basename "$path"); + +    echo "$dir/.$file.zr$$"; +} + +relocate_file() +{ +    path=$1; +    stat_info=$(stat -c '%a' "$path"); +    if [ $stat_info -lt 1000 ] ; then +        return; +    fi + +    flag=0; +    linknode=$(getfattr --only-values -n trusted.distribute.linkinfo $path 2>/dev/null); +    if [ -z $linknode ] ; then +        return; +    fi + +    for bricks in ${added_bricks}; do +        current_brick=${linknode:0:${#bricks}}; +        if [ "${bricks}" == "${current_brick}" ]; then +            flag=1; +        fi +    done + +    if [ $flag -ne 1 ]; then +        return; +    fi + +    tmp_path=$(rsync_filename "$path"); + +    pre_mtime=$(stat -c '%Y' "$path"); +    $CP -a "$path" "$tmp_path"; +    post_mtime=$(stat -c '%Y' "$path"); + +    if [ $pre_mtime = $post_mtime ]; then +	chmod -t "$tmp_path"; +	$MV "$tmp_path" "$path"; +	echo "file '$path' relocated" +    else +	echo "file '$path' modified during defrag. skipping" +	rm -f "$tmp_path"; +    fi +} + +defrag_usage() +{ +    echo "Usage: $0 <directory>" +} + +main() +{ +    path="$1"; + +    if [ -z "$path" ]; then +        defrag_usage; +        return; +    fi + +    if [ -d "$path" ]; then +        fix_xattr "$path"; +	scan_dir "$path"; +    else +	relocate_file "$@"; +    fi +} + +main "$1"  | 
