97 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			2.2 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/" || "$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
 | 
