static int qemudDomainDetachPciControllerDevice(struct qemud_driver *driver,
virDomainObjPtr vm,
- virDomainDeviceDefPtr dev)
+ virDomainDeviceDefPtr dev,
+ unsigned long long qemuCmdFlags)
{
int i, ret = -1;
virDomainControllerDefPtr detach = NULL;
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);
const char *xml) {
struct qemud_driver *driver = dom->conn->privateData;
virDomainObjPtr vm;
+ unsigned long long qemuCmdFlags;
virDomainDeviceDefPtr dev = NULL;
int ret = -1;
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 &&
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."),
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)
int qemuMonitorAddDevice(qemuMonitorPtr mon,
const char *devicestr);
+int qemuMonitorDelDevice(qemuMonitorPtr mon,
+ const char *devicestr);
+
int qemuMonitorAddDrive(qemuMonitorPtr mon,
const char *drivestr);
}
+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)
{
int qemuMonitorJSONAddDevice(qemuMonitorPtr mon,
const char *devicestr);
+int qemuMonitorJSONDelDevice(qemuMonitorPtr mon,
+ const char *devicestr);
+
int qemuMonitorJSONAddDrive(qemuMonitorPtr mon,
const char *drivestr);
#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)
{
int qemuMonitorTextAddDevice(qemuMonitorPtr mon,
const char *devicestr);
+int qemuMonitorTextDelDevice(qemuMonitorPtr mon,
+ const char *devicestr);
+
int qemuMonitorTextAddDrive(qemuMonitorPtr mon,
const char *drivestr);