| #!/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/" || "$dev" =~ "blktap-2/" ]]; 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/" || "$dev" =~ "blktap-2/" ]]; 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 |