vbox: Rewrite vboxDomainAttachDevice

This commit is contained in:
Taowei 2014-08-11 18:06:47 +08:00 committed by Michal Privoznik
parent 400bdccb2a
commit 2b5e727413
3 changed files with 256 additions and 5 deletions

View File

@ -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);
}

View File

@ -1650,11 +1650,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)
@ -7813,6 +7808,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,
@ -7872,6 +7924,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
@ -7890,6 +8001,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,
@ -7898,6 +8018,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)
@ -9550,7 +9679,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;

View File

@ -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);