summaryrefslogtreecommitdiffstats
path: root/extras/glusterfs-defrag.in
diff options
context:
space:
mode:
Diffstat (limited to 'extras/glusterfs-defrag.in')
-rw-r--r--extras/glusterfs-defrag.in109
1 files changed, 109 insertions, 0 deletions
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 "<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"