Skip to content

Commit

Permalink
nodedev: add PostParse callback for nodedev parsing
Browse files Browse the repository at this point in the history
This can be used similarly to other postparse callbacks in libvirt --
filling in additional information that can be determined by using the
information provided in the XML. In this case, we determine the address
of the parent device and cache it in the mdev caps so that we can use it
for generating a unique name and interacting with mdevctl.

Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
  • Loading branch information
jonner committed Aug 6, 2021
1 parent d5ae634 commit 08d29eb
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 11 deletions.
7 changes: 7 additions & 0 deletions src/conf/node_device_conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -2185,6 +2185,13 @@ virNodeDeviceDefParse(const char *str,

if (parserCallbacks) {
int ret = 0;
/* fill in backend-specific aspects */
if (parserCallbacks->postParse) {
ret = parserCallbacks->postParse(def, opaque);
if (ret < 0)
return NULL;
}

/* validate definition */
if (parserCallbacks->validate) {
ret = parserCallbacks->validate(def, opaque);
Expand Down
45 changes: 34 additions & 11 deletions src/node_device/node_device_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -718,11 +718,9 @@ nodeDeviceGetMdevctlCommand(virNodeDeviceDef *def,
char **outbuf,
char **errbuf)
{
g_autofree char *parent_addr = NULL;
g_autoptr(virCommand) cmd = NULL;
const char *subcommand = virMdevctlCommandTypeToString(cmd_type);
g_autofree char *inbuf = NULL;
virNodeDeviceObj *parent_obj = NULL;

switch (cmd_type) {
case MDEVCTL_CMD_CREATE:
Expand All @@ -747,12 +745,7 @@ nodeDeviceGetMdevctlCommand(virNodeDeviceDef *def,
switch (cmd_type) {
case MDEVCTL_CMD_CREATE:
case MDEVCTL_CMD_DEFINE:
if ((parent_obj = nodeDeviceObjFindByName(def->parent))) {
parent_addr = nodeDeviceObjFormatAddress(parent_obj);
virNodeDeviceObjEndAPI(&parent_obj);
}

if (!parent_addr) {
if (!def->caps->data.mdev.parent_addr) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unable to find parent device '%s'"), def->parent);
return NULL;
Expand All @@ -764,7 +757,7 @@ nodeDeviceGetMdevctlCommand(virNodeDeviceDef *def,
return NULL;
}

virCommandAddArgPair(cmd, "--parent", parent_addr);
virCommandAddArgPair(cmd, "--parent", def->caps->data.mdev.parent_addr);
virCommandAddArgPair(cmd, "--jsonfile", "/dev/stdin");

virCommandSetInputBuffer(cmd, inbuf);
Expand Down Expand Up @@ -1764,9 +1757,30 @@ nodeDeviceDefCopyFromMdevctl(virNodeDeviceDef *dst,
}


int nodeDeviceDefPostParse(virNodeDeviceDef *def,
G_GNUC_UNUSED void *opaque)
{
virNodeDevCapsDef *caps = NULL;
for (caps = def->caps; caps != NULL; caps = caps->next) {
if (caps->data.type == VIR_NODE_DEV_CAP_MDEV) {
virNodeDeviceObj *obj = NULL;

if (def->parent)
obj = virNodeDeviceObjListFindByName(driver->devs, def->parent);

if (obj) {
caps->data.mdev.parent_addr = nodeDeviceObjFormatAddress(obj);
virNodeDeviceObjEndAPI(&obj);
}
}
}
return 0;
}


/* validate that parent exists */
static int nodeDeviceDefValidateMdev(virNodeDeviceDef *def,
G_GNUC_UNUSED virNodeDevCapMdev *mdev,
virNodeDevCapMdev *mdev,
G_GNUC_UNUSED void *opaque)
{
virNodeDeviceObj *obj = NULL;
Expand All @@ -1782,8 +1796,17 @@ static int nodeDeviceDefValidateMdev(virNodeDeviceDef *def,
def->parent);
return -1;
}

virNodeDeviceObjEndAPI(&obj);

/* the post-parse callback should have found the address of the parent
* device and stored it in the mdev caps */
if (!mdev->parent_addr) {
virReportError(VIR_ERR_PARSE_FAILED,
_("Unable to find address for parent device '%s'"),
def->parent);
return -1;
}

return 0;
}

Expand Down
3 changes: 3 additions & 0 deletions src/node_device/node_device_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,5 +172,8 @@ int
nodeDeviceCreate(virNodeDevice *dev,
unsigned int flags);

int nodeDeviceDefPostParse(virNodeDeviceDef *def,
void *opaque);

int nodeDeviceDefValidate(virNodeDeviceDef *def,
void *opaque);
1 change: 1 addition & 0 deletions src/node_device/node_device_udev.c
Original file line number Diff line number Diff line change
Expand Up @@ -2243,6 +2243,7 @@ nodeStateInitialize(bool privileged,
driver->privateData = priv;
driver->nodeDeviceEventState = virObjectEventStateNew();

driver->parserCallbacks.postParse = nodeDeviceDefPostParse;
driver->parserCallbacks.validate = nodeDeviceDefValidate;

if (udevPCITranslateInit(privileged) < 0)
Expand Down
1 change: 1 addition & 0 deletions tests/nodedevmdevctltest.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#define VIRT_TYPE "QEMU"

static virNodeDeviceDefParserCallbacks parser_callbacks = {
.postParse = nodeDeviceDefPostParse,
.validate = nodeDeviceDefValidate
};

Expand Down

0 comments on commit 08d29eb

Please sign in to comment.