From 654a720eed0bc5faaeeaa4eb34f1cfc10df76230 Mon Sep 17 00:00:00 2001 From: Amar Tumballi Date: Wed, 14 Jul 2010 13:58:20 +0000 Subject: proper way to do defrag of a mountpoint Usage: "glusterfs-defrag " there are new features added to distribute with this patch: * bash# getfattr -n trusted.distribute.linkinfo Gives output in the format ":", if there is a linkfile present, where hostname is server, directory is backend directory where the actual linkfile is present. * bash# getfattr -n trusted.glusterfs.pathinfo Gives layout information if directory, and info about actual location of file in backend servers, in the form of 'hostname:directory'. (TODO: should extend it to all xlators) * bash# getfattr -n trusted.distribute.fix.layout scales out the directory layout in distribute, so when new servers are added, layouts are fixed to include them. * removed 'scale-n-defrag.sh' as its no more required. * changed 'defrag.sh' to have a feature to specify target bricks, so defrag happens to only those nodes. moved the file to 'glusterfs-defrag', which now gets installed to '${prefix}/bin' * storage/posix: takes new option 'hostname' so it can resolve to same hostname given during 'gluster volume create'. with 'trusted.glusterfs.pathinfo' posix returns the value in 'hostname:real_path' format. Signed-off-by: Amar Tumballi Signed-off-by: Anand V. Avati BUG: 1073 ('gluster defrag ' fails in mainline) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1073 --- extras/glusterfs-defrag.in | 109 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 extras/glusterfs-defrag.in (limited to 'extras/glusterfs-defrag.in') diff --git a/extras/glusterfs-defrag.in b/extras/glusterfs-defrag.in new file mode 100644 index 00000000000..982878bdbe9 --- /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 ":" form (which was given +# in 'gluster volume create' command) +# More than one brick can be given with space inbetween. + +# +# (c) 2010 Gluster Inc +# + +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 " +} + +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" -- cgit