zdev: Add support for virtio devices

Add support for managing virtual I/O ccw (virtio-ccw) devices in
lszdev/chzdev.

New zdev device type virtio. Each virtio device type (blk, net,
gpu, vsock, etc.) is represented by a unique subtype of the virtio
base type.

If the virtio device type is recognized, then it will show up as
virtio-blk or virtio-net, or whatever the virtio device type is.
Otherwise, it will just show up as virtio-ccw.

Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/29
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Peter Jin <pjin@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
Peter Jin
2025-05-28 13:03:40 -04:00
committed by Jan Höppner
parent 2d86117167
commit 2349236bb4
7 changed files with 317 additions and 3 deletions

View File

@@ -21,6 +21,36 @@
#include "misc.h"
#include "path.h"
struct virtio_cb_data {
char *virtio_name;
};
static exit_code_t add_virtio_cb(const char *path, const char *filename, void *data)
{
struct virtio_cb_data *cb_data = data;
if (starts_with(filename, "virtio")) {
cb_data->virtio_name = misc_strdup(path);
return EXIT_RUNTIME_ERROR;
}
return EXIT_OK;
}
/*
* Given path like /sys/bus/ccw/devices/0.0.0001, get virtio subdirectory
* like "virtio4", NULL if not found.
*/
char *devnode_get_virtio_dir(const char *ccw_path)
{
struct virtio_cb_data cb_data = {};
if (util_path_is_dir(ccw_path))
path_for_each(ccw_path, add_virtio_cb, &cb_data);
return cb_data.virtio_name;
}
/* Create a newly allocated devnode object from the specified data. */
struct devnode *devnode_new(devnode_t type, unsigned int major,
unsigned int minor, const char *name)
@@ -244,7 +274,7 @@ static exit_code_t add_block_cb(const char *path, const char *filename,
int devnode_add_block_from_sysfs(struct util_list *list, const char *path)
{
struct add_cb_data cb_data;
char *blkpath;
char *blkpath, *virtio_path;
cb_data.list = list;
cb_data.num = 0;
@@ -255,6 +285,15 @@ int devnode_add_block_from_sysfs(struct util_list *list, const char *path)
path_for_each(blkpath, add_block_cb, &cb_data);
free(blkpath);
virtio_path = devnode_get_virtio_dir(path);
if (virtio_path) {
blkpath = misc_asprintf("%s/block", virtio_path);
if (util_path_is_dir(blkpath))
path_for_each(blkpath, add_block_cb, &cb_data);
free(blkpath);
free(virtio_path);
}
return cb_data.num;
}
@@ -278,7 +317,7 @@ static exit_code_t add_net_cb(const char *path, const char *filename,
int devnode_add_net_from_sysfs(struct util_list *list, const char *path)
{
struct add_cb_data cb_data;
char *netpath;
char *netpath, *virtio_path;
cb_data.list = list;
cb_data.num = 0;
@@ -289,6 +328,15 @@ int devnode_add_net_from_sysfs(struct util_list *list, const char *path)
path_for_each(netpath, add_net_cb, &cb_data);
free(netpath);
virtio_path = devnode_get_virtio_dir(path);
if (virtio_path) {
netpath = misc_asprintf("%s/net", virtio_path);
if (util_path_is_dir(netpath))
path_for_each(netpath, add_net_cb, &cb_data);
free(netpath);
free(virtio_path);
}
return cb_data.num;
}