udev/qvm-block: exclude devices used elsewhere
Exclude exclude device if mounted/part of other device, or any of its partition is used (same definition). Update this state whenever device or it's partition receives udev event. Fixes QubesOS/qubes-issues#1600
This commit is contained in:
parent
98aed38ec5
commit
efd9854376
@ -1,5 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
shopt -s nullglob
|
||||||
|
|
||||||
export LC_CTYPE=en_US.UTF-8
|
export LC_CTYPE=en_US.UTF-8
|
||||||
NAME=${DEVNAME#/dev/}
|
NAME=${DEVNAME#/dev/}
|
||||||
DESC="`echo "${ID_MODEL} (${ID_FS_LABEL})" | iconv -f utf8 -t ascii//TRANSLIT`"
|
DESC="`echo "${ID_MODEL} (${ID_FS_LABEL})" | iconv -f utf8 -t ascii//TRANSLIT`"
|
||||||
@ -15,26 +17,62 @@ xs_remove() {
|
|||||||
echo QUBES_EXPOSED=0
|
echo QUBES_EXPOSED=0
|
||||||
}
|
}
|
||||||
|
|
||||||
# Ignore mounted...
|
is_used() {
|
||||||
if fgrep -q $DEVNAME /proc/mounts; then
|
local sys_devpath=$1
|
||||||
|
# mounted
|
||||||
|
if fgrep -q $(basename $sys_devpath) /proc/mounts; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
# part of other device-mapper
|
||||||
|
if [ -n "`ls -A $sys_devpath/holders 2> /dev/null`" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
# open device-mapper device
|
||||||
|
if [ -f "$sys_devpath/dm/name" ] && \
|
||||||
|
/sbin/dmsetup info "$(cat $sys_devpath/dm/name)" |\
|
||||||
|
grep -q "^Open count:.*[1-9]"; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# update info about parent devices, if any:
|
||||||
|
if [ -f /sys$DEVPATH/partition ]; then
|
||||||
|
parent=$(dirname $(readlink -f /sys$DEVPATH))
|
||||||
|
udevadm trigger \
|
||||||
|
--property-match=DEVPATH=/$(realpath --relative-to=/sys $parent)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# and underlying devices of device-mapper (if any)
|
||||||
|
for dev in /sys$DEVPATH/slaves/*; do
|
||||||
|
udevadm trigger \
|
||||||
|
--property-match=DEVPATH=/$(realpath --relative-to=/sys $dev)
|
||||||
|
done
|
||||||
|
|
||||||
|
# then take care of this device:
|
||||||
|
|
||||||
|
# device itself is already used
|
||||||
|
if is_used /sys$DEVPATH; then
|
||||||
xs_remove
|
xs_remove
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
# ... and used by device-mapper
|
|
||||||
if [ -n "`ls -A /sys/$DEVPATH/holders 2> /dev/null`" ]; then
|
# or one of its partitions is used
|
||||||
|
for part in /sys$DEVPATH/$NAME*; do
|
||||||
|
if [ -d $part ]; then
|
||||||
|
if is_used $part; then
|
||||||
xs_remove
|
xs_remove
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
# ... and used device-mapper devices
|
fi
|
||||||
if [ -n "$DM_NAME" ] && /sbin/dmsetup info "$DM_NAME" | grep -q "^Open count:.*[1-9]"; then
|
done
|
||||||
xs_remove
|
|
||||||
exit 0
|
# or "empty" loop device
|
||||||
fi
|
|
||||||
# ... and "empty" loop devices
|
|
||||||
if [ "$MAJOR" -eq 7 -a ! -d /sys/$DEVPATH/loop ]; then
|
if [ "$MAJOR" -eq 7 -a ! -d /sys/$DEVPATH/loop ]; then
|
||||||
xs_remove
|
xs_remove
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ... and temporary devices used during VM startup
|
# ... and temporary devices used during VM startup
|
||||||
if [[ "$NAME" = 'loop'* ]] && \
|
if [[ "$NAME" = 'loop'* ]] && \
|
||||||
[[ "`cat /sys/block/${NAME%p*}/loop/backing_file`" = \
|
[[ "`cat /sys/block/${NAME%p*}/loop/backing_file`" = \
|
||||||
|
@ -26,6 +26,11 @@ device_detach() {
|
|||||||
xenstore-rm $xs_path
|
xenstore-rm $xs_path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# update info about underlying devices of device-mapper (if any)
|
||||||
|
# at this stage device-mapper is already removed, so can't check what devices
|
||||||
|
# were used there
|
||||||
|
udevadm trigger --subsystem-match=block
|
||||||
|
|
||||||
for XS_DEV_PATH in `xenstore-ls -f backend/vbd | grep 'backend/vbd/[0-9]*/[0-9]* ' | cut -f 1 -d ' '`; do
|
for XS_DEV_PATH in `xenstore-ls -f backend/vbd | grep 'backend/vbd/[0-9]*/[0-9]* ' | cut -f 1 -d ' '`; do
|
||||||
CUR_DEVICE=`xenstore-read "$XS_DEV_PATH/params"`
|
CUR_DEVICE=`xenstore-read "$XS_DEV_PATH/params"`
|
||||||
if [ "$CUR_DEVICE" == "$DEVNAME" ]; then
|
if [ "$CUR_DEVICE" == "$DEVNAME" ]; then
|
||||||
|
Loading…
Reference in New Issue
Block a user