[libvirt] [PATCH 11/12] qemu: Implement random number generator hotplug

Peter Krempa pkrempa at redhat.com
Fri Feb 6 15:32:25 UTC 2015


From: Luyao Huang <lhuang at redhat.com>

Export the required helpers and add backend code to hotplug RNG devices.

Signed-off-by: Luyao Huang <lhuang at redhat.com>
Signed-off-by: Peter Krempa <pkrempa at redhat.com>
---
 src/qemu/qemu_command.c |  2 +-
 src/qemu/qemu_command.h |  4 ++
 src/qemu/qemu_driver.c  |  8 +++-
 src/qemu/qemu_hotplug.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_hotplug.h |  3 ++
 5 files changed, 114 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 9179c1f..9068f50 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6171,7 +6171,7 @@ qemuBuildRNGBackendChrdevStr(virDomainRNGDefPtr rng,
 }


-static int
+int
 qemuBuildRNGBackendProps(virDomainRNGDefPtr rng,
                          virQEMUCapsPtr qemuCaps,
                          const char **type,
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index e280497..89e8351 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -174,6 +174,10 @@ char *qemuBuildPCIHostdevDevStr(virDomainDefPtr def,
 char *qemuBuildRNGDevStr(virDomainDefPtr def,
                          virDomainRNGDefPtr dev,
                          virQEMUCapsPtr qemuCaps);
+int qemuBuildRNGBackendProps(virDomainRNGDefPtr rng,
+                             virQEMUCapsPtr qemuCaps,
+                             const char **type,
+                             virJSONValuePtr *props);

 int qemuOpenPCIConfig(virDomainHostdevDefPtr dev);

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 717b384..9e5bdee 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7109,6 +7109,13 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
             dev->data.chr = NULL;
         break;

+    case VIR_DOMAIN_DEVICE_RNG:
+        ret = qemuDomainAttachRNGDevice(driver, vm,
+                                        dev->data.rng);
+        if (!ret)
+            dev->data.rng = NULL;
+        break;
+
     case VIR_DOMAIN_DEVICE_NONE:
     case VIR_DOMAIN_DEVICE_FS:
     case VIR_DOMAIN_DEVICE_INPUT:
@@ -7120,7 +7127,6 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
     case VIR_DOMAIN_DEVICE_SMARTCARD:
     case VIR_DOMAIN_DEVICE_MEMBALLOON:
     case VIR_DOMAIN_DEVICE_NVRAM:
-    case VIR_DOMAIN_DEVICE_RNG:
     case VIR_DOMAIN_DEVICE_SHMEM:
     case VIR_DOMAIN_DEVICE_TPM:
     case VIR_DOMAIN_DEVICE_PANIC:
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 033b281..6dd7360 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1569,6 +1569,105 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
     return ret;
 }

+
+int
+qemuDomainAttachRNGDevice(virQEMUDriverPtr driver,
+                          virDomainObjPtr vm,
+                          virDomainRNGDefPtr rng)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    char *devstr = NULL;
+    char *charAlias = NULL;
+    char *objAlias = NULL;
+    virJSONValuePtr props = NULL;
+    const char *type;
+    int ret = -1;
+
+    if (qemuAssignDeviceRNGAlias(rng, vm->def->nrngs) < 0)
+        return -1;
+
+    if (rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
+        if (STRPREFIX(vm->def->os.machine, "s390-ccw") &&
+            virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW)) {
+            rng->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW;
+        } else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_S390)) {
+            rng->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390;
+        }
+    }
+
+    if (rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE ||
+        rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
+        if (virDomainPCIAddressEnsureAddr(priv->pciaddrs, &rng->info) < 0)
+            return -1;
+    } else if (rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
+        if (virDomainCCWAddressAssign(&rng->info, priv->ccwaddrs,
+                                      !rng->info.addr.ccw.assigned) < 0)
+            return -1;
+    }
+
+    /* build required metadata */
+    if (!(devstr = qemuBuildRNGDevStr(vm->def, rng, priv->qemuCaps)))
+        goto cleanup;
+
+    if (qemuBuildRNGBackendProps(rng, priv->qemuCaps, &type, &props) < 0)
+        goto cleanup;
+
+    if (virAsprintf(&objAlias, "obj%s", rng->info.alias) < 0)
+        goto cleanup;
+
+    if (virAsprintf(&charAlias, "char%s", rng->info.alias) < 0)
+        goto cleanup;
+
+    /* attach the device - up to a 3 stage process */
+    qemuDomainObjEnterMonitor(driver, vm);
+
+    if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD &&
+        qemuMonitorAttachCharDev(priv->mon, charAlias,
+                                 rng->source.chardev) < 0)
+        goto failchardev;
+
+    if (qemuMonitorAddObject(priv->mon, type, objAlias, props) < 0)
+        goto failbackend;
+
+    if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
+        goto failfrontend;
+
+    if (qemuDomainObjExitMonitor(driver, vm) < 0) {
+        vm = NULL;
+        goto cleanup;
+    }
+
+    if (virDomainRNGInsert(vm->def, rng) < 0)
+        goto audit;
+
+    ret = 0;
+
+ audit:
+    virDomainAuditRNG(vm, NULL, rng, "attach", ret == 0);
+ cleanup:
+    if (vm)
+        qemuDomainReleaseDeviceAddress(vm, &rng->info, NULL);
+    VIR_FREE(charAlias);
+    VIR_FREE(objAlias);
+    VIR_FREE(devstr);
+    return ret;
+
+    /* rollback */
+ failfrontend:
+    ignore_value(qemuMonitorDelObject(priv->mon, objAlias));
+ failbackend:
+    if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD)
+        ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias));
+ failchardev:
+    if (qemuDomainObjExitMonitor(driver, vm) < 0) {
+        vm = NULL;
+        goto cleanup;
+    }
+
+    goto audit;
+}
+
+
 static int
 qemuDomainAttachHostUSBDevice(virQEMUDriverPtr driver,
                               virDomainObjPtr vm,
diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h
index a30788d..4f28a9d 100644
--- a/src/qemu/qemu_hotplug.h
+++ b/src/qemu/qemu_hotplug.h
@@ -97,6 +97,9 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
 int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
                               virDomainObjPtr vm,
                               virDomainChrDefPtr chr);
+int qemuDomainAttachRNGDevice(virQEMUDriverPtr driver,
+                              virDomainObjPtr vm,
+                              virDomainRNGDefPtr rng);


 int
-- 
2.2.2




More information about the libvir-list mailing list