mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-23 14:15:28 +00:00
vbox: Rewrite vboxDomainAttachDevice
This commit is contained in:
parent
400bdccb2a
commit
2b5e727413
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user