Add script to check brick logs for permission denied #15

Merged
thomas.gebert merged 1 commits from check-and-fix-permissions into main 2026-05-07 12:35:21 +00:00

View File

@ -0,0 +1,173 @@
#!/bin/bash
if ! [ "${LOGNAME}" == "root" ]; then
echo "Please run this script as root or with sudo..."
exit 1
fi
################################################################################
# Global variables
################################################################################
TIMEOUT="60s"
MODE=""
################################################################################
# Functions
################################################################################
show_help() {
cat << HELP
Check the brick logs of a repository for "Permission denied" errors due to lost
permissions while expanding. Normally folders look like
# stat /gluster/repositories/hydmedia//HYD$/data/current/VOLUME3692/169
File: /gluster/repositories/hydmedia//HYD$/data/current/VOLUME3692/169
Size: 4096 Blocks: 8 IO Block: 131072 directory
Device: 48h/72d Inode: 12128098184435013363 Links: 2
Access: (0000/d---------) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2026-04-20 11:51:40.722905693 +0000
Modify: 2026-04-20 12:40:36.049491386 +0000
Change: 2026-04-20 12:40:36.049491386 +0000
Birth: -
Owner and group should be fsnobody
Access should be 0755
Usage: $1 [OPTION]
Mandatory:
-r|--repo REPO The repository to check
Optionial:
-t|--timeout TIMEOUT Timout to wait after scanning the brick logs for the
next iteration (DEFAULT: ${TIMEOUT}
-m|--mode MODE Scan for names or GFIDs. (DEFAULT: both)
HELP
exit 0
}
################################################################################
# Argument parser
################################################################################
die() {
printf '%s\n' "$1" >&2
exit 1
}
while :; do
case $1 in
-h|-\?|--help)
show_help # Display a usage synopsis.
exit
;;
-r|--repo)
if [ "$2" ]; then
REPO=$2
shift
else
die 'ERROR: "-r|--repo" requires a non-empty option argument.'
fi
;;
-m|--mode)
if [ "$2" ]; then
MODE=$2
shift
else
die 'ERROR: "-r|--repo" requires a non-empty option argument.'
fi
;;
-t|--timeout)
if [ "$2" ]; then
TIMEOUT=$2
shift
else
die 'ERROR: "-t|--timeout" requires a non-empty option argument.'
fi
;;
--) # End of all options.
shift
break
;;
*) # Default case: No more options, so break out of the loop.
break
esac
shift
done
get_bricks() {
MY_HOSTNAME=$(echo "${HOSTNAME}" | cut -d '.' -f 1)
if ! BRICKS=$(gluster vol info "${REPO}" | grep -i "${MY_HOSTNAME}" | grep -o 'brick[0-9]\+'); then
return 1
fi
for BRICK in ${BRICKS}; do
BRICK_LOGS="${BRICK_LOGS} /var/log/glusterfs/bricks/*${BRICK}*log"
done
}
header() {
echo "################################################################################"
date
echo "Checking following logs:"
for BRICK_LOG in ${BRICK_LOGS}; do
echo " ${BRICK_LOG}"
done
echo ""
}
get_pathnames_by_name() {
PATHNAMES_BY_NAME=$(zgrep "error=Permission denied" ${BRICK_LOGS} | grep -o 'path=\S\+' | cut -d '=' -f 2 | egrep -v '<gfid' | sed -e 's/\}\,//g' | sort -u)
}
get_pathnames_by_gfid() {
GFIDS=$(zgrep "error=Permission denied" ${BRICK_LOGS} | grep -o 'path=\S\+' | cut -d '=' -f 2 | egrep '<gfid' | cut -d ':' -f 2 | cut -d '>' -f 1 | sort -u)
PATHNAMES_BY_GFID=""
for GFID in ${GFIDS}; do
NEW_PATHNAME=$(getfattr -n glusterfs.ancestry.path -e text /gluster/repositories/"${REPO}"/.gfid/"${GFID}" |& grep glusterfs.ancestry.path | cut -d '=' -f 2 | sed -e's/\"//g')
PATHNAMES_BY_GFID="${PATHNAMES_BY_GFID} ${NEW_PATHNAME}"
done
}
scan_paths() {
while true; do
header
if [ "${MODE}" == "names" ] || [ "${MODE}" == "" ]; then
get_pathnames_by_name
fi
if [ "${MODE}" == "gfid" ] || [ "${MODE}" == "" ]; then
get_pathnames_by_gfid
fi
PATHNAMES="${PATHNAMES_BY_NAME} ${PATHNAMES_BY_GFID}"
echo "Folders fixed:"
for PATHNAME in ${PATHNAMES}; do
if [ -f /gluster/repositories/"${REPO}"/"${PATHNAME}" ]; then
PATHNAME=$(dirname "${PATHNAME}")
fi
if [ -d /gluster/repositories/"${REPO}"/"${PATHNAME}" ]; then
find /gluster/repositories/"${REPO}"/"${PATHNAME}" -maxdepth 0 -type d -perm 0000 -exec chown fsnobody: "{}" \; -exec chmod 0755 "{}" \; -printf '%p\n'
fi
done
sleep "${TIMEOUT}"
done
}
################################################################################
# Main Main Main
################################################################################
if [ "${REPO}" == "" ]; then
echo "Repository is needed"
exit 1
fi
if ! get_bricks; then
echo "Could not get bricks of repository \"${REPO}\". Will exit now..."
exit 1
fi
scan_paths