[libvirt] [PATCH 44/66] vbox: Rewrite vboxDomainAttachDevice

Taowei uaedante at gmail.com
Mon Aug 11 10:06:47 UTC 2014


---
 src/vbox/vbox_common.c        |  117 ++++++++++++++++++++++++++++++++++
 src/vbox/vbox_tmpl.c          |  141 +++++++++++++++++++++++++++++++++++++++--
 src/vbox/vbox_uniformed_api.h |    3 +
 3 files changed, 256 insertions(+), 5 deletions(-)

diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
index 5b0706f..84d82d7 100644
--- a/src/vbox/vbox_common.c
+++ b/src/vbox/vbox_common.c
@@ -4038,3 +4038,120 @@ int vboxConnectNumOfDefinedDomains(virConnectPtr conn)
     gVBoxAPI.UArray.vboxArrayRelease(&machines);
     return ret;
 }
+
+static int vboxDomainAttachDeviceImpl(virDomainPtr dom,
+                                      const char *xml,
+                                      int mediaChangeOnly ATTRIBUTE_UNUSED)
+{
+    VBOX_OBJECT_CHECK(dom->conn, int, -1);
+    IMachine *machine    = NULL;
+    vboxIIDUnion iid;
+    PRUint32 state;
+    virDomainDefPtr def  = NULL;
+    virDomainDeviceDefPtr dev  = NULL;
+    nsresult rc;
+
+    VBOX_IID_INITIALIZE(&iid);
+    if (VIR_ALLOC(def) < 0)
+        return ret;
+
+    if (VIR_STRDUP(def->os.type, "hvm") < 0)
+        goto cleanup;
+
+    dev = virDomainDeviceDefParse(xml, def, data->caps, data->xmlopt,
+                                  VIR_DOMAIN_XML_INACTIVE);
+    if (dev == NULL)
+        goto cleanup;
+
+    if (openSessionForMachine(data, dom->uuid, &iid, &machine, false) < 0)
+        goto cleanup;
+
+    if (!machine)
+        goto cleanup;
+
+    gVBoxAPI.UIMachine.GetState(machine, &state);
+
+    if (gVBoxAPI.machineStateChecker.Running(state) ||
+        gVBoxAPI.machineStateChecker.Paused(state)) {
+        rc = gVBoxAPI.UISession.OpenExisting(data, &iid, machine);
+    } else {
+        rc = gVBoxAPI.UISession.Open(data, &iid, machine);
+    }
+
+    if (NS_FAILED(rc))
+        goto cleanup;
+
+    rc = gVBoxAPI.UISession.GetMachine(data->vboxSession, &machine);
+
+    if (NS_SUCCEEDED(rc) && machine) {
+        /* ret = -VIR_ERR_ARGUMENT_UNSUPPORTED means the current device don't support hotplug. */
+        ret = -VIR_ERR_ARGUMENT_UNSUPPORTED;
+        if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
+            if (gVBoxAPI.oldMediumInterface) {
+                const char *src = virDomainDiskGetSource(dev->data.disk);
+                int type = virDomainDiskGetType(dev->data.disk);
+
+                if (dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
+                    if (type == VIR_STORAGE_TYPE_FILE && src) {
+                        ret = gVBoxAPI.attachDVD(data, machine, src);
+                    } else if (type == VIR_STORAGE_TYPE_BLOCK) {
+                    }
+                } else if (dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
+                    if (type == VIR_STORAGE_TYPE_FILE && src) {
+                        ret = gVBoxAPI.attachFloppy(data, machine, src);
+                    } else if (type == VIR_STORAGE_TYPE_BLOCK) {
+                    }
+                }
+            }
+        } else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
+        } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
+            if (dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
+                if (dev->data.hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
+                }
+            }
+        } else if (dev->type == VIR_DOMAIN_DEVICE_FS &&
+                   dev->data.fs->type == VIR_DOMAIN_FS_TYPE_MOUNT) {
+            PRUnichar *nameUtf16;
+            PRUnichar *hostPathUtf16;
+            PRBool writable;
+
+            VBOX_UTF8_TO_UTF16(dev->data.fs->dst, &nameUtf16);
+            VBOX_UTF8_TO_UTF16(dev->data.fs->src, &hostPathUtf16);
+            writable = !dev->data.fs->readonly;
+
+            rc = gVBoxAPI.UIMachine.CreateSharedFolder(machine, nameUtf16, hostPathUtf16,
+                                                       writable, PR_FALSE);
+
+            if (NS_FAILED(rc)) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("could not attach shared folder '%s', rc=%08x"),
+                               dev->data.fs->dst, (unsigned)rc);
+                ret = -1;
+            } else {
+                ret = 0;
+            }
+
+            VBOX_UTF16_FREE(nameUtf16);
+            VBOX_UTF16_FREE(hostPathUtf16);
+        }
+        gVBoxAPI.UIMachine.SaveSettings(machine);
+        VBOX_RELEASE(machine);
+
+        if (ret == -VIR_ERR_ARGUMENT_UNSUPPORTED) {
+            virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, _("Unsupported device type %d"), dev->type);
+            ret = -1;
+        }
+    }
+    gVBoxAPI.UISession.Close(data->vboxSession);
+
+ cleanup:
+    vboxIIDUnalloc(&iid);
+    virDomainDefFree(def);
+    virDomainDeviceDefFree(dev);
+    return ret;
+}
+
+int vboxDomainAttachDevice(virDomainPtr dom, const char *xml)
+{
+    return vboxDomainAttachDeviceImpl(dom, xml, 0);
+}
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 3651498..b80810d 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -1649,11 +1649,6 @@ static int vboxDomainAttachDeviceImpl(virDomainPtr dom,
     return ret;
 }
 
-static int vboxDomainAttachDevice(virDomainPtr dom, const char *xml)
-{
-    return vboxDomainAttachDeviceImpl(dom, xml, 0);
-}
-
 static int
 vboxDomainAttachDeviceFlags(virDomainPtr dom, const char *xml,
                             unsigned int flags)
@@ -7812,6 +7807,63 @@ _dumpDVD(virDomainDefPtr def,
     VBOX_RELEASE(dvdDrive);
 }
 
+static int
+_attachDVD(vboxGlobalData *data, IMachine *machine, const char *src)
+{
+    IDVDDrive *dvdDrive     = NULL;
+    IDVDImage *dvdImage     = NULL;
+    PRUnichar *dvdfileUtf16 = NULL;
+    vboxIID dvduuid = VBOX_IID_INITIALIZER;
+    vboxIID dvdemptyuuid = VBOX_IID_INITIALIZER;
+    nsresult rc;
+    int ret = -1;
+
+    /* Currently CDROM/DVD Drive is always IDE
+     * Secondary Master so neglecting the following
+     * parameter dev->data.disk->bus
+     */
+    machine->vtbl->GetDVDDrive(machine, &dvdDrive);
+    if (!dvdDrive)
+        return ret;
+
+    VBOX_UTF8_TO_UTF16(src, &dvdfileUtf16);
+
+    data->vboxObj->vtbl->FindDVDImage(data->vboxObj, dvdfileUtf16, &dvdImage);
+    if (!dvdImage) {
+        data->vboxObj->vtbl->OpenDVDImage(data->vboxObj, dvdfileUtf16, dvdemptyuuid.value, &dvdImage);
+    }
+
+    if (!dvdImage)
+        goto cleanup;
+
+    rc = dvdImage->vtbl->imedium.GetId((IMedium *)dvdImage, &dvduuid.value);
+    if (NS_FAILED(rc)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("can't get the uuid of the file to "
+                         "be attached to cdrom: %s, rc=%08x"),
+                       src, (unsigned)rc);
+    } else {
+        /* unmount the previous mounted image */
+        dvdDrive->vtbl->Unmount(dvdDrive);
+        rc = dvdDrive->vtbl->MountImage(dvdDrive, dvduuid.value);
+        if (NS_FAILED(rc)) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("could not attach the file to cdrom: %s, rc=%08x"),
+                           src, (unsigned)rc);
+        } else {
+            ret = 0;
+            DEBUGIID("CD/DVD Image UUID:", dvduuid.value);
+        }
+    }
+
+    VBOX_MEDIUM_RELEASE(dvdImage);
+ cleanup:
+    vboxIIDUnalloc(&dvduuid);
+    VBOX_UTF16_FREE(dvdfileUtf16);
+    VBOX_RELEASE(dvdDrive);
+    return ret;
+}
+
 static void
 _dumpFloppy(virDomainDefPtr def,
             vboxGlobalData *data,
@@ -7871,6 +7923,65 @@ _dumpFloppy(virDomainDefPtr def,
     VBOX_RELEASE(floppyDrive);
 }
 
+static int
+_attachFloppy(vboxGlobalData *data, IMachine *machine, const char *src)
+{
+    IFloppyDrive *floppyDrive;
+    IFloppyImage *floppyImage   = NULL;
+    PRUnichar *fdfileUtf16      = NULL;
+    vboxIID fduuid = VBOX_IID_INITIALIZER;
+    vboxIID fdemptyuuid = VBOX_IID_INITIALIZER;
+    nsresult rc;
+    int ret = -1;
+
+    machine->vtbl->GetFloppyDrive(machine, &floppyDrive);
+    if (!floppyDrive)
+        return ret;
+
+    rc = floppyDrive->vtbl->SetEnabled(floppyDrive, 1);
+    if (NS_FAILED(rc))
+        goto cleanup;
+
+    VBOX_UTF8_TO_UTF16(src, &fdfileUtf16);
+    rc = data->vboxObj->vtbl->FindFloppyImage(data->vboxObj,
+                                              fdfileUtf16,
+                                              &floppyImage);
+
+    if (!floppyImage) {
+        data->vboxObj->vtbl->OpenFloppyImage(data->vboxObj,
+                                             fdfileUtf16,
+                                             fdemptyuuid.value,
+                                             &floppyImage);
+    }
+
+    if (floppyImage) {
+        rc = floppyImage->vtbl->imedium.GetId((IMedium *)floppyImage, &fduuid.value);
+        if (NS_FAILED(rc)) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("can't get the uuid of the file to be "
+                             "attached to floppy drive: %s, rc=%08x"),
+                           src, (unsigned)rc);
+        } else {
+            rc = floppyDrive->vtbl->MountImage(floppyDrive, fduuid.value);
+            if (NS_FAILED(rc)) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("could not attach the file to floppy drive: %s, rc=%08x"),
+                               src, (unsigned)rc);
+            } else {
+                ret = 0;
+                DEBUGIID("attached floppy, UUID:", fduuid.value);
+            }
+        }
+        VBOX_MEDIUM_RELEASE(floppyImage);
+    }
+    vboxIIDUnalloc(&fduuid);
+    VBOX_UTF16_FREE(fdfileUtf16);
+
+ cleanup:
+    VBOX_RELEASE(floppyDrive);
+    return ret;
+}
+
 #else  /* VBOX_API_VERSION >= 3001000 */
 
 static void
@@ -7889,6 +8000,15 @@ _dumpDVD(virDomainDefPtr def ATTRIBUTE_UNUSED,
     vboxUnsupported();
 }
 
+static int
+_attachDVD(vboxGlobalData *data ATTRIBUTE_UNUSED,
+           IMachine *machine ATTRIBUTE_UNUSED,
+           const char *src ATTRIBUTE_UNUSED)
+{
+    vboxUnsupported();
+    return 0;
+}
+
 static void
 _dumpFloppy(virDomainDefPtr def ATTRIBUTE_UNUSED,
             vboxGlobalData *data ATTRIBUTE_UNUSED,
@@ -7897,6 +8017,15 @@ _dumpFloppy(virDomainDefPtr def ATTRIBUTE_UNUSED,
     vboxUnsupported();
 }
 
+static int
+_attachFloppy(vboxGlobalData *data ATTRIBUTE_UNUSED,
+              IMachine *machine ATTRIBUTE_UNUSED,
+              const char *src ATTRIBUTE_UNUSED)
+{
+    vboxUnsupported();
+    return 0;
+}
+
 #endif  /* VBOX_API_VERSION >= 3001000 */
 
 static void _pfnUninitialize(vboxGlobalData *data)
@@ -9549,7 +9678,9 @@ void NAME(InstallUniformedAPI)(vboxUniformedAPI *pVBoxAPI)
     pVBoxAPI->vboxConvertState = _vboxConvertState;
     pVBoxAPI->dumpIDEHDDsOld = _dumpIDEHDDsOld;
     pVBoxAPI->dumpDVD = _dumpDVD;
+    pVBoxAPI->attachDVD = _attachDVD;
     pVBoxAPI->dumpFloppy = _dumpFloppy;
+    pVBoxAPI->attachFloppy = _attachFloppy;
     pVBoxAPI->UPFN = _UPFN;
     pVBoxAPI->UIID = _UIID;
     pVBoxAPI->UArray = _UArray;
diff --git a/src/vbox/vbox_uniformed_api.h b/src/vbox/vbox_uniformed_api.h
index 9488999..1f82616 100644
--- a/src/vbox/vbox_uniformed_api.h
+++ b/src/vbox/vbox_uniformed_api.h
@@ -433,7 +433,9 @@ typedef struct {
     virDomainState (*vboxConvertState)(PRUint32 state);
     void (*dumpIDEHDDsOld)(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine);
     void (*dumpDVD)(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine);
+    int (*attachDVD)(vboxGlobalData *data, IMachine *machine, const char *src);
     void (*dumpFloppy)(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine);
+    int (*attachFloppy)(vboxGlobalData *data, IMachine *machine, const char *src);
     vboxUniformedPFN UPFN;
     vboxUniformedIID UIID;
     vboxUniformedArray UArray;
@@ -522,6 +524,7 @@ char *vboxDomainGetXMLDesc(virDomainPtr dom, unsigned int flags);
 int vboxConnectListDefinedDomains(virConnectPtr conn,
                                   char ** const names, int maxnames);
 int vboxConnectNumOfDefinedDomains(virConnectPtr conn);
+int vboxDomainAttachDevice(virDomainPtr dom, const char *xml);
 
 /* Version specified functions for installing uniformed API */
 void vbox22InstallUniformedAPI(vboxUniformedAPI *pVBoxAPI);
-- 
1.7.9.5




More information about the libvir-list mailing list