[libvirt] [PATCH 5/6] Use device_del to remove SCSI controllers

Wolfgang Mauerer wolfgang.mauerer at siemens.com
Fri Feb 26 13:09:18 UTC 2010


...when the underlying qemu supports the drive/device model and the
controller has been added this way.

Signed-off-by: Wolfgang Mauerer <woilfgang.mauerer at siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
---
 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




More information about the libvir-list mailing list