mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-24 22:55:23 +00:00
Make hotplug use new device_add where possible
Since QEMU startup uses the new -device argument, the hotplug code needs todo the same. This converts disk, network and host device hotplug to use the device_add command * src/qemu/qemu_driver.c: Use new device_add monitor APIs whereever possible
This commit is contained in:
parent
5ec6cf7fb8
commit
264e98d6a8
@ -5192,12 +5192,14 @@ error:
|
|||||||
static int qemudDomainAttachPciDiskDevice(virConnectPtr conn,
|
static int qemudDomainAttachPciDiskDevice(virConnectPtr conn,
|
||||||
struct qemud_driver *driver,
|
struct qemud_driver *driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainDiskDefPtr disk)
|
virDomainDiskDefPtr disk,
|
||||||
|
int qemuCmdFlags)
|
||||||
{
|
{
|
||||||
int i, ret;
|
int i, ret;
|
||||||
const char* type = virDomainDiskBusTypeToString(disk->bus);
|
const char* type = virDomainDiskBusTypeToString(disk->bus);
|
||||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
virDomainDevicePCIAddress guestAddr;
|
char *devstr = NULL;
|
||||||
|
char *drivestr = NULL;
|
||||||
|
|
||||||
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
||||||
if (STREQ(vm->def->disks[i]->dst, disk->dst)) {
|
if (STREQ(vm->def->disks[i]->dst, disk->dst)) {
|
||||||
@ -5212,28 +5214,52 @@ static int qemudDomainAttachPciDiskDevice(virConnectPtr conn,
|
|||||||
driver->securityDriver->domainSetSecurityImageLabel(conn, vm, disk) < 0)
|
driver->securityDriver->domainSetSecurityImageLabel(conn, vm, disk) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
|
||||||
|
if (!(drivestr = qemuBuildDriveStr(disk, 0, qemuCmdFlags)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!(devstr = qemuBuildDriveDevStr(NULL, disk)))
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0) {
|
if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0) {
|
||||||
virReportOOMError(conn);
|
virReportOOMError(conn);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
||||||
ret = qemuMonitorAddPCIDisk(priv->mon,
|
if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
|
||||||
disk->src,
|
ret = qemuMonitorAddDrive(priv->mon, drivestr);
|
||||||
type,
|
if (ret == 0)
|
||||||
&guestAddr);
|
qemuMonitorAddDevice(priv->mon, devstr);
|
||||||
|
/* XXX remove the drive upon fail */
|
||||||
|
} else {
|
||||||
|
virDomainDevicePCIAddress guestAddr;
|
||||||
|
ret = qemuMonitorAddPCIDisk(priv->mon,
|
||||||
|
disk->src,
|
||||||
|
type,
|
||||||
|
&guestAddr);
|
||||||
|
if (ret == 0) {
|
||||||
|
disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
|
||||||
|
memcpy(&disk->info.addr.pci, &guestAddr, sizeof(guestAddr));
|
||||||
|
}
|
||||||
|
}
|
||||||
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
|
|
||||||
memcpy(&disk->info.addr.pci, &guestAddr, sizeof(guestAddr));
|
|
||||||
virDomainDiskInsertPreAlloced(vm->def, disk);
|
virDomainDiskInsertPreAlloced(vm->def, disk);
|
||||||
|
|
||||||
|
VIR_FREE(devstr);
|
||||||
|
VIR_FREE(drivestr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
VIR_FREE(devstr);
|
||||||
|
VIR_FREE(drivestr);
|
||||||
|
|
||||||
if (driver->securityDriver &&
|
if (driver->securityDriver &&
|
||||||
driver->securityDriver->domainRestoreSecurityImageLabel &&
|
driver->securityDriver->domainRestoreSecurityImageLabel &&
|
||||||
driver->securityDriver->domainRestoreSecurityImageLabel(conn, vm, disk) < 0)
|
driver->securityDriver->domainRestoreSecurityImageLabel(conn, vm, disk) < 0)
|
||||||
@ -5246,10 +5272,13 @@ error:
|
|||||||
static int qemudDomainAttachPciControllerDevice(virConnectPtr conn,
|
static int qemudDomainAttachPciControllerDevice(virConnectPtr conn,
|
||||||
struct qemud_driver *driver,
|
struct qemud_driver *driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainControllerDefPtr controller)
|
virDomainControllerDefPtr controller,
|
||||||
|
int qemuCmdFlags)
|
||||||
{
|
{
|
||||||
int i, ret;
|
int i;
|
||||||
|
int ret = -1;
|
||||||
const char* type = virDomainControllerTypeToString(controller->type);
|
const char* type = virDomainControllerTypeToString(controller->type);
|
||||||
|
char *devstr = NULL;
|
||||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
|
|
||||||
for (i = 0 ; i < vm->def->ncontrollers ; i++) {
|
for (i = 0 ; i < vm->def->ncontrollers ; i++) {
|
||||||
@ -5262,15 +5291,24 @@ static int qemudDomainAttachPciControllerDevice(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(devstr = qemuBuildControllerDevStr(controller))) {
|
||||||
|
virReportOOMError(NULL);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
if (VIR_REALLOC_N(vm->def->controllers, vm->def->ncontrollers+1) < 0) {
|
if (VIR_REALLOC_N(vm->def->controllers, vm->def->ncontrollers+1) < 0) {
|
||||||
virReportOOMError(conn);
|
virReportOOMError(NULL);
|
||||||
return -1;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
||||||
ret = qemuMonitorAttachPCIDiskController(priv->mon,
|
if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
|
||||||
type,
|
ret = qemuMonitorAddDevice(priv->mon, devstr);
|
||||||
&controller->info.addr.pci);
|
} else {
|
||||||
|
ret = qemuMonitorAttachPCIDiskController(priv->mon,
|
||||||
|
type,
|
||||||
|
&controller->info.addr.pci);
|
||||||
|
}
|
||||||
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
@ -5278,6 +5316,8 @@ static int qemudDomainAttachPciControllerDevice(virConnectPtr conn,
|
|||||||
virDomainControllerInsertPreAlloced(vm->def, controller);
|
virDomainControllerInsertPreAlloced(vm->def, controller);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(devstr);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5286,7 +5326,8 @@ static virDomainControllerDefPtr
|
|||||||
qemuDomainFindOrCreateSCSIDiskController(virConnectPtr conn,
|
qemuDomainFindOrCreateSCSIDiskController(virConnectPtr conn,
|
||||||
struct qemud_driver *driver,
|
struct qemud_driver *driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
int controller)
|
int controller,
|
||||||
|
int qemuCmdFlags)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
virDomainControllerDefPtr cont;
|
virDomainControllerDefPtr cont;
|
||||||
@ -5311,7 +5352,7 @@ qemuDomainFindOrCreateSCSIDiskController(virConnectPtr conn,
|
|||||||
|
|
||||||
VIR_INFO0("No SCSI controller present, hotplugging one");
|
VIR_INFO0("No SCSI controller present, hotplugging one");
|
||||||
if (qemudDomainAttachPciControllerDevice(conn, driver,
|
if (qemudDomainAttachPciControllerDevice(conn, driver,
|
||||||
vm, cont) < 0) {
|
vm, cont, qemuCmdFlags) < 0) {
|
||||||
VIR_FREE(cont);
|
VIR_FREE(cont);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -5327,9 +5368,9 @@ static int qemudDomainAttachSCSIDisk(virConnectPtr conn,
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
virDomainDeviceDriveAddress driveAddr;
|
|
||||||
virDomainControllerDefPtr cont;
|
virDomainControllerDefPtr cont;
|
||||||
char *drivestr = NULL;
|
char *drivestr = NULL;
|
||||||
|
char *devstr = NULL;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
||||||
@ -5352,6 +5393,9 @@ static int qemudDomainAttachSCSIDisk(virConnectPtr conn,
|
|||||||
if (!(drivestr = qemuBuildDriveStr(disk, 0, qemuCmdFlags)))
|
if (!(drivestr = qemuBuildDriveStr(disk, 0, qemuCmdFlags)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
if ((qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) &&
|
||||||
|
!(devstr = qemuBuildDriveDevStr(NULL, disk)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
/* We should have an adddress now, so make sure */
|
/* We should have an adddress now, so make sure */
|
||||||
if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) {
|
if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) {
|
||||||
@ -5362,7 +5406,7 @@ static int qemudDomainAttachSCSIDisk(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0 ; i <= disk->info.addr.drive.controller ; i++) {
|
for (i = 0 ; i <= disk->info.addr.drive.controller ; i++) {
|
||||||
cont = qemuDomainFindOrCreateSCSIDiskController(conn, driver, vm, i);
|
cont = qemuDomainFindOrCreateSCSIDiskController(conn, driver, vm, i, qemuCmdFlags);
|
||||||
if (!cont)
|
if (!cont)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@ -5379,26 +5423,42 @@ static int qemudDomainAttachSCSIDisk(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
||||||
ret = qemuMonitorAttachDrive(priv->mon,
|
if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
|
||||||
drivestr,
|
ret = qemuMonitorAddDrive(priv->mon,
|
||||||
&cont->info.addr.pci,
|
drivestr);
|
||||||
&driveAddr);
|
if (ret == 0)
|
||||||
|
ret = qemuMonitorAddDevice(priv->mon,
|
||||||
|
devstr);
|
||||||
|
/* XXX should call 'drive_del' on error but this does not exist yet */
|
||||||
|
} else {
|
||||||
|
virDomainDeviceDriveAddress driveAddr;
|
||||||
|
ret = qemuMonitorAttachDrive(priv->mon,
|
||||||
|
drivestr,
|
||||||
|
&cont->info.addr.pci,
|
||||||
|
&driveAddr);
|
||||||
|
if (ret == 0) {
|
||||||
|
/* XXX we should probably validate that the addr matches
|
||||||
|
* our existing defined addr instead of overwriting */
|
||||||
|
disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE;
|
||||||
|
memcpy(&disk->info.addr.drive, &driveAddr, sizeof(driveAddr));
|
||||||
|
}
|
||||||
|
}
|
||||||
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/* XXX we should probably validate that the addr matches
|
|
||||||
* our existing defined addr instead of overwriting */
|
|
||||||
disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE;
|
|
||||||
memcpy(&disk->info.addr.drive, &driveAddr, sizeof(driveAddr));
|
|
||||||
virDomainDiskInsertPreAlloced(vm->def, disk);
|
virDomainDiskInsertPreAlloced(vm->def, disk);
|
||||||
|
|
||||||
|
VIR_FREE(devstr);
|
||||||
VIR_FREE(drivestr);
|
VIR_FREE(drivestr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
VIR_FREE(devstr);
|
||||||
VIR_FREE(drivestr);
|
VIR_FREE(drivestr);
|
||||||
|
|
||||||
if (driver->securityDriver &&
|
if (driver->securityDriver &&
|
||||||
driver->securityDriver->domainRestoreSecurityImageLabel &&
|
driver->securityDriver->domainRestoreSecurityImageLabel &&
|
||||||
driver->securityDriver->domainRestoreSecurityImageLabel(conn, vm, disk) < 0)
|
driver->securityDriver->domainRestoreSecurityImageLabel(conn, vm, disk) < 0)
|
||||||
@ -5411,10 +5471,13 @@ error:
|
|||||||
static int qemudDomainAttachUsbMassstorageDevice(virConnectPtr conn,
|
static int qemudDomainAttachUsbMassstorageDevice(virConnectPtr conn,
|
||||||
struct qemud_driver *driver,
|
struct qemud_driver *driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainDiskDefPtr disk)
|
virDomainDiskDefPtr disk,
|
||||||
|
int qemuCmdFlags)
|
||||||
{
|
{
|
||||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
char *drivestr = NULL;
|
||||||
|
char *devstr = NULL;
|
||||||
|
|
||||||
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
||||||
if (STREQ(vm->def->disks[i]->dst, disk->dst)) {
|
if (STREQ(vm->def->disks[i]->dst, disk->dst)) {
|
||||||
@ -5435,13 +5498,29 @@ static int qemudDomainAttachUsbMassstorageDevice(virConnectPtr conn,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
|
||||||
|
if (!(drivestr = qemuBuildDriveStr(disk, 0, qemuCmdFlags)))
|
||||||
|
goto error;
|
||||||
|
if (!(devstr = qemuBuildDriveDevStr(NULL, disk)))
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0) {
|
if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0) {
|
||||||
virReportOOMError(conn);
|
virReportOOMError(conn);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
||||||
ret = qemuMonitorAddUSBDisk(priv->mon, disk->src);
|
if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
|
||||||
|
ret = qemuMonitorAddDrive(priv->mon,
|
||||||
|
drivestr);
|
||||||
|
if (ret == 0)
|
||||||
|
ret = qemuMonitorAddDevice(priv->mon,
|
||||||
|
devstr);
|
||||||
|
/* XXX should call 'drive_del' on error but this does not exist yet */
|
||||||
|
} else {
|
||||||
|
ret = qemuMonitorAddUSBDisk(priv->mon, disk->src);
|
||||||
|
}
|
||||||
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -5449,9 +5528,15 @@ static int qemudDomainAttachUsbMassstorageDevice(virConnectPtr conn,
|
|||||||
|
|
||||||
virDomainDiskInsertPreAlloced(vm->def, disk);
|
virDomainDiskInsertPreAlloced(vm->def, disk);
|
||||||
|
|
||||||
|
VIR_FREE(devstr);
|
||||||
|
VIR_FREE(drivestr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
VIR_FREE(devstr);
|
||||||
|
VIR_FREE(drivestr);
|
||||||
|
|
||||||
if (driver->securityDriver &&
|
if (driver->securityDriver &&
|
||||||
driver->securityDriver->domainRestoreSecurityImageLabel &&
|
driver->securityDriver->domainRestoreSecurityImageLabel &&
|
||||||
driver->securityDriver->domainRestoreSecurityImageLabel(conn, vm, disk) < 0)
|
driver->securityDriver->domainRestoreSecurityImageLabel(conn, vm, disk) < 0)
|
||||||
@ -5594,12 +5679,14 @@ no_memory:
|
|||||||
static int qemudDomainAttachHostPciDevice(virConnectPtr conn,
|
static int qemudDomainAttachHostPciDevice(virConnectPtr conn,
|
||||||
struct qemud_driver *driver,
|
struct qemud_driver *driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainHostdevDefPtr hostdev)
|
virDomainHostdevDefPtr hostdev,
|
||||||
|
int qemuCmdFlags)
|
||||||
{
|
{
|
||||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
pciDevice *pci;
|
pciDevice *pci;
|
||||||
int ret;
|
int ret;
|
||||||
virDomainDevicePCIAddress guestAddr;
|
virDomainDevicePCIAddress guestAddr;
|
||||||
|
char *devstr = NULL;
|
||||||
|
|
||||||
if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0) {
|
if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0) {
|
||||||
virReportOOMError(conn);
|
virReportOOMError(conn);
|
||||||
@ -5626,10 +5713,17 @@ static int qemudDomainAttachHostPciDevice(virConnectPtr conn,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) &&
|
||||||
|
!(devstr = qemuBuildPCIHostdevDevStr(hostdev)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
||||||
ret = qemuMonitorAddPCIHostDevice(priv->mon,
|
if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)
|
||||||
&hostdev->source.subsys.u.pci,
|
ret = qemuMonitorAddDevice(priv->mon, devstr);
|
||||||
&guestAddr);
|
else
|
||||||
|
ret = qemuMonitorAddPCIHostDevice(priv->mon,
|
||||||
|
&hostdev->source.subsys.u.pci,
|
||||||
|
&guestAddr);
|
||||||
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error;
|
goto error;
|
||||||
@ -5638,9 +5732,12 @@ static int qemudDomainAttachHostPciDevice(virConnectPtr conn,
|
|||||||
|
|
||||||
vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
|
vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
|
||||||
|
|
||||||
|
VIR_FREE(devstr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
VIR_FREE(devstr);
|
||||||
pciDeviceListDel(conn, driver->activePciHostdevs, pci);
|
pciDeviceListDel(conn, driver->activePciHostdevs, pci);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@ -5650,39 +5747,50 @@ error:
|
|||||||
static int qemudDomainAttachHostUsbDevice(virConnectPtr conn,
|
static int qemudDomainAttachHostUsbDevice(virConnectPtr conn,
|
||||||
struct qemud_driver *driver,
|
struct qemud_driver *driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainHostdevDefPtr hostdev)
|
virDomainHostdevDefPtr hostdev,
|
||||||
|
int qemuCmdFlags)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
|
char *devstr = NULL;
|
||||||
|
|
||||||
|
if ((qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) &&
|
||||||
|
!(devstr = qemuBuildPCIHostdevDevStr(hostdev)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0) {
|
if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0) {
|
||||||
virReportOOMError(conn);
|
virReportOOMError(conn);
|
||||||
return -1;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
||||||
if (hostdev->source.subsys.u.usb.vendor) {
|
if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)
|
||||||
ret = qemuMonitorAddUSBDeviceMatch(priv->mon,
|
ret = qemuMonitorAddDevice(priv->mon, devstr);
|
||||||
hostdev->source.subsys.u.usb.vendor,
|
else
|
||||||
hostdev->source.subsys.u.usb.product);
|
|
||||||
} else {
|
|
||||||
ret = qemuMonitorAddUSBDeviceExact(priv->mon,
|
ret = qemuMonitorAddUSBDeviceExact(priv->mon,
|
||||||
hostdev->source.subsys.u.usb.bus,
|
hostdev->source.subsys.u.usb.bus,
|
||||||
hostdev->source.subsys.u.usb.device);
|
hostdev->source.subsys.u.usb.device);
|
||||||
}
|
|
||||||
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
||||||
|
if (ret < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
if (ret == 0)
|
vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
|
||||||
vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
|
|
||||||
|
|
||||||
return ret;
|
VIR_FREE(devstr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
VIR_FREE(devstr);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int qemudDomainAttachHostDevice(virConnectPtr conn,
|
static int qemudDomainAttachHostDevice(virConnectPtr conn,
|
||||||
struct qemud_driver *driver,
|
struct qemud_driver *driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainHostdevDefPtr hostdev)
|
virDomainHostdevDefPtr hostdev,
|
||||||
|
int qemuCmdFlags)
|
||||||
{
|
{
|
||||||
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
|
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
|
||||||
qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
||||||
@ -5698,12 +5806,14 @@ static int qemudDomainAttachHostDevice(virConnectPtr conn,
|
|||||||
|
|
||||||
switch (hostdev->source.subsys.type) {
|
switch (hostdev->source.subsys.type) {
|
||||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
|
||||||
if (qemudDomainAttachHostPciDevice(conn, driver, vm, hostdev) < 0)
|
if (qemudDomainAttachHostPciDevice(conn, driver, vm,
|
||||||
|
hostdev, qemuCmdFlags) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
|
||||||
if (qemudDomainAttachHostUsbDevice(conn, driver, vm, hostdev) < 0)
|
if (qemudDomainAttachHostUsbDevice(conn, driver, vm,
|
||||||
|
hostdev, qemuCmdFlags) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -5794,15 +5904,18 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
|
|||||||
|
|
||||||
case VIR_DOMAIN_DISK_DEVICE_DISK:
|
case VIR_DOMAIN_DISK_DEVICE_DISK:
|
||||||
if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
|
if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
|
||||||
ret = qemudDomainAttachUsbMassstorageDevice(dom->conn, driver, vm, dev->data.disk);
|
ret = qemudDomainAttachUsbMassstorageDevice(dom->conn, driver, vm,
|
||||||
|
dev->data.disk, qemuCmdFlags);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
dev->data.disk = NULL;
|
dev->data.disk = NULL;
|
||||||
} else if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
|
} else if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
|
||||||
ret = qemudDomainAttachPciDiskDevice(dom->conn, driver, vm, dev->data.disk);
|
ret = qemudDomainAttachPciDiskDevice(dom->conn, driver, vm,
|
||||||
|
dev->data.disk, qemuCmdFlags);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
dev->data.disk = NULL;
|
dev->data.disk = NULL;
|
||||||
} else if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
|
} else if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
|
||||||
ret = qemudDomainAttachSCSIDisk(dom->conn, driver, vm, dev->data.disk, qemuCmdFlags);
|
ret = qemudDomainAttachSCSIDisk(dom->conn, driver, vm,
|
||||||
|
dev->data.disk, qemuCmdFlags);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
dev->data.disk = NULL;
|
dev->data.disk = NULL;
|
||||||
} else {
|
} else {
|
||||||
@ -5825,7 +5938,8 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
|
|||||||
}
|
}
|
||||||
} else if (dev->type == VIR_DOMAIN_DEVICE_CONTROLLER) {
|
} else if (dev->type == VIR_DOMAIN_DEVICE_CONTROLLER) {
|
||||||
if (dev->data.controller->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
|
if (dev->data.controller->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
|
||||||
ret = qemudDomainAttachPciControllerDevice(dom->conn, driver, vm, dev->data.controller);
|
ret = qemudDomainAttachPciControllerDevice(dom->conn, driver, vm,
|
||||||
|
dev->data.controller, qemuCmdFlags);
|
||||||
} else {
|
} else {
|
||||||
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
||||||
_("disk controller bus '%s' cannot be hotplugged."),
|
_("disk controller bus '%s' cannot be hotplugged."),
|
||||||
@ -5833,11 +5947,13 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
|
|||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
}
|
}
|
||||||
} else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
|
} else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
|
||||||
ret = qemudDomainAttachNetDevice(dom->conn, driver, vm, dev->data.net, qemuCmdFlags);
|
ret = qemudDomainAttachNetDevice(dom->conn, driver, vm,
|
||||||
|
dev->data.net, qemuCmdFlags);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
dev->data.net = NULL;
|
dev->data.net = NULL;
|
||||||
} else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
|
} else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
|
||||||
ret = qemudDomainAttachHostDevice(dom->conn, driver, vm, dev->data.hostdev);
|
ret = qemudDomainAttachHostDevice(dom->conn, driver, vm,
|
||||||
|
dev->data.hostdev, qemuCmdFlags);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
dev->data.hostdev = NULL;
|
dev->data.hostdev = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user