This script helps to find permission denied in realtion to wrong folder permissions during a repo expansion. It scans the brick logs of the given repository and tries to fix permissions and ownership of the folders. Additionally a find over the whole repo should be run in paralllel. This script is only intended to help against errors actually happens due to access attemps.
174 lines
4.9 KiB
Bash
174 lines
4.9 KiB
Bash
#!/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
|