[libvirt] [PATCH v2 10/15] vbox: Process <controller> element in domain XML

Dawid Zamirski dzamirski at datto.com
Fri Nov 3 15:28:58 UTC 2017


On Fri, 2017-11-03 at 09:51 -0400, John Ferlan wrote:
> 
> On 10/24/2017 03:35 PM, Dawid Zamirski wrote:
> > This patch enables the VBOX driver to process the <controller>
> > element
> > in domain XML through which one can now customize the controller
> > model.
> > 
> > Since VirtualBox has two distinct SAS and SCSI they do not "map"
> > directly to libvirt XML, he VBOX driver uses <contoller type="scsi"
> > model="lsisas1068" /> to create SAS controller in VBOX VM.
> > Additionally
> > once can set model on the IDE controller to be one of "piix3",
> > "piix4"
> > or "ich6".
> > ---
> >  src/vbox/vbox_common.c | 214
> > ++++++++++++++++++++++++++++++++++++++-----------
> >  src/vbox/vbox_common.h |   8 ++
> >  2 files changed, 176 insertions(+), 46 deletions(-)
> > 
> 
> So beyond patch 3 which I know you have to repost anyway - starting
> with
> this patch and going forward, I figure you have to repost anyway as
> long
> as I get the question in patch 5 answered of course...
> 
> This patch left me with a concern.  Up to this point vboxAttachDrives
> would add at least one controller for each type supported regardless
> of
> whether the VM used it.
> 
> After this patch only those controllers defined in the VM XML will be
> added. Which would seem to be fine, except for the case of hotplug
> which
> I wasn't clear whether vbox support or not.
> 
> Let's say the VM is defined with and IDE controller, if someone tried
> to
> add a SCSI disk after startup, then there'd be no SCSI controller
> already present.
> 

I've just checked this with VirutalBox GUI and the only thing that can
be changed on live VM is removable media (CD/DVD). All options to add
disk devices to controller are disabled when VM is running. Neither
quick web search returned anything useful regarding hot-add disk
support on VBOX.
Having said that, the original behavior was, IIRC, the reason why I
actually started working on this series. According to our tech support
they have ran into a couple of cases where the OS would BSOD (some
legacy Windows OS e.g. 2000 or XP) when there was a controller (without
a disk) attached to VM that the OS did not handle well. It sounded very
strange to me but I've been told it was not a one-off case though I
personally haven't reproduced it. Unfortunately, I won't be able to
provide more details as we no longer use VBox internally (migrated to
KVM) so those potential test cases are no longer around.

> 
> > diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
> > index 2bd891efb..9d45e4a76 100644
> > --- a/src/vbox/vbox_common.c
> > +++ b/src/vbox/vbox_common.c
> > @@ -406,6 +406,160 @@ static char *vboxGenerateMediumName(PRUint32
> > storageBus,
> >      return name;
> >  }
> >  
> > +
> > +static int
> > +vboxSetStorageController(virDomainControllerDefPtr controller,
> > +                         vboxDriverPtr data,
> > +                         IMachine *machine)
> > +{
> > +    PRUnichar *controllerName = NULL;
> > +    PRInt32 vboxModel = StorageControllerType_Null;
> > +    PRInt32 vboxBusType = StorageBus_Null;
> > +    IStorageController *vboxController = NULL;
> > +    nsresult rc = 0;
> > +    char *debugName = NULL;
> > +    int ret = -1;
> > +
> > +    /* libvirt controller type => vbox bus type */
> > +    switch ((virDomainControllerType) controller->type) {
> > +    case VIR_DOMAIN_CONTROLLER_TYPE_FDC:
> > +        VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_FLOPPY_NAME,
> > &controllerName);
> > +        vboxBusType = StorageBus_Floppy;
> > +
> > +        break;
> > +    case VIR_DOMAIN_CONTROLLER_TYPE_IDE:
> > +        VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_IDE_NAME,
> > &controllerName);
> > +        vboxBusType = StorageBus_IDE;
> > +
> > +        break;
> > +    case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
> > +        VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SCSI_NAME,
> > &controllerName);
> > +        vboxBusType = StorageBus_SCSI;
> > +
> > +        break;
> > +    case VIR_DOMAIN_CONTROLLER_TYPE_SATA:
> > +        VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SATA_NAME,
> > &controllerName);
> > +        vboxBusType = StorageBus_SATA;
> 
> 
> I think prior to this patch - there should be a patch that "manages"
> all
> those range check differences, storageBus comparison checks, etc. for
> VIR_DOMAIN_CONTROLLER_TYPE_SATA that end up in future patches.
> 
> John
> 
> > +
> > +        break;
> > +    case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL:
> > +    case VIR_DOMAIN_CONTROLLER_TYPE_CCID:
> > +    case VIR_DOMAIN_CONTROLLER_TYPE_USB:
> > +    case VIR_DOMAIN_CONTROLLER_TYPE_PCI:
> > +    case VIR_DOMAIN_CONTROLLER_TYPE_LAST:
> > +        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> > +                       _("The vbox driver does not support %s
> > controller type"),
> > +                       virDomainControllerTypeToString(controller-
> > >type));
> > +        return -1;
> > +    }
> > +
> > +    /* libvirt scsi model => vbox scsi model */
> > +    if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
> > +        switch ((virDomainControllerModelSCSI) controller->model)
> > {
> > +        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC:
> > +        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AUTO:
> > +            vboxModel = StorageControllerType_LsiLogic;
> > +
> > +            break;
> > +        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_BUSLOGIC:
> > +            vboxModel = StorageControllerType_BusLogic;
> > +
> > +            break;
> > +        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1068:
> > +            /* in vbox, lsisas has a dedicated SAS bus type with
> > no model */
> > +            VBOX_UTF16_FREE(controllerName);
> > +            VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SAS_NAME,
> > &controllerName);
> > +            vboxBusType = StorageBus_SAS;
> > +
> > +            break;
> > +        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VMPVSCSI:
> > +        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI:
> > +        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI:
> > +        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1078:
> > +        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST:
> > +            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> > +                           _("The vbox driver does not support %s
> > SCSI "
> > +                             "controller model"),
> > +                           virDomainControllerModelSCSITypeToStrin
> > g(controller->model));
> > +            goto cleanup;
> > +        }
> > +    /* libvirt ide model => vbox ide model */
> > +    } else if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_IDE)
> > {
> > +        switch ((virDomainControllerModelIDE) controller->model) {
> > +        case VIR_DOMAIN_CONTROLLER_MODEL_IDE_PIIX3:
> > +            vboxModel = StorageControllerType_PIIX3;
> > +
> > +            break;
> > +        case VIR_DOMAIN_CONTROLLER_MODEL_IDE_PIIX4:
> > +            vboxModel = StorageControllerType_PIIX4;
> > +
> > +            break;
> > +        case VIR_DOMAIN_CONTROLLER_MODEL_IDE_ICH6:
> > +            vboxModel = StorageControllerType_ICH6;
> > +
> > +            break;
> > +        case VIR_DOMAIN_CONTROLLER_MODEL_IDE_LAST:
> > +            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> > +                           _("The vbox driver does not support %s
> > IDE "
> > +                             "controller model"),
> > +                             virDomainControllerModelIDETypeToStri
> > ng(controller->model));
> > +            goto cleanup;
> > +        }
> > +    }
> > +
> > +    VBOX_UTF16_TO_UTF8(controllerName, &debugName);
> > +    VIR_DEBUG("Adding VBOX storage controller (name: %s, busType:
> > %d)",
> > +               debugName, vboxBusType);
> > +
> > +    rc = gVBoxAPI.UIMachine.AddStorageController(machine,
> > controllerName,
> > +                                                 vboxBusType,
> > &vboxController);
> > +
> > +    if (NS_FAILED(rc)) {
> > +        virReportError(VIR_ERR_INTERNAL_ERROR,
> > +                       _("Failed to add storage controller "
> > +                         "(name: %s, busType: %d), rc=%08x"),
> > +                       debugName, vboxBusType, rc);
> > +        goto cleanup;
> > +    }
> > +
> > +    /* only IDE or SCSI controller have model choices */
> > +    if (vboxModel != StorageControllerType_Null) {
> > +        rc =
> > gVBoxAPI.UIStorageController.SetControllerType(vboxController,
> > +                                                            vboxMo
> > del);
> > +        if (NS_FAILED(rc)) {
> > +            virReportError(VIR_ERR_INTERNAL_ERROR,
> > +                            _("Failed to change storage controller
> > model, "
> > +                              "rc=%08x"), rc);
> > +            goto cleanup;
> > +        }
> > +    }
> > +
> > +    ret = 0;
> > +
> > + cleanup:
> > +    VBOX_UTF16_FREE(controllerName);
> > +    VBOX_UTF8_FREE(debugName);
> > +    VBOX_RELEASE(vboxController);
> > +
> > +    return ret;
> > +}
> > +
> > +
> > +static int
> > +vboxAttachStorageControllers(virDomainDefPtr def,
> > +                             vboxDriverPtr data,
> > +                             IMachine *machine)
> > +{
> > +    size_t i;
> > +    for (i = 0; i < def->ncontrollers; i++) {
> > +        if (vboxSetStorageController(def->controllers[i], data,
> > machine) < 0)
> > +            return -1;
> > +    }
> > +
> > +    return 0;
> > +}
> > +
> > +
> >  static virDrvOpenStatus
> >  vboxConnectOpen(virConnectPtr conn,
> >                  virConnectAuthPtr auth ATTRIBUTE_UNUSED,
> > @@ -959,7 +1113,7 @@ static int
> >  vboxAttachDrives(virDomainDefPtr def, vboxDriverPtr data, IMachine
> > *machine)
> >  {
> >      size_t i;
> > -    int type, ret = 0;
> > +    int type, ret = 0, model = -1;
> >      const char *src = NULL;
> >      nsresult rc = 0;
> >      virDomainDiskDefPtr disk = NULL;
> > @@ -972,46 +1126,6 @@ vboxAttachDrives(virDomainDefPtr def,
> > vboxDriverPtr data, IMachine *machine)
> >  
> >      VBOX_IID_INITIALIZE(&mediumUUID);
> >  
> > -    /* add a storage controller for the mediums to be attached */
> > -    /* this needs to change when multiple controller are supported
> > for
> > -     * ver > 3.1 */
> > -    {
> > -        IStorageController *storageCtl = NULL;
> > -        PRUnichar *sName = NULL;
> > -
> > -        VBOX_UTF8_TO_UTF16("IDE Controller", &sName);
> > -        gVBoxAPI.UIMachine.AddStorageController(machine,
> > -                                                sName,
> > -                                                StorageBus_IDE,
> > -                                                &storageCtl);
> > -        VBOX_UTF16_FREE(sName);
> > -        VBOX_RELEASE(storageCtl);
> > -
> > -        VBOX_UTF8_TO_UTF16("SATA Controller", &sName);
> > -        gVBoxAPI.UIMachine.AddStorageController(machine,
> > -                                                sName,
> > -                                                StorageBus_SATA,
> > -                                                &storageCtl);
> > -        VBOX_UTF16_FREE(sName);
> > -        VBOX_RELEASE(storageCtl);
> > -
> > -        VBOX_UTF8_TO_UTF16("SCSI Controller", &sName);
> > -        gVBoxAPI.UIMachine.AddStorageController(machine,
> > -                                                sName,
> > -                                                StorageBus_SCSI,
> > -                                                &storageCtl);
> > -        VBOX_UTF16_FREE(sName);
> > -        VBOX_RELEASE(storageCtl);
> > -
> > -        VBOX_UTF8_TO_UTF16("Floppy Controller", &sName);
> > -        gVBoxAPI.UIMachine.AddStorageController(machine,
> > -                                                sName,
> > -                                                StorageBus_Floppy,
> > -                                                &storageCtl);
> > -        VBOX_UTF16_FREE(sName);
> > -        VBOX_RELEASE(storageCtl);
> > -    }
> > -
> >      for (i = 0; i < def->ndisks; i++) {
> >          disk = def->disks[i];
> >          src = virDomainDiskGetSource(disk);
> > @@ -1066,21 +1180,28 @@ vboxAttachDrives(virDomainDefPtr def,
> > vboxDriverPtr data, IMachine *machine)
> >  
> >          switch ((virDomainDiskBus) disk->bus) {
> >          case VIR_DOMAIN_DISK_BUS_IDE:
> > -            VBOX_UTF8_TO_UTF16("IDE Controller", &storageCtlName);
> > +            VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_IDE_NAME,
> > &storageCtlName);
> >              devicePort = def->disks[i]->info.addr.drive.bus;
> >              deviceSlot = def->disks[i]->info.addr.drive.unit;
> >  
> >              break;
> >          case VIR_DOMAIN_DISK_BUS_SATA:
> > -            VBOX_UTF8_TO_UTF16("SATA Controller",
> > &storageCtlName);
> > +            VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SATA_NAME,
> > &storageCtlName);
> >  
> >              break;
> >          case VIR_DOMAIN_DISK_BUS_SCSI:
> > -            VBOX_UTF8_TO_UTF16("SCSI Controller",
> > &storageCtlName);
> > +            VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SCSI_NAME,
> > &storageCtlName);
> > +
> > +            model = virDomainDeviceFindControllerModel(def, &disk-
> > >info,
> > +                                                       VIR_DOMAIN_
> > CONTROLLER_TYPE_SCSI);
> > +            if (model ==
> > VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1068) {
> > +                VBOX_UTF16_FREE(storageCtlName);
> > +                VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SAS_NAME,
> > &storageCtlName);
> > +            }
> >  
> >              break;
> >          case VIR_DOMAIN_DISK_BUS_FDC:
> > -            VBOX_UTF8_TO_UTF16("Floppy Controller",
> > &storageCtlName);
> > +            VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_FLOPPY_NAME,
> > &storageCtlName);
> >              devicePort = 0;
> >              deviceSlot = disk->info.addr.drive.unit;
> >  
> > @@ -1148,7 +1269,6 @@ vboxAttachDrives(virDomainDefPtr def,
> > vboxDriverPtr data, IMachine *machine)
> >                  gVBoxAPI.UIMedium.SetType(medium,
> > MediumType_Normal);
> >                  VIR_DEBUG("Setting hard disk type to normal");
> >              }
> > -
> >          }
> >  
> >          VBOX_UTF16_TO_UTF8(storageCtlName, &controllerName);
> > @@ -1918,6 +2038,8 @@ vboxDomainDefineXMLFlags(virConnectPtr conn,
> > const char *xml, unsigned int flags
> >      gVBoxAPI.UISession.GetMachine(data->vboxSession, &machine);
> >  
> >      vboxSetBootDeviceOrder(def, data, machine);
> > +    if (vboxAttachStorageControllers(def, data, machine) < 0)
> > +        goto cleanup;
> >      if (vboxAttachDrives(def, data, machine) < 0)
> >          goto cleanup;
> >      vboxAttachSound(def, machine);
> > diff --git a/src/vbox/vbox_common.h b/src/vbox/vbox_common.h
> > index b08ad1e3e..3340374c1 100644
> > --- a/src/vbox/vbox_common.h
> > +++ b/src/vbox/vbox_common.h
> > @@ -326,6 +326,14 @@ enum HardDiskVariant
> >  # define VBOX_E_INVALID_SESSION_STATE 0x80BB000B
> >  # define VBOX_E_OBJECT_IN_USE 0x80BB000C
> >  
> > +/* VBOX storage controller name definitions */
> > +
> > +# define VBOX_CONTROLLER_IDE_NAME "IDE Controller"
> > +# define VBOX_CONTROLLER_FLOPPY_NAME "Floppy Controller"
> > +# define VBOX_CONTROLLER_SATA_NAME "SATA Controller"
> > +# define VBOX_CONTROLLER_SCSI_NAME "SCSI Controller"
> > +# define VBOX_CONTROLLER_SAS_NAME "SAS Controller"
> > +
> >  /* Simplied definitions in vbox_CAPI_*.h */
> >  
> >  typedef void const *PCVBOXXPCOM;
> > 




More information about the libvir-list mailing list