[PATCH 1/2] qemu: Add callback struct for qemuBuildCommandLine

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Since 0d70656afded, it starts to access the sysfs files to build
the qemu command line (by virSCSIDeviceGetSgName, which is to find
out the scsi generic device name by adpater:bus:target:unit), there
is no way to work around, qemu wants to see the scsi generic device
like "/dev/sg6" anyway.

And there might be other places which need to access sysfs files
when building qemu command line in future.

Instead of increasing the arguments of qemuBuildCommandLine, this
introduces a new callback for qemuBuildCommandLine, and thus tests
can register their own callbacks for sysfs test input files accessing.

"tests/sysfsroot" is created to hold the sysfs related test input
files.

* src/qemu/qemu_command.h: (New callback struct
                            qemuBuildCommandLineCallbacks;
                            extern buildCommandLineCallbacks)
* src/qemu/qemu_command.c: (Helper qemuSCSIDeviceGetSgName;
                            wire up the callback struct)
* src/qemu/qemu_driver.c: (Use the new syntax of qemuBuildCommandLine)
* src/qemu/qemu_hotplug.c: Likewise
* src/qemu/qemu_process.c: Likewise
* src/util/virscsi.c: (Allow to specify the sysfs root for
                       virSCSIDeviceGetSgName)
* src/util/virscsi.h: (Change the definition of virSCSIDeviceGetSgName)
* tests/qemuxml2argvtest.c: (Helper testSCSIDeviceGetSgName;
                             callback struct testCallbacks;
                             Use the callback struct)
* src/tests/qemuxmlnstest.c :( Use the new syntax of qemuBuildCommandLine)
* tests/sysfsroot/* : (New test input files)
* tests/Makefile.am: (Add "sysfsroot" in EXTRA_DIST)
---
 src/qemu/qemu_command.c                            | 31 ++++++++++++++-----
 src/qemu/qemu_command.h                            | 16 ++++++++--
 src/qemu/qemu_driver.c                             |  3 +-
 src/qemu/qemu_hotplug.c                            |  6 ++--
 src/qemu/qemu_process.c                            |  3 +-
 src/util/virscsi.c                                 | 35 ++++++++++++++++++----
 src/util/virscsi.h                                 |  3 +-
 tests/Makefile.am                                  |  1 +
 tests/qemuxml2argvtest.c                           | 18 ++++++++++-
 tests/qemuxmlnstest.c                              |  3 +-
 .../bus/scsi/devices/0:0:0:0/scsi_generic/sg0/dev  |  1 +
 11 files changed, 97 insertions(+), 23 deletions(-)
 create mode 100644 tests/sysfsroot/bus/scsi/devices/0:0:0:0/scsi_generic/sg0/dev

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 5b95c07..b71a3b9 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4757,17 +4757,18 @@ qemuBuildUSBHostdevUsbDevStr(virDomainHostdevDefPtr dev)
 
 char *
 qemuBuildSCSIHostdevDrvStr(virDomainHostdevDefPtr dev,
-                           virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED)
+                           virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED,
+                           qemuBuildCommandLineCallbacksPtr callbacks)
 {
     virBuffer buf = VIR_BUFFER_INITIALIZER;
     char *sg = NULL;
 
-    if (!(sg = virSCSIDeviceGetSgName(dev->source.subsys.u.scsi.adapter,
-                                      dev->source.subsys.u.scsi.bus,
-                                      dev->source.subsys.u.scsi.target,
-                                      dev->source.subsys.u.scsi.unit))) {
+    sg = (callbacks->qemuGetSCSIDeviceSgName)(dev->source.subsys.u.scsi.adapter,
+                                              dev->source.subsys.u.scsi.bus,
+                                              dev->source.subsys.u.scsi.target,
+                                              dev->source.subsys.u.scsi.unit);
+    if (!sg)
         goto error;
-    }
 
     virBufferAsprintf(&buf, "file=/dev/%s,if=none", sg);
     virBufferAsprintf(&buf, ",id=%s-%s",
@@ -6405,6 +6406,19 @@ qemuBuildGraphicsCommandLine(virQEMUDriverConfigPtr cfg,
     return 0;
 }
 
+static char *
+qemuSCSIDeviceGetSgName(const char *adapter,
+                        unsigned int bus,
+                        unsigned int target,
+                        unsigned int unit)
+{
+    return virSCSIDeviceGetSgName(adapter, bus, target, unit, NULL);
+}
+
+qemuBuildCommandLineCallbacks buildCommandLineCallbacks = {
+    .qemuGetSCSIDeviceSgName = qemuSCSIDeviceGetSgName,
+};
+
 /*
  * Constructs a argv suitable for launching qemu with config defined
  * for a given virtual machine.
@@ -6422,7 +6436,8 @@ qemuBuildCommandLine(virConnectPtr conn,
                      const char *migrateFrom,
                      int migrateFd,
                      virDomainSnapshotObjPtr snapshot,
-                     enum virNetDevVPortProfileOp vmop)
+                     enum virNetDevVPortProfileOp vmop,
+                     qemuBuildCommandLineCallbacksPtr callbacks)
 {
     virErrorPtr originalError = NULL;
     int i, j;
@@ -8243,7 +8258,7 @@ qemuBuildCommandLine(virConnectPtr conn,
                 char *drvstr;
 
                 virCommandAddArg(cmd, "-drive");
-                if (!(drvstr = qemuBuildSCSIHostdevDrvStr(hostdev, qemuCaps)))
+                if (!(drvstr = qemuBuildSCSIHostdevDrvStr(hostdev, qemuCaps, callbacks)))
                     goto error;
                 virCommandAddArg(cmd, drvstr);
                 VIR_FREE(drvstr);
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 36dfa6b..23b6af3 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -51,6 +51,16 @@
 # define QEMU_WEBSOCKET_PORT_MIN  5700
 # define QEMU_WEBSOCKET_PORT_MAX  65535
 
+typedef struct _qemuBuildCommandLineCallbacks qemuBuildCommandLineCallbacks;
+typedef qemuBuildCommandLineCallbacks *qemuBuildCommandLineCallbacksPtr;
+struct _qemuBuildCommandLineCallbacks {
+    char * (*qemuGetSCSIDeviceSgName) (const char *adapter,
+                                       unsigned int bus,
+                                       unsigned int target,
+                                       unsigned int unit);
+};
+
+extern qemuBuildCommandLineCallbacks buildCommandLineCallbacks;
 
 virCommandPtr qemuBuildCommandLine(virConnectPtr conn,
                                    virQEMUDriverPtr driver,
@@ -61,7 +71,8 @@ virCommandPtr qemuBuildCommandLine(virConnectPtr conn,
                                    const char *migrateFrom,
                                    int migrateFd,
                                    virDomainSnapshotObjPtr current_snapshot,
-                                   enum virNetDevVPortProfileOp vmop)
+                                   enum virNetDevVPortProfileOp vmop,
+                                   qemuBuildCommandLineCallbacksPtr callbacks)
     ATTRIBUTE_NONNULL(1);
 
 /* Generate string for arch-specific '-device' parameter */
@@ -142,7 +153,8 @@ char * qemuBuildUSBHostdevDevStr(virDomainHostdevDefPtr dev,
                                  virQEMUCapsPtr qemuCaps);
 
 char * qemuBuildSCSIHostdevDrvStr(virDomainHostdevDefPtr dev,
-                                  virQEMUCapsPtr qemuCaps);
+                                  virQEMUCapsPtr qemuCaps,
+                                  qemuBuildCommandLineCallbacksPtr callbacks);
 char * qemuBuildSCSIHostdevDevStr(virDomainDefPtr def,
                                   virDomainHostdevDefPtr dev,
                                   virQEMUCapsPtr qemuCaps);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b1630f8..cb46276 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5362,7 +5362,8 @@ static char *qemuConnectDomainXMLToNative(virConnectPtr conn,
 
     if (!(cmd = qemuBuildCommandLine(conn, driver, def,
                                      &monConfig, monitor_json, qemuCaps,
-                                     NULL, -1, NULL, VIR_NETDEV_VPORT_PROFILE_OP_NO_OP)))
+                                     NULL, -1, NULL, VIR_NETDEV_VPORT_PROFILE_OP_NO_OP,
+                                     &buildCommandLineCallbacks)))
         goto cleanup;
 
     ret = virCommandToString(cmd);
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index d037c9d..77d9f4f 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1226,7 +1226,8 @@ qemuDomainAttachHostScsiDevice(virQEMUDriverPtr driver,
     if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, 0) < 0)
         goto cleanup;
 
-    if (!(drvstr = qemuBuildSCSIHostdevDrvStr(hostdev, priv->qemuCaps)))
+    if (!(drvstr = qemuBuildSCSIHostdevDrvStr(hostdev, priv->qemuCaps,
+                                              &buildCommandLineCallbacks)))
         goto cleanup;
 
     if (!(devstr = qemuBuildSCSIHostdevDevStr(vm->def, hostdev, priv->qemuCaps)))
@@ -2543,7 +2544,8 @@ qemuDomainDetachHostScsiDevice(virQEMUDriverPtr driver,
         return -1;
     }
 
-    if (!(drvstr = qemuBuildSCSIHostdevDrvStr(detach, priv->qemuCaps)))
+    if (!(drvstr = qemuBuildSCSIHostdevDrvStr(detach, priv->qemuCaps,
+                                              &buildCommandLineCallbacks)))
         goto cleanup;
     if (!(devstr = qemuBuildSCSIHostdevDevStr(vm->def, detach, priv->qemuCaps)))
         goto cleanup;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index dbbb7bf..3b247a5 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3638,7 +3638,8 @@ int qemuProcessStart(virConnectPtr conn,
     VIR_DEBUG("Building emulator command line");
     if (!(cmd = qemuBuildCommandLine(conn, driver, vm->def, priv->monConfig,
                                      priv->monJSON, priv->qemuCaps,
-                                     migrateFrom, stdin_fd, snapshot, vmop)))
+                                     migrateFrom, stdin_fd, snapshot, vmop,
+                                     &buildCommandLineCallbacks)))
         goto cleanup;
 
     /* now that we know it is about to start call the hook if present */
diff --git a/src/util/virscsi.c b/src/util/virscsi.c
index d6685fa..56a2cbf 100644
--- a/src/util/virscsi.c
+++ b/src/util/virscsi.c
@@ -100,26 +100,48 @@ virSCSIDeviceGetAdapterId(const char *adapter,
     return 0;
 }
 
+static char *
+virSCSIDeviceSysfsPrefix(const char *sysfs_root)
+{
+    char *ret = NULL;
+
+    if (sysfs_root) {
+        if (virAsprintf(&ret, "%s/bus/scsi/devices", sysfs_root) < 0) {
+            virReportOOMError();
+            return NULL;
+        }
+    } else {
+        if (VIR_STRDUP(ret, SYSFS_SCSI_DEVICES) < 0)
+            return NULL;
+    }
+
+    return ret;
+}
+
 char *
 virSCSIDeviceGetSgName(const char *adapter,
                        unsigned int bus,
                        unsigned int target,
-                       unsigned int unit)
+                       unsigned int unit,
+                       const char *sysfs_root)
 {
     DIR *dir = NULL;
     struct dirent *entry;
     char *path = NULL;
     char *sg = NULL;
     unsigned int adapter_id;
+    char *sysfs_prefix = NULL;
 
     if (virSCSIDeviceGetAdapterId(adapter, &adapter_id) < 0)
         return NULL;
 
-    if (virAsprintf(&path,
-                    SYSFS_SCSI_DEVICES "/%d:%d:%d:%d/scsi_generic",
-                    adapter_id, bus, target, unit) < 0) {
-        virReportOOMError();
+    if (!(sysfs_prefix = virSCSIDeviceSysfsPrefix(sysfs_root)))
         return NULL;
+
+    if (virAsprintf(&path, "%s/%d:%d:%d:%d/scsi_generic",
+                    sysfs_prefix, adapter_id, bus, target, unit) < 0) {
+        virReportOOMError();
+        goto cleanup;
     }
 
     if (!(dir = opendir(path))) {
@@ -138,6 +160,7 @@ virSCSIDeviceGetSgName(const char *adapter,
 
 cleanup:
     closedir(dir);
+    VIR_FREE(sysfs_prefix);
     VIR_FREE(path);
     return sg;
 }
@@ -166,7 +189,7 @@ virSCSIDeviceNew(const char *adapter,
     dev->unit = unit;
     dev->readonly = readonly;
 
-    if (!(sg = virSCSIDeviceGetSgName(adapter, bus, target, unit)))
+    if (!(sg = virSCSIDeviceGetSgName(adapter, bus, target, unit, NULL)))
         goto cleanup;
 
     if (virSCSIDeviceGetAdapterId(adapter, &dev->adapter) < 0)
diff --git a/src/util/virscsi.h b/src/util/virscsi.h
index 8268cdf..749e8d9 100644
--- a/src/util/virscsi.h
+++ b/src/util/virscsi.h
@@ -36,7 +36,8 @@ typedef virSCSIDeviceList *virSCSIDeviceListPtr;
 char *virSCSIDeviceGetSgName(const char *adapter,
                              unsigned int bus,
                              unsigned int target,
-                             unsigned int unit);
+                             unsigned int unit,
+                             const char *sysfs_root);
 
 virSCSIDevicePtr virSCSIDeviceNew(const char *adapter,
                                   unsigned int bus,
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 41c4067..a6cc5bf 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -80,6 +80,7 @@ EXTRA_DIST =		\
 	storagevolschematest \
 	storagevolxml2xmlin \
 	storagevolxml2xmlout \
+	sysfsroot \
 	sysinfodata \
 	test-lib.sh	\
 	vmx2xmldata \
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index ac31d2a..3d22491 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -82,6 +82,21 @@ typedef enum {
     FLAG_JSON               = 1 << 3,
 } virQemuXML2ArgvTestFlags;
 
+# define TEST_SYSFS_ROOT "./sysfsroot"
+
+static char *
+testSCSIDeviceGetSgName(const char *adapter,
+                        unsigned int bus,
+                        unsigned int target,
+                        unsigned int unit)
+{
+    return virSCSIDeviceGetSgName(adapter, bus, target, unit, TEST_SYSFS_ROOT);
+}
+
+static qemuBuildCommandLineCallbacks testCallbacks = {
+    .qemuGetSCSIDeviceSgName = testSCSIDeviceGetSgName,
+};
+
 static int testCompareXMLToArgvFiles(const char *xml,
                                      const char *cmdline,
                                      virQEMUCapsPtr extraFlags,
@@ -157,7 +172,8 @@ static int testCompareXMLToArgvFiles(const char *xml,
     if (!(cmd = qemuBuildCommandLine(conn, &driver, vmdef, &monitor_chr,
                                      (flags & FLAG_JSON), extraFlags,
                                      migrateFrom, migrateFd, NULL,
-                                     VIR_NETDEV_VPORT_PROFILE_OP_NO_OP))) {
+                                     VIR_NETDEV_VPORT_PROFILE_OP_NO_OP,
+                                     &testCallbacks))) {
         if (flags & FLAG_EXPECT_FAILURE) {
             ret = 0;
             if (virTestGetDebug() > 1)
diff --git a/tests/qemuxmlnstest.c b/tests/qemuxmlnstest.c
index 952b8e2..9d3d2a0 100644
--- a/tests/qemuxmlnstest.c
+++ b/tests/qemuxmlnstest.c
@@ -113,7 +113,8 @@ static int testCompareXMLToArgvFiles(const char *xml,
     if (!(cmd = qemuBuildCommandLine(conn, &driver,
                                      vmdef, &monitor_chr, json, extraFlags,
                                      migrateFrom, migrateFd, NULL,
-                                     VIR_NETDEV_VPORT_PROFILE_OP_NO_OP)))
+                                     VIR_NETDEV_VPORT_PROFILE_OP_NO_OP,
+                                     NULL)))
         goto fail;
 
     if (!!virGetLastError() != expectError) {
diff --git a/tests/sysfsroot/bus/scsi/devices/0:0:0:0/scsi_generic/sg0/dev b/tests/sysfsroot/bus/scsi/devices/0:0:0:0/scsi_generic/sg0/dev
new file mode 100644
index 0000000..992e920
--- /dev/null
+++ b/tests/sysfsroot/bus/scsi/devices/0:0:0:0/scsi_generic/sg0/dev
@@ -0,0 +1 @@
+21:0
-- 
1.8.1.4

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]