
kpartx creates partition devices asynchronously - it may exit before the devices have been created. This may cause a subsequent mount call to fail, because the device it is trying to mount does not yet exist. kpartx now has a -s option which makes it wait for the devices to be created before returning, but the version XenServer's dom0 doesn't have this option. Work around this by retrying the mount. When dom0's kpartx is updated, we will be able to use the -s option. Change-Id: I823a8eac4f3a2ef313d06e21da0f38ed46d7386a
97 lines
2.1 KiB
Bash
Executable File
97 lines
2.1 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
set -eux
|
|
|
|
action="$1"
|
|
vm="$2"
|
|
device="${3-0}"
|
|
part="${4-}"
|
|
|
|
function xe_min() {
|
|
local cmd="$1"
|
|
shift
|
|
xe "$cmd" --minimal "$@"
|
|
}
|
|
|
|
function run_udev_settle() {
|
|
which_udev=$(which udevsettle) || true
|
|
if [ -n "$which_udev" ]; then
|
|
udevsettle
|
|
else
|
|
udevadm settle
|
|
fi
|
|
}
|
|
|
|
vm_uuid=$(xe_min vm-list name-label="$vm")
|
|
vdi_uuid=$(xe_min vbd-list params=vdi-uuid vm-uuid="$vm_uuid" \
|
|
userdevice="$device")
|
|
|
|
dom0_uuid=$(xe_min vm-list is-control-domain=true)
|
|
|
|
function get_mount_device() {
|
|
vbd_uuid=$1
|
|
|
|
dev=$(xe_min vbd-list params=device uuid="$vbd_uuid")
|
|
if [[ "$dev" =~ "sm/" ]]; then
|
|
DEBIAN_FRONTEND=noninteractive \
|
|
apt-get --option "Dpkg::Options::=--force-confold" --assume-yes \
|
|
install kpartx &> /dev/null || true
|
|
mapping=$(kpartx -av "/dev/$dev" | sed -ne 's,^add map \([a-z0-9\-]*\).*$,\1,p' | sed -ne "s,^\(.*${part}\)\$,\1,p")
|
|
if [ -z "$mapping" ]; then
|
|
echo "Failed to find mapping"
|
|
exit -1
|
|
fi
|
|
|
|
local device="/dev/mapper/${mapping}"
|
|
for (( i = 0; i < 5; i++ )) ; do
|
|
if [ -b $device ] ; then
|
|
echo $device
|
|
return
|
|
fi
|
|
sleep 1
|
|
done
|
|
echo "ERROR: timed out waiting for dev-mapper"
|
|
exit 1
|
|
else
|
|
echo "/dev/$dev$part"
|
|
fi
|
|
}
|
|
|
|
function clean_dev_mappings() {
|
|
dev=$(xe_min vbd-list params=device uuid="$vbd_uuid")
|
|
if [[ "$dev" =~ "sm/" ]]; then
|
|
kpartx -dv "/dev/$dev"
|
|
fi
|
|
}
|
|
|
|
function open_vdi() {
|
|
vbd_uuid=$(xe vbd-create vm-uuid="$dom0_uuid" vdi-uuid="$vdi_uuid" \
|
|
device=autodetect)
|
|
mp=$(mktemp -d)
|
|
xe vbd-plug uuid="$vbd_uuid"
|
|
|
|
run_udev_settle
|
|
|
|
mount_device=$(get_mount_device "$vbd_uuid")
|
|
mount "$mount_device" "$mp"
|
|
echo "Your vdi is mounted at $mp"
|
|
}
|
|
|
|
function close_vdi() {
|
|
vbd_uuid=$(xe_min vbd-list vm-uuid="$dom0_uuid" vdi-uuid="$vdi_uuid")
|
|
mount_device=$(get_mount_device "$vbd_uuid")
|
|
run_udev_settle
|
|
umount "$mount_device"
|
|
|
|
clean_dev_mappings
|
|
|
|
xe vbd-unplug uuid=$vbd_uuid
|
|
xe vbd-destroy uuid=$vbd_uuid
|
|
}
|
|
|
|
if [ "$action" == "open" ]; then
|
|
open_vdi
|
|
elif [ "$action" == "close" ]; then
|
|
close_vdi
|
|
fi
|