1
0
mirror of https://github.com/gluster/glusterfs.git synced 2026-02-05 15:48:40 +01:00
Files
glusterfs/tests/afr.rc
Pranith Kumar K 9ecbd69127 cluster/afr: Heal directory rename without rmdir/mkdir
Problem1:
When a directory is renamed while a brick
is down entry-heal always did an rm -rf on that directory on
the sink on old location and did mkdir and created the directory
hierarchy again in the new location. This is inefficient.

Problem2:
Renamedir heal order may lead to a scenario where directory in
the new location could be created before deleting it from old
location leading to 2 directories with same gfid in posix.

Fix:
As part of heal, if oldlocation is healed first and is not present in
source-brick always rename it into a hidden directory inside the
sink-brick so that when heal is triggered in new-location shd can
rename it from this hidden directory to the new-location.

If new-location heal is triggered first and it detects that the
directory already exists in the brick, then it should skip healing the
directory until it appears in the hidden directory.

Credits: Ravi for rename-data-loss.t script

Fixes: #1211
Change-Id: I0cba2006f35cd03d314d18211ce0bd530e254843
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
2020-10-01 12:03:25 +00:00

124 lines
4.3 KiB
Bash

#!/bin/bash
function create_brick_xattrop_entry {
local xattrop_dir=$(afr_get_index_path $1)
local base_entry=`ls $xattrop_dir|grep xattrop`
local gfid_str
local params=`echo "$@" | cut -d' ' -f2-`
echo $params
for file in $params
do
gfid_str=$(gf_gfid_xattr_to_str $(gf_get_gfid_xattr $1/$file))
ln $xattrop_dir/$base_entry $xattrop_dir/$gfid_str
done
}
function diff_dirs {
diff <(ls $1 | sort) <(ls $2 | sort)
}
function heal_status {
local f1_path="${1}/${3}"
local f2_path="${2}/${3}"
local zero_xattr="000000000000000000000000"
local insync=""
diff_dirs $f1_path $f2_path
if [ $? -eq 0 ];
then
insync="Y"
else
insync="N"
fi
local xattr11=$(get_hex_xattr trusted.afr.$V0-client-0 $f1_path)
local xattr12=$(get_hex_xattr trusted.afr.$V0-client-1 $f1_path)
local xattr21=$(get_hex_xattr trusted.afr.$V0-client-0 $f2_path)
local xattr22=$(get_hex_xattr trusted.afr.$V0-client-1 $f2_path)
local dirty1=$(get_hex_xattr trusted.afr.dirty $f1_path)
local dirty2=$(get_hex_xattr trusted.afr.dirty $f2_path)
if [ -z $xattr11 ]; then xattr11="000000000000000000000000"; fi
if [ -z $xattr12 ]; then xattr12="000000000000000000000000"; fi
if [ -z $xattr21 ]; then xattr21="000000000000000000000000"; fi
if [ -z $xattr22 ]; then xattr22="000000000000000000000000"; fi
if [ -z $dirty1 ]; then dirty1="000000000000000000000000"; fi
if [ -z $dirty2 ]; then dirty2="000000000000000000000000"; fi
echo ${insync}${xattr11}${xattr12}${xattr21}${xattr22}${dirty1}${dirty2}
}
# Check if given dir's self-heal is done
function is_dir_heal_done {
local zero_xattr="000000000000000000000000"
if [ "$(heal_status $@)" == "Y${zero_xattr}${zero_xattr}${zero_xattr}${zero_xattr}${zero_xattr}${zero_xattr}" ];
then
echo "Y"
else
echo "N"
fi
}
# Check if the given file's self-heal is done
function is_file_heal_done {
local f1_path="${1}/${3}"
local f2_path="${2}/${3}"
local zxattr="000000000000000000000000"
local size1=$(stat -c "%s" $f1_path)
local size2=$(stat -c "%s" $f2_path)
local diff=$((size1-size2))
local x11=$(get_hex_xattr trusted.afr.$V0-client-0 $f1_path)
local x12=$(get_hex_xattr trusted.afr.$V0-client-1 $f1_path)
local x21=$(get_hex_xattr trusted.afr.$V0-client-0 $f2_path)
local x22=$(get_hex_xattr trusted.afr.$V0-client-1 $f2_path)
local dirty1=$(get_hex_xattr trusted.afr.dirty $f1_path)
local dirty2=$(get_hex_xattr trusted.afr.dirty $f2_path)
if [ -z $x11 ]; then x11="000000000000000000000000"; fi
if [ -z $x12 ]; then x12="000000000000000000000000"; fi
if [ -z $x21 ]; then x21="000000000000000000000000"; fi
if [ -z $x22 ]; then x22="000000000000000000000000"; fi
if [ -z $dirty1 ]; then dirty1="000000000000000000000000"; fi
if [ -z $dirty2 ]; then dirty2="000000000000000000000000"; fi
if [ "${diff}${x11}${x12}${x21}${x22}${dirty1}${dirty2}" == "0${zxattr}${zxattr}${zxattr}${zxattr}${zxattr}${zxattr}" ];
then
echo "Y"
else
echo "N"
fi
}
#count the number of entries marked for self-heal
#in brick $1's index
function count_index_entries()
{
ls $1/.glusterfs/indices/xattrop | wc -l
}
function afr_up_status()
{
local v=$1
local m=$2
local replica_id=$3
grep -E "^up = " $m/.meta/graphs/active/${v}-replicate-${replica_id}/private | cut -f2 -d'='
}
function get_quorum_type()
{
local m="$1"
local v="$2"
local repl_id="$3"
cat $m/.meta/graphs/active/$v-replicate-$repl_id/private|grep quorum-type|awk '{print $3}'
}
function afr_private_key_value()
{
local v=$1
local m=$2
local replica_id=$3
local key=$4
#xargs at the end will strip leading spaces
grep -E "^${key} = " $m/.meta/graphs/active/${v}-replicate-${replica_id}/private | cut -f2 -d'=' | xargs
}
function afr_anon_entry_count()
{
local b=$1
ls $b/.glusterfs-anonymous-inode* | wc -l
}