libvirt/tools/libvirt_recover_xattrs.sh
Daniel P. Berrangé e674218dc2 tools: fix iterating over argv when recovering xattr
The libvirt_recover_xattrs.sh tool hangs when run. When no flags
are provided OPTIND is 1, so the loop expands to 'shift 0' which
has not effect. Rewrite to just loop over $@ instead which involves
less cleverness.

Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2021-11-30 10:45:35 +00:00

119 lines
2.4 KiB
Bash
Executable File

#!/bin/bash
function die {
echo $@ >&2
exit 1
}
function show_help {
cat << EOF
Usage: ${0##*/} -[hqnu] [PATH ...]
Clear out any XATTRs set by libvirt on all files that have them.
The idea is to reset refcounting, should it break.
-h display this help and exit
-q quiet (don't print which files are being fixed)
-n dry run; don't remove any XATTR just report the file name
-u unsafe; don't check whether there are running VMs; PATH must be specified
PATH can be specified to refine search to only to given path
instead of whole root ('/'), which is the default.
EOF
}
QUIET=0
DRY_RUN=0
UNSAFE=0
# So far only qemu and lxc drivers use security driver.
URI=("qemu:///system"
"lxc:///system")
if [ $(whoami) != "root" ]; then
die "Must be run as root"
fi
while getopts hqnu opt; do
case $opt in
h)
show_help
exit 0
;;
q)
QUIET=1
;;
n)
DRY_RUN=1
;;
u)
UNSAFE=1
;;
*)
show_help >&2
exit 1
;;
esac
done
case $(uname -s) in
Linux)
XATTR_PREFIX="trusted.libvirt.security"
;;
FreeBSD)
XATTR_PREFIX="system.libvirt.security"
;;
*)
die "$0 is not supported on this platform"
;;
esac
if [ ${DRY_RUN} -eq 0 ] && [ ${UNSAFE} -eq 0 ]; then
for u in ${URI[*]} ; do
if [ -n "`virsh -q -c $u list 2>/dev/null`" ]; then
die "There are still some domains running for $u"
fi
done
fi
declare -a XATTRS
for i in "dac" "selinux"; do
XATTRS+=("$XATTR_PREFIX.$i" "$XATTR_PREFIX.ref_$i" "$XATTR_PREFIX.timestamp_$i")
done
fix_xattrs() {
local DIR="$1"
for i in $(getfattr -R -d -m ${XATTR_PREFIX} --absolute-names ${DIR} 2>/dev/null | grep "^# file:" | cut -d':' -f 2); do
if [ ${DRY_RUN} -ne 0 ]; then
getfattr -d -m ${XATTR_PREFIX} --absolute-names $i
continue
fi
if [ ${QUIET} -eq 0 ]; then
echo "Fixing $i";
fi
for x in ${XATTRS[*]}; do
setfattr -x $x $i
done
done
}
shift $((OPTIND - 1))
if [ $# -gt 0 ]; then
for arg in "$@"
do
fix_xattrs "$arg"
done
else
if [ ${UNSAFE} -eq 1 ]; then
die "Unsafe mode (-u) requires explicit 'PATH' argument"
fi
fix_xattrs "/"
fi