---
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