...when the underlying qemu supports the drive/device model and the controller has been added this way. Signed-off-by: Wolfgang Mauerer <woilfgang.mauerer@xxxxxxxxxxx> Signed-off-by: Jan Kiszka <jan.kiszka@xxxxxxxxxxx> --- src/qemu/qemu_driver.c | 31 +++++++++++++++++++++++++------ src/qemu/qemu_monitor.c | 13 +++++++++++++ src/qemu/qemu_monitor.h | 3 +++ src/qemu/qemu_monitor_json.c | 24 ++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 3 +++ src/qemu/qemu_monitor_text.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_text.h | 3 +++ 7 files changed, 111 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 8960ef8..d683b1c 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6230,7 +6230,8 @@ cleanup: static int qemudDomainDetachPciControllerDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev) + virDomainDeviceDefPtr dev, + unsigned long long qemuCmdFlags) { int i, ret = -1; virDomainControllerDefPtr detach = NULL; @@ -6259,11 +6260,23 @@ static int qemudDomainDetachPciControllerDevice(struct qemud_driver *driver, goto cleanup; } + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { + if (qemuAssignDeviceControllerAlias(detach) < 0) + goto cleanup; + } + qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuMonitorRemovePCIDevice(priv->mon, - &detach->info.addr.pci) < 0) { - qemuDomainObjExitMonitor(vm); - goto cleanup; + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { + if (qemuMonitorDelDevice(priv->mon, detach->info.alias)) { + qemuDomainObjExitMonitor(vm); + goto cleanup; + } + } else { + if (qemuMonitorRemovePCIDevice(priv->mon, + &detach->info.addr.pci) < 0) { + qemuDomainObjExitMonitor(vm); + goto cleanup; + } } qemuDomainObjExitMonitorWithDriver(driver, vm); @@ -6513,6 +6526,7 @@ static int qemudDomainDetachDevice(virDomainPtr dom, const char *xml) { struct qemud_driver *driver = dom->conn->privateData; virDomainObjPtr vm; + unsigned long long qemuCmdFlags; virDomainDeviceDefPtr dev = NULL; int ret = -1; @@ -6540,6 +6554,10 @@ static int qemudDomainDetachDevice(virDomainPtr dom, if (dev == NULL) goto endjob; + if (qemudExtractVersionInfo(vm->def->emulator, + NULL, + &qemuCmdFlags) < 0) + goto endjob; if (dev->type == VIR_DOMAIN_DEVICE_DISK && dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_DISK && @@ -6549,7 +6567,8 @@ static int qemudDomainDetachDevice(virDomainPtr dom, ret = qemudDomainDetachNetDevice(driver, vm, dev); } else if (dev->type == VIR_DOMAIN_DEVICE_CONTROLLER) { if (dev->data.controller->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) { - ret = qemudDomainDetachPciControllerDevice(driver, vm, dev); + ret = qemudDomainDetachPciControllerDevice(driver, vm, dev, + qemuCmdFlags); } else { qemuReportError(VIR_ERR_NO_SUPPORT, _("disk controller bus '%s' cannot be hotunplugged."), diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index b88532c..a4d2b89 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1318,6 +1318,19 @@ int qemuMonitorGetAllPCIAddresses(qemuMonitorPtr mon, return ret; } +int qemuMonitorDelDevice(qemuMonitorPtr mon, + const char *devicestr) +{ + DEBUG("mon=%p, fd=%d device(del)=%s", mon, mon->fd, devicestr); + int ret; + + if (mon->json) + ret = qemuMonitorJSONDelDevice(mon, devicestr); + else + ret = qemuMonitorTextDelDevice(mon, devicestr); + return ret; +} + int qemuMonitorAddDevice(qemuMonitorPtr mon, const char *devicestr) diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 0ac3957..3e55236 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -290,6 +290,9 @@ int qemuMonitorGetAllPCIAddresses(qemuMonitorPtr mon, int qemuMonitorAddDevice(qemuMonitorPtr mon, const char *devicestr); +int qemuMonitorDelDevice(qemuMonitorPtr mon, + const char *devicestr); + int qemuMonitorAddDrive(qemuMonitorPtr mon, const char *drivestr); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 7b45594..3a94dd0 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -1835,6 +1835,30 @@ int qemuMonitorJSONGetAllPCIAddresses(qemuMonitorPtr mon ATTRIBUTE_UNUSED, } +int qemuMonitorJSONDelDevice(qemuMonitorPtr mon, + const char *devicestr) +{ + int ret; + virJSONValuePtr cmd; + virJSONValuePtr reply = NULL; + + cmd = qemuMonitorJSONMakeCommand("device_del", + "s:config", devicestr, + NULL); + if (!cmd) + return -1; + + ret = qemuMonitorJSONCommand(mon, cmd, &reply); + + if (ret == 0) + ret = qemuMonitorJSONCheckError(cmd, reply); + + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +} + + int qemuMonitorJSONAddDevice(qemuMonitorPtr mon, const char *devicestr) { diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index c6a6d51..70a8dae 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -161,6 +161,9 @@ int qemuMonitorJSONGetAllPCIAddresses(qemuMonitorPtr mon, int qemuMonitorJSONAddDevice(qemuMonitorPtr mon, const char *devicestr); +int qemuMonitorJSONDelDevice(qemuMonitorPtr mon, + const char *devicestr); + int qemuMonitorJSONAddDrive(qemuMonitorPtr mon, const char *drivestr); diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index 62ffcc6..610bb1f 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -2053,6 +2053,46 @@ error: #undef SKIP_TO +int qemuMonitorTextDelDevice(qemuMonitorPtr mon, + const char *devicestr) +{ + char *cmd = NULL; + char *reply = NULL; + char *safedev; + int ret = -1; + + if (!(safedev = qemuMonitorEscapeArg(devicestr))) { + virReportOOMError(); + goto cleanup; + } + + if (virAsprintf(&cmd, "device_del %s", safedev) < 0) { + virReportOOMError(); + goto cleanup; + } + + if (qemuMonitorCommand(mon, cmd, &reply) < 0) { + qemuReportError(VIR_ERR_OPERATION_FAILED, + _("cannot detach %s device"), devicestr); + goto cleanup; + } + + if (STRNEQ(reply, "")) { + qemuReportError(VIR_ERR_OPERATION_FAILED, + _("detaching %s device failed: %s"), devicestr, reply); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FREE(cmd); + VIR_FREE(reply); + VIR_FREE(safedev); + return ret; +} + + int qemuMonitorTextAddDevice(qemuMonitorPtr mon, const char *devicestr) { diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h index 1937e99..9dcb0c2 100644 --- a/src/qemu/qemu_monitor_text.h +++ b/src/qemu/qemu_monitor_text.h @@ -163,6 +163,9 @@ int qemuMonitorTextGetAllPCIAddresses(qemuMonitorPtr mon, int qemuMonitorTextAddDevice(qemuMonitorPtr mon, const char *devicestr); +int qemuMonitorTextDelDevice(qemuMonitorPtr mon, + const char *devicestr); + int qemuMonitorTextAddDrive(qemuMonitorPtr mon, const char *drivestr); -- 1.6.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list