Files
devstack/tools/xen/scripts/manage-vdi
Euan Harris a3ec804ad9 manage-vdi: Wait until devices have been created before mounting
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
2013-07-11 15:50:32 +01:00

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