Fix disk multiattach with VirtualBox 6

Starting with version 6.0, the behavior of VirtualBox with regards to
disk multiattach changed.

The result are error messages like:
  VBoxManage: error: Cannot change type for medium '<base_disk_path>':
  the media type 'MultiAttach' can only be used on media registered
  with a machine that was created with VirtualBox 4.0 or later

The new code should work for both VirtualBox 6 and older versions.

The workaround suggests that we may not be using the VirtualBox volumes
the way they are meant to be used, but with scant documentation out
there rewriting the volume logic may result in no improvement at all,
so let's leave it at that for the time being.

backport: rocky queens pike ocata

Closes-Bug: 1817584

Change-Id: I9307d2e0f077539c118f540a9b0a4358e4f3b459
(cherry picked from commit e4dec38469)
This commit is contained in:
Roger Luethi 2019-05-13 08:54:24 +02:00
parent ef6fe1e223
commit e246560cab
2 changed files with 23 additions and 1 deletions

View File

@ -70,7 +70,22 @@ def vm_create_node(vm_name):
if disk is None:
continue
elif disk == "base":
vm.vm_attach_disk_multi(vm_name, cvb.get_base_disk_path())
base_disk_path = cvb.get_base_disk_path()
if conf.wbatch or not vm.vm_disk_is_multiattach(base_disk_path):
# Skip the following workaround if the base disk is already
# registered as a multiattach image to avoid creating orphaned
# COW images. Windows batch scripts use the workaround
# unconditionally and therefore create COW orphan images
# (visible in the VirtualBox Media Manager).
# Attach and detach base disk first to have it registered with
# the VirtualBox Media Manager. Required by VirtualBox 6+ for
# configuring a multiattach volume.
vm.vm_attach_disk(vm_name, base_disk_path)
vm.vm_detach_disk(vm_name)
vm.vm_attach_disk_multi(vm_name, base_disk_path)
else:
size = disk
disk_name = "{}-sd{}.vdi".format(vm_name, disk_letter)

View File

@ -550,6 +550,13 @@ def vm_attach_disk(vm_name, disk, port=0):
"--medium", disk)
# disk can be either a path or a disk UUID
def vm_disk_is_multiattach(disk):
output = vbm("showmediuminfo", disk, wbatch=False)
regex = re.compile(r"^Type:.*multiattach", re.MULTILINE)
return True if re.search(regex, output) else False
# disk can be either a path or a disk UUID
def vm_attach_disk_multi(vm_name, disk, port=0):
vbm("modifyhd", "--type", "multiattach", disk)