提交 3a6204cb 编写于 作者: O Osier Yang

qemu: Add callback struct for qemuBuildCommandLine

Since 0d70656a, 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.

* src/qemu/qemu_command.h: (New callback struct
                            qemuBuildCommandLineCallbacks;
                            extern buildCommandLineCallbacks)
* src/qemu/qemu_command.c: (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
* tests/testutilsqemu.[ch]: (Helper testSCSIDeviceGetSgName;
                             callback struct testCallbacks;)
* tests/qemuxml2argvtest.c: (Use testCallbacks)
* src/tests/qemuxmlnstest.c: (Like above)
上级 8b7b43a1
......@@ -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,10 @@ qemuBuildGraphicsCommandLine(virQEMUDriverConfigPtr cfg,
return 0;
}
qemuBuildCommandLineCallbacks buildCommandLineCallbacks = {
.qemuGetSCSIDeviceSgName = virSCSIDeviceGetSgName,
};
/*
* Constructs a argv suitable for launching qemu with config defined
* for a given virtual machine.
......@@ -6422,7 +6427,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;
......@@ -8254,7 +8260,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);
......
......@@ -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,8 +71,9 @@ virCommandPtr qemuBuildCommandLine(virConnectPtr conn,
const char *migrateFrom,
int migrateFd,
virDomainSnapshotObjPtr current_snapshot,
enum virNetDevVPortProfileOp vmop)
ATTRIBUTE_NONNULL(1);
enum virNetDevVPortProfileOp vmop,
qemuBuildCommandLineCallbacksPtr callbacks)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(11);
/* Generate string for arch-specific '-device' parameter */
char *
......@@ -142,7 +153,9 @@ char * qemuBuildUSBHostdevDevStr(virDomainHostdevDefPtr dev,
virQEMUCapsPtr qemuCaps);
char * qemuBuildSCSIHostdevDrvStr(virDomainHostdevDefPtr dev,
virQEMUCapsPtr qemuCaps);
virQEMUCapsPtr qemuCaps,
qemuBuildCommandLineCallbacksPtr callbacks)
ATTRIBUTE_NONNULL(3);
char * qemuBuildSCSIHostdevDevStr(virDomainDefPtr def,
virDomainHostdevDefPtr dev,
virQEMUCapsPtr qemuCaps);
......
......@@ -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);
......
......@@ -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;
......
......@@ -3605,7 +3605,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 */
......
......@@ -157,7 +157,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)
......
......@@ -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,
&testCallbacks)))
goto fail;
if (!!virGetLastError() != expectError) {
......
......@@ -289,4 +289,23 @@ cleanup:
virObjectUnref(caps);
return NULL;
}
static char *
testSCSIDeviceGetSgName(const char *adapter ATTRIBUTE_UNUSED,
unsigned int bus ATTRIBUTE_UNUSED,
unsigned int target ATTRIBUTE_UNUSED,
unsigned int unit ATTRIBUTE_UNUSED)
{
char *sg = NULL;
if (VIR_STRDUP(sg, "sg0") < 0)
return NULL;
return sg;
}
qemuBuildCommandLineCallbacks testCallbacks = {
.qemuGetSCSIDeviceSgName = testSCSIDeviceGetSgName,
};
#endif
#include "capabilities.h"
#include "domain_conf.h"
#include "qemu/qemu_command.h"
virCapsPtr testQemuCapsInit(void);
virDomainXMLOptionPtr testQemuXMLConfInit(void);
extern qemuBuildCommandLineCallbacks testCallbacks;
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册