[libvirt] [PATCH 47/66] vbox: Rewrite vboxDomainDetachDevice

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


---
 src/vbox/vbox_common.c        |  101 +++++++++++++++++++
 src/vbox/vbox_tmpl.c          |  221 ++++++++++++++++-------------------------
 src/vbox/vbox_uniformed_api.h |    4 +
 3 files changed, 190 insertions(+), 136 deletions(-)

diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
index 71c97a0..f6ea357 100644
--- a/src/vbox/vbox_common.c
+++ b/src/vbox/vbox_common.c
@@ -4185,3 +4185,104 @@ int vboxDomainUpdateDeviceFlags(virDomainPtr dom, const char *xml,
 
     return vboxDomainAttachDeviceImpl(dom, xml, 1);
 }
+
+int vboxDomainDetachDevice(virDomainPtr dom, const char *xml)
+{
+    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) {
+                int type = virDomainDiskGetType(dev->data.disk);
+
+                if (dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
+                    if (type == VIR_STORAGE_TYPE_FILE) {
+                        ret = gVBoxAPI.detachDVD(machine);
+                    } else if (type == VIR_STORAGE_TYPE_BLOCK) {
+                    }
+                } else if (dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
+                    if (type == VIR_STORAGE_TYPE_FILE) {
+                        ret = gVBoxAPI.detachFloppy(machine);
+                    } 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;
+
+            VBOX_UTF8_TO_UTF16(dev->data.fs->dst, &nameUtf16);
+
+            rc = gVBoxAPI.UIMachine.RemoveSharedFolder(machine, nameUtf16);
+
+            if (NS_FAILED(rc)) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("could not detach shared folder '%s', rc=%08x"),
+                               dev->data.fs->dst, (unsigned)rc);
+            } else {
+                ret = 0;
+            }
+
+            VBOX_UTF16_FREE(nameUtf16);
+        }
+        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;
+}
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index dd93e2a..65f2d34 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -1450,142 +1450,6 @@ _vboxAttachDrivesOld(virDomainDefPtr def ATTRIBUTE_UNUSED,
 
 #endif /* VBOX_API_VERSION >= 4000000 */
 
-static int vboxDomainDetachDevice(virDomainPtr dom, const char *xml)
-{
-    VBOX_OBJECT_CHECK(dom->conn, int, -1);
-    IMachine *machine    = NULL;
-    vboxIID iid = VBOX_IID_INITIALIZER;
-    PRUint32 state       = MachineState_Null;
-    virDomainDefPtr def  = NULL;
-    virDomainDeviceDefPtr dev  = NULL;
-    nsresult rc;
-
-    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;
-
-    vboxIIDFromUUID(&iid, dom->uuid);
-    rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
-    if (NS_FAILED(rc)) {
-        virReportError(VIR_ERR_NO_DOMAIN, "%s",
-                       _("no domain with matching uuid"));
-        goto cleanup;
-    }
-
-    if (machine) {
-        machine->vtbl->GetState(machine, &state);
-
-        if ((state == MachineState_Running) ||
-            (state == MachineState_Paused)) {
-            rc = VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
-        } else {
-            rc = VBOX_SESSION_OPEN(iid.value, machine);
-        }
-
-        if (NS_SUCCEEDED(rc)) {
-            rc = data->vboxSession->vtbl->GetMachine(data->vboxSession, &machine);
-            if (NS_SUCCEEDED(rc) && machine) {
-                if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
-#if VBOX_API_VERSION < 3001000
-                    int type = virDomainDiskGetType(dev->data.disk);
-
-                    if (dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
-                        if (type == VIR_STORAGE_TYPE_FILE) {
-                            IDVDDrive *dvdDrive = NULL;
-                            /* 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) {
-                                rc = dvdDrive->vtbl->Unmount(dvdDrive);
-                                if (NS_FAILED(rc)) {
-                                    virReportError(VIR_ERR_INTERNAL_ERROR,
-                                                   _("could not de-attach the mounted ISO, rc=%08x"),
-                                                   (unsigned)rc);
-                                } else {
-                                    ret = 0;
-                                }
-                                VBOX_RELEASE(dvdDrive);
-                            }
-                        } else if (type == VIR_STORAGE_TYPE_BLOCK) {
-                        }
-                    } else if (dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
-                        if (type == VIR_STORAGE_TYPE_FILE) {
-                            IFloppyDrive *floppyDrive;
-                            machine->vtbl->GetFloppyDrive(machine, &floppyDrive);
-                            if (floppyDrive) {
-                                PRBool enabled = PR_FALSE;
-
-                                floppyDrive->vtbl->GetEnabled(floppyDrive, &enabled);
-                                if (enabled) {
-                                    rc = floppyDrive->vtbl->Unmount(floppyDrive);
-                                    if (NS_FAILED(rc)) {
-                                        virReportError(VIR_ERR_INTERNAL_ERROR,
-                                                       _("could not attach the file "
-                                                         "to floppy drive, rc=%08x"),
-                                                       (unsigned)rc);
-                                    } else {
-                                        ret = 0;
-                                    }
-                                } else {
-                                    /* If you are here means floppy drive is already unmounted
-                                     * so don't flag error, just say everything is fine and quit
-                                     */
-                                    ret = 0;
-                                }
-                                VBOX_RELEASE(floppyDrive);
-                            }
-                        } else if (type == VIR_STORAGE_TYPE_BLOCK) {
-                        }
-                    }
-#else  /* VBOX_API_VERSION >= 3001000 */
-#endif /* VBOX_API_VERSION >= 3001000 */
-                } 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;
-
-                    VBOX_UTF8_TO_UTF16(dev->data.fs->dst, &nameUtf16);
-
-                    rc = machine->vtbl->RemoveSharedFolder(machine, nameUtf16);
-
-                    if (NS_FAILED(rc)) {
-                        virReportError(VIR_ERR_INTERNAL_ERROR,
-                                       _("could not detach shared folder '%s', rc=%08x"),
-                                       dev->data.fs->dst, (unsigned)rc);
-                    } else {
-                        ret = 0;
-                    }
-
-                    VBOX_UTF16_FREE(nameUtf16);
-                }
-                machine->vtbl->SaveSettings(machine);
-                VBOX_RELEASE(machine);
-            }
-            VBOX_SESSION_CLOSE();
-        }
-    }
-
- cleanup:
-    vboxIIDUnalloc(&iid);
-    virDomainDefFree(def);
-    virDomainDeviceDefFree(dev);
-    return ret;
-}
-
 static int
 vboxDomainDetachDeviceFlags(virDomainPtr dom, const char *xml,
                             unsigned int flags)
@@ -7634,6 +7498,33 @@ _attachDVD(vboxGlobalData *data, IMachine *machine, const char *src)
     return ret;
 }
 
+static int
+_detachDVD(IMachine *machine)
+{
+    IDVDDrive *dvdDrive = NULL;
+    int ret = -1;
+    nsresult rc;
+    /* 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;
+
+    rc = dvdDrive->vtbl->Unmount(dvdDrive);
+    if (NS_FAILED(rc)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("could not de-attach the mounted ISO, rc=%08x"),
+                       (unsigned)rc);
+    } else {
+        ret = 0;
+    }
+    VBOX_RELEASE(dvdDrive);
+
+    return ret;
+}
+
 static void
 _dumpFloppy(virDomainDefPtr def,
             vboxGlobalData *data,
@@ -7752,6 +7643,41 @@ _attachFloppy(vboxGlobalData *data, IMachine *machine, const char *src)
     return ret;
 }
 
+static int
+_detachFloppy(IMachine *machine)
+{
+    IFloppyDrive *floppyDrive;
+    int ret = -1;
+    nsresult rc;
+
+    machine->vtbl->GetFloppyDrive(machine, &floppyDrive);
+    if (!floppyDrive)
+        return ret;
+
+    PRBool enabled = PR_FALSE;
+
+    floppyDrive->vtbl->GetEnabled(floppyDrive, &enabled);
+    if (enabled) {
+        rc = floppyDrive->vtbl->Unmount(floppyDrive);
+        if (NS_FAILED(rc)) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("could not attach the file "
+                             "to floppy drive, rc=%08x"),
+                           (unsigned)rc);
+        } else {
+            ret = 0;
+        }
+    } else {
+        /* If you are here means floppy drive is already unmounted
+         * so don't flag error, just say everything is fine and quit
+         */
+        ret = 0;
+    }
+    VBOX_RELEASE(floppyDrive);
+
+    return ret;
+}
+
 #else  /* VBOX_API_VERSION >= 3001000 */
 
 static void
@@ -7779,6 +7705,13 @@ _attachDVD(vboxGlobalData *data ATTRIBUTE_UNUSED,
     return 0;
 }
 
+static int
+_detachDVD(IMachine *machine ATTRIBUTE_UNUSED)
+{
+    vboxUnsupported();
+    return 0;
+}
+
 static void
 _dumpFloppy(virDomainDefPtr def ATTRIBUTE_UNUSED,
             vboxGlobalData *data ATTRIBUTE_UNUSED,
@@ -7796,6 +7729,13 @@ _attachFloppy(vboxGlobalData *data ATTRIBUTE_UNUSED,
     return 0;
 }
 
+static int
+_detachFloppy(IMachine *machine ATTRIBUTE_UNUSED)
+{
+    vboxUnsupported();
+    return 0;
+}
+
 #endif  /* VBOX_API_VERSION >= 3001000 */
 
 static void _pfnUninitialize(vboxGlobalData *data)
@@ -8081,6 +8021,12 @@ _machineCreateSharedFolder(IMachine *machine, PRUnichar *name,
 }
 
 static nsresult
+_machineRemoveSharedFolder(IMachine *machine, PRUnichar *name)
+{
+    return machine->vtbl->RemoveSharedFolder(machine, name);
+}
+
+static nsresult
 _machineLaunchVMProcess(vboxGlobalData *data,
                         IMachine *machine ATTRIBUTE_UNUSED,
                         vboxIIDUnion *iidu ATTRIBUTE_UNUSED,
@@ -9245,6 +9191,7 @@ static vboxUniformedIMachine _UIMachine = {
     .GetStorageControllerByName = _machineGetStorageControllerByName,
     .AttachDevice = _machineAttachDevice,
     .CreateSharedFolder = _machineCreateSharedFolder,
+    .RemoveSharedFolder = _machineRemoveSharedFolder,
     .LaunchVMProcess = _machineLaunchVMProcess,
     .GetAccessible = _machineGetAccessible,
     .GetState = _machineGetState,
@@ -9449,8 +9396,10 @@ void NAME(InstallUniformedAPI)(vboxUniformedAPI *pVBoxAPI)
     pVBoxAPI->dumpIDEHDDsOld = _dumpIDEHDDsOld;
     pVBoxAPI->dumpDVD = _dumpDVD;
     pVBoxAPI->attachDVD = _attachDVD;
+    pVBoxAPI->detachDVD = _detachDVD;
     pVBoxAPI->dumpFloppy = _dumpFloppy;
     pVBoxAPI->attachFloppy = _attachFloppy;
+    pVBoxAPI->detachFloppy = _detachFloppy;
     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 493d12c..357590c 100644
--- a/src/vbox/vbox_uniformed_api.h
+++ b/src/vbox/vbox_uniformed_api.h
@@ -201,6 +201,7 @@ typedef struct {
     nsresult (*CreateSharedFolder)(IMachine *machine, PRUnichar *name,
                                    PRUnichar *hostPath, PRBool writable,
                                    PRBool automount);
+    nsresult (*RemoveSharedFolder)(IMachine *machine, PRUnichar *name);
     nsresult (*LaunchVMProcess)(vboxGlobalData *data, IMachine *machine,
                                 vboxIIDUnion *iidu,
                                 PRUnichar *sessionType, PRUnichar *env,
@@ -434,8 +435,10 @@ typedef struct {
     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);
+    int (*detachDVD)(IMachine *machine);
     void (*dumpFloppy)(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine);
     int (*attachFloppy)(vboxGlobalData *data, IMachine *machine, const char *src);
+    int (*detachFloppy)(IMachine *machine);
     vboxUniformedPFN UPFN;
     vboxUniformedIID UIID;
     vboxUniformedArray UArray;
@@ -529,6 +532,7 @@ int vboxDomainAttachDeviceFlags(virDomainPtr dom, const char *xml,
                                 unsigned int flags);
 int vboxDomainUpdateDeviceFlags(virDomainPtr dom, const char *xml,
                                 unsigned int flags);
+int vboxDomainDetachDevice(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