nodedev: add function to generate mdevctl define command

Abstract out the function used to generate the commandline for 'mdevctl
start' since they take the same arguments. Add tests to ensure that
we're generating the command properly.

Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
Reviewed-by: Erik Skultety <eskultet@redhat.com>
This commit is contained in:
Jonathon Jongsma 2021-01-27 10:55:07 -06:00
parent 2c57b28191
commit a48a2abe60
9 changed files with 95 additions and 27 deletions

View File

@ -698,10 +698,14 @@ nodeDeviceFindAddressByName(const char *name)
} }
virCommandPtr /* the mdevctl 'start' and 'define' commands accept almost the exact same
nodeDeviceGetMdevctlStartCommand(virNodeDeviceDefPtr def, * arguments, so provide a common implementation that can be wrapped by a more
char **uuid_out, * specific function */
char **errmsg) static virCommand*
nodeDeviceGetMdevctlDefineStartCommand(virNodeDeviceDef *def,
const char *subcommand,
char **uuid_out,
char **errmsg)
{ {
virCommandPtr cmd; virCommandPtr cmd;
g_autofree char *json = NULL; g_autofree char *json = NULL;
@ -719,7 +723,7 @@ nodeDeviceGetMdevctlStartCommand(virNodeDeviceDefPtr def,
return NULL; return NULL;
} }
cmd = virCommandNewArgList(MDEVCTL, "start", cmd = virCommandNewArgList(MDEVCTL, subcommand,
"-p", parent_addr, "-p", parent_addr,
"--jsonfile", "/dev/stdin", "--jsonfile", "/dev/stdin",
NULL); NULL);
@ -731,6 +735,26 @@ nodeDeviceGetMdevctlStartCommand(virNodeDeviceDefPtr def,
return cmd; return cmd;
} }
virCommand*
nodeDeviceGetMdevctlStartCommand(virNodeDeviceDef *def,
char **uuid_out,
char **errmsg)
{
return nodeDeviceGetMdevctlDefineStartCommand(def, "start", uuid_out,
errmsg);
}
virCommand*
nodeDeviceGetMdevctlDefineCommand(virNodeDeviceDef *def,
char **uuid_out,
char **errmsg)
{
return nodeDeviceGetMdevctlDefineStartCommand(def, "define", uuid_out,
errmsg);
}
static int static int
virMdevctlStart(virNodeDeviceDefPtr def, char **uuid, char **errmsg) virMdevctlStart(virNodeDeviceDefPtr def, char **uuid, char **errmsg)
{ {

View File

@ -117,6 +117,12 @@ virCommandPtr
nodeDeviceGetMdevctlStartCommand(virNodeDeviceDefPtr def, nodeDeviceGetMdevctlStartCommand(virNodeDeviceDefPtr def,
char **uuid_out, char **uuid_out,
char **errmsg); char **errmsg);
virCommand*
nodeDeviceGetMdevctlDefineCommand(virNodeDeviceDef *def,
char **uuid_out,
char **errmsg);
virCommandPtr virCommandPtr
nodeDeviceGetMdevctlStopCommand(const char *uuid, nodeDeviceGetMdevctlStopCommand(const char *uuid,
char **errmsg); char **errmsg);

View File

@ -0,0 +1 @@
$MDEVCTL_BINARY$ define -p 0000:00:02.0 --jsonfile /dev/stdin

View File

@ -0,0 +1 @@
{"mdev_type":"i915-GVTg_V5_8","start":"manual"}

View File

@ -0,0 +1 @@
$MDEVCTL_BINARY$ define -p 0000:00:02.0 --jsonfile /dev/stdin

View File

@ -0,0 +1 @@
{"mdev_type":"i915-GVTg_V5_8","start":"manual","attrs":[{"example-attribute-1":"attribute-value-1"},{"example-attribute-2":"attribute-value-2"}]}

View File

@ -0,0 +1 @@
$MDEVCTL_BINARY$ define -p 0000:00:02.0 --jsonfile /dev/stdin

View File

@ -0,0 +1 @@
{"mdev_type":"i915-GVTg_V5_8","start":"manual","attrs":[{"example-attribute":"attribute-value"}]}

View File

@ -10,10 +10,16 @@
#define VIR_FROM_THIS VIR_FROM_NODEDEV #define VIR_FROM_THIS VIR_FROM_NODEDEV
typedef enum {
MDEVCTL_CMD_START,
MDEVCTL_CMD_DEFINE,
} MdevctlCmd;
struct startTestInfo { struct startTestInfo {
const char *virt_type; const char *virt_type;
int create; int create;
const char *filename; const char *filename;
MdevctlCmd command;
}; };
/* capture stdin passed to command */ /* capture stdin passed to command */
@ -45,12 +51,17 @@ nodedevCompareToFile(const char *actual,
return virTestCompareToFile(replacedCmdline, filename); return virTestCompareToFile(replacedCmdline, filename);
} }
typedef virCommand* (*MdevctlCmdFunc)(virNodeDeviceDef *, char **, char **);
static int static int
testMdevctlStart(const char *virt_type, testMdevctlStartOrDefine(const char *virt_type,
int create, int create,
const char *mdevxml, MdevctlCmdFunc mdevctl_cmd_func,
const char *startcmdfile, const char *mdevxml,
const char *startjsonfile) const char *cmdfile,
const char *jsonfile)
{ {
g_autoptr(virNodeDeviceDef) def = NULL; g_autoptr(virNodeDeviceDef) def = NULL;
virNodeDeviceObjPtr obj = NULL; virNodeDeviceObjPtr obj = NULL;
@ -67,7 +78,7 @@ testMdevctlStart(const char *virt_type,
/* this function will set a stdin buffer containing the json configuration /* this function will set a stdin buffer containing the json configuration
* of the device. The json value is captured in the callback above */ * of the device. The json value is captured in the callback above */
cmd = nodeDeviceGetMdevctlStartCommand(def, &uuid, &errmsg); cmd = mdevctl_cmd_func(def, &uuid, &errmsg);
if (!cmd) if (!cmd)
goto cleanup; goto cleanup;
@ -79,10 +90,10 @@ testMdevctlStart(const char *virt_type,
if (!(actualCmdline = virBufferCurrentContent(&buf))) if (!(actualCmdline = virBufferCurrentContent(&buf)))
goto cleanup; goto cleanup;
if (nodedevCompareToFile(actualCmdline, startcmdfile) < 0) if (nodedevCompareToFile(actualCmdline, cmdfile) < 0)
goto cleanup; goto cleanup;
if (virTestCompareToFile(stdinbuf, startjsonfile) < 0) if (virTestCompareToFile(stdinbuf, jsonfile) < 0)
goto cleanup; goto cleanup;
ret = 0; ret = 0;
@ -94,20 +105,34 @@ testMdevctlStart(const char *virt_type,
} }
static int static int
testMdevctlStartHelper(const void *data) testMdevctlStartOrDefineHelper(const void *data)
{ {
const struct startTestInfo *info = data; const struct startTestInfo *info = data;
const char *cmd;
MdevctlCmdFunc func;
g_autofree char *mdevxml = NULL;
g_autofree char *cmdlinefile = NULL;
g_autofree char *jsonfile = NULL;
g_autofree char *mdevxml = g_strdup_printf("%s/nodedevschemadata/%s.xml", if (info->command == MDEVCTL_CMD_START) {
abs_srcdir, info->filename); cmd = "start";
g_autofree char *cmdlinefile = g_strdup_printf("%s/nodedevmdevctldata/%s-start.argv", func = nodeDeviceGetMdevctlStartCommand;
abs_srcdir, info->filename); } else if (info->command == MDEVCTL_CMD_DEFINE) {
g_autofree char *jsonfile = g_strdup_printf("%s/nodedevmdevctldata/%s-start.json", cmd = "define";
abs_srcdir, info->filename); func = nodeDeviceGetMdevctlDefineCommand;
} else {
return -1;
}
return testMdevctlStart(info->virt_type, mdevxml = g_strdup_printf("%s/nodedevschemadata/%s.xml", abs_srcdir,
info->create, mdevxml, cmdlinefile, info->filename);
jsonfile); cmdlinefile = g_strdup_printf("%s/nodedevmdevctldata/%s-%s.argv",
abs_srcdir, info->filename, cmd);
jsonfile = g_strdup_printf("%s/nodedevmdevctldata/%s-%s.json", abs_srcdir,
info->filename, cmd);
return testMdevctlStartOrDefine(info->virt_type, info->create, func,
mdevxml, cmdlinefile, jsonfile);
} }
static int static int
@ -350,15 +375,18 @@ mymain(void)
if (virTestRun(desc, func, info) < 0) \ if (virTestRun(desc, func, info) < 0) \
ret = -1; ret = -1;
#define DO_TEST_START_FULL(virt_type, create, filename) \ #define DO_TEST_CMD(desc, virt_type, create, filename, command) \
do { \ do { \
struct startTestInfo info = { virt_type, create, filename }; \ struct startTestInfo info = { virt_type, create, filename, command }; \
DO_TEST_FULL("mdevctl start " filename, testMdevctlStartHelper, &info); \ DO_TEST_FULL(desc, testMdevctlStartOrDefineHelper, &info); \
} \ } \
while (0) while (0)
#define DO_TEST_START(filename) \ #define DO_TEST_START(filename) \
DO_TEST_START_FULL("QEMU", CREATE_DEVICE, filename) DO_TEST_CMD("mdevctl start " filename, "QEMU", CREATE_DEVICE, filename, MDEVCTL_CMD_START)
#define DO_TEST_DEFINE(filename) \
DO_TEST_CMD("mdevctl define " filename, "QEMU", CREATE_DEVICE, filename, MDEVCTL_CMD_DEFINE)
#define DO_TEST_STOP(uuid) \ #define DO_TEST_STOP(uuid) \
DO_TEST_FULL("mdevctl stop " uuid, testMdevctlStop, uuid) DO_TEST_FULL("mdevctl stop " uuid, testMdevctlStop, uuid)
@ -381,6 +409,10 @@ mymain(void)
DO_TEST_PARSE_JSON("mdevctl-list-multiple"); DO_TEST_PARSE_JSON("mdevctl-list-multiple");
DO_TEST_DEFINE("mdev_d069d019_36ea_4111_8f0a_8c9a70e21366");
DO_TEST_DEFINE("mdev_fedc4916_1ca8_49ac_b176_871d16c13076");
DO_TEST_DEFINE("mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9");
done: done:
nodedevTestDriverFree(driver); nodedevTestDriverFree(driver);