mirror of
https://github.com/gluster/glusterfs.git
synced 2026-02-05 15:48:40 +01:00
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>
124 lines
4.3 KiB
Bash
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
|
|
}
|