Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 85 additions & 25 deletions tools/virtio/devices/blk/virtio_blk.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "virtio.h"
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
Expand Down Expand Up @@ -128,7 +129,7 @@ static void *blkproc_thread(void *arg) {
}

// create blk dev.
BlkDev *init_blk_dev(VirtIODevice *vdev) {
static BlkDev *init_blk_dev(VirtIODevice *vdev) {
BlkDev *dev = malloc(sizeof(BlkDev));
vdev->dev = dev;
dev->config.capacity = -1;
Expand All @@ -145,27 +146,29 @@ BlkDev *init_blk_dev(VirtIODevice *vdev) {
return dev;
}

int virtio_blk_init(VirtIODevice *vdev, const char *img_path) {
int img_fd = open(img_path, O_RDWR);
static int virtio_blk_init(VirtIODevice *vdev, const char *img_path) {
BlkDev *dev = vdev->dev;
struct stat st;
uint64_t blk_size;
if (img_fd == -1) {
if (!dev) {
log_error("virtio_blk_init: vdev->dev is nullptr");
return -1;
}

dev->img_fd = open(img_path, O_RDWR);
if (dev->img_fd == -1) {
log_error("cannot open %s, Error code is %d", img_path, errno);
close(img_fd);
return -1;
}
if (fstat(img_fd, &st) == -1) {

struct stat st;
if (fstat(dev->img_fd, &st) == -1) {
log_error("cannot stat %s, Error code is %d", img_path, errno);
close(img_fd);
return -1;
}
blk_size = st.st_size / 512; // 512 bytes per block
uint64_t blk_size = st.st_size / SECTOR_BSIZE;
dev->config.capacity = blk_size;
dev->config.size_max = blk_size;
dev->img_fd = img_fd;
vdev->virtio_close = virtio_blk_close;
log_info("debug: virtio_blk_init: %s, size is %lld", img_path,

log_info("virtio_blk_init: %s, size is %" PRIu64, img_path,
dev->config.capacity);
return 0;
}
Expand Down Expand Up @@ -227,7 +230,7 @@ static struct blkp_req *virtq_blk_handle_one_request(VirtQueue *vq) {
return NULL;
}

int virtio_blk_notify_handler(VirtIODevice *vdev, VirtQueue *vq) {
static int virtio_blk_notify_handler(VirtIODevice *vdev, VirtQueue *vq) {
log_debug("virtio blk notify handler enter");
BlkDev *blkDev = (BlkDev *)vdev->dev;
struct blkp_req *breq;
Expand All @@ -252,17 +255,74 @@ int virtio_blk_notify_handler(VirtIODevice *vdev, VirtQueue *vq) {
return 0;
}

void virtio_blk_close(VirtIODevice *vdev) {
static void virtio_blk_reset(VirtIODevice *vdev) { (void)vdev; }

/*
* Shut down the blk device: signal close, wait for the worker to exit,
* then release all resources.
*/
static void virtio_blk_close(VirtIODevice *vdev) {
if (!vdev)
return;

BlkDev *dev = vdev->dev;
pthread_mutex_lock(&dev->mtx);
dev->close = 1;
pthread_cond_signal(&dev->cond);
pthread_mutex_unlock(&dev->mtx);
pthread_join(dev->tid, NULL);
pthread_mutex_destroy(&dev->mtx);
pthread_cond_destroy(&dev->cond);
close(dev->img_fd);
free(dev);
if (dev) {
pthread_mutex_lock(&dev->mtx);
dev->close = 1;
pthread_cond_signal(&dev->cond);
pthread_mutex_unlock(&dev->mtx);
pthread_join(dev->tid, NULL);
pthread_mutex_destroy(&dev->mtx);
pthread_cond_destroy(&dev->cond);
if (dev->img_fd >= 0)
close(dev->img_fd);
free(dev);
vdev->dev = NULL;
}
free(vdev->vqs);
vdev->vqs = NULL;
free(vdev);
}
}

static int virtio_blk_do_init(VirtIODevice *vdev, const void *params) {
const struct virtio_blk_init_params *p = params;
if (!p)
return -EINVAL;
if (!init_blk_dev(vdev))
return -ENOMEM;
if (virtio_blk_init(vdev, p->img_path) != 0)
return -EIO;
return 0;
}

const struct virtio_device_ops virtio_blk_ops = {
.type = VirtioTBlock,
.features = BLK_SUPPORTED_FEATURES,
.num_queues = 1,
.queue_max_size = VIRTQUEUE_BLK_MAX_SIZE,
.init = virtio_blk_do_init,
.close = virtio_blk_close,
.reset = virtio_blk_reset,
.notify_handlers = {virtio_blk_notify_handler},
};

static int virtio_blk_parse_params(const cJSON *json, void **out) {
struct virtio_blk_init_params *p = calloc(1, sizeof(*p));
if (!p)
return -ENOMEM;
cJSON *img = cJSON_GetObjectItem(json, "img");
if (!cJSON_IsString(img) || !img->valuestring[0]) {
free(p);
return -EINVAL;
}
p->img_path = img->valuestring;
*out = p;
return 0;
}

static void virtio_blk_free_params(void *params) { free(params); }

const struct virtio_config_ops virtio_blk_config_ops = {
.parse = virtio_blk_parse_params,
.free = virtio_blk_free_params,
};
87 changes: 60 additions & 27 deletions tools/virtio/devices/console/virtio_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

static uint8_t trashbuf[1024];

ConsoleDev *init_console_dev() {
static ConsoleDev *init_console_dev() {
ConsoleDev *dev = (ConsoleDev *)malloc(sizeof(ConsoleDev));
dev->config.cols = 80;
dev->config.rows = 25;
Expand Down Expand Up @@ -87,7 +87,7 @@ static void virtio_console_event_handler(int fd, int epoll_type, void *param) {
return;
}

int virtio_console_init(VirtIODevice *vdev) {
static int virtio_console_init(VirtIODevice *vdev) {
ConsoleDev *dev = (ConsoleDev *)vdev->dev;
int master_fd, slave_fd;
char *slave_name;
Expand Down Expand Up @@ -115,8 +115,6 @@ int virtio_console_init(VirtIODevice *vdev) {
slave_fd = open(slave_name, O_RDWR);
if (slave_fd < 0) {
log_error("Failed to open slave pty, errno is %d", errno);
close(master_fd);
dev->master_fd = -1;
return -1;
}

Expand All @@ -129,13 +127,7 @@ int virtio_console_init(VirtIODevice *vdev) {
dev->slave_keepalive_fd = slave_fd;

if (set_nonblocking(dev->master_fd) < 0) {
close(dev->master_fd);
if (dev->slave_keepalive_fd >= 0) {
close(dev->slave_keepalive_fd);
dev->slave_keepalive_fd = -1;
}
dev->master_fd = -1;
log_error("Failed to set nonblocking mode, fd closed!");
log_error("Failed to set nonblocking mode");
return -1;
}

Expand All @@ -144,20 +136,14 @@ int virtio_console_init(VirtIODevice *vdev) {

if (dev->event == NULL) {
log_error("Can't register console event");
close(master_fd);
if (dev->slave_keepalive_fd >= 0) {
close(dev->slave_keepalive_fd);
dev->slave_keepalive_fd = -1;
}
dev->master_fd = -1;
return -1;
}

vdev->virtio_close = virtio_console_close;
return 0;
}

int virtio_console_rxq_notify_handler(VirtIODevice *vdev, VirtQueue *vq) {
static int virtio_console_rxq_notify_handler(VirtIODevice *vdev,
VirtQueue *vq) {
log_debug("%s", __func__);
ConsoleDev *dev = (ConsoleDev *)vdev->dev;
if (dev->rx_ready <= 0) {
Expand Down Expand Up @@ -191,7 +177,8 @@ static void virtq_tx_handle_one_request(ConsoleDev *dev, VirtQueue *vq) {
free(iov);
}

int virtio_console_txq_notify_handler(VirtIODevice *vdev, VirtQueue *vq) {
static int virtio_console_txq_notify_handler(VirtIODevice *vdev,
VirtQueue *vq) {
log_debug("%s", __func__);
while (!virtqueue_is_empty(vq)) {
virtqueue_disable_notify(vq);
Expand All @@ -204,14 +191,60 @@ int virtio_console_txq_notify_handler(VirtIODevice *vdev, VirtQueue *vq) {
return 0;
}

void virtio_console_close(VirtIODevice *vdev) {
static void virtio_console_reset(VirtIODevice *vdev) { (void)vdev; }

static void virtio_console_close(VirtIODevice *vdev) {
if (!vdev)
return;

ConsoleDev *dev = vdev->dev;
close(dev->master_fd);
if (dev->slave_keepalive_fd >= 0) {
close(dev->slave_keepalive_fd);
if (dev) {
if (dev->master_fd >= 0)
close(dev->master_fd);
if (dev->slave_keepalive_fd >= 0)
close(dev->slave_keepalive_fd);
remove_event(dev->event);
free(dev->event);
free(dev);
vdev->dev = NULL;
}
free(dev->event);
free(dev);
free(vdev->vqs);
vdev->vqs = NULL;
free(vdev);
}
}

static int virtio_console_do_init(VirtIODevice *vdev, const void *params) {
(void)params;
vdev->dev = init_console_dev();
if (!vdev->dev)
return -ENOMEM;
return virtio_console_init(vdev);
}

const struct virtio_device_ops virtio_console_ops = {
.type = VirtioTConsole,
.features = CONSOLE_SUPPORTED_FEATURES,
.num_queues = CONSOLE_MAX_QUEUES,
.queue_max_size = VIRTQUEUE_CONSOLE_MAX_SIZE,
.init = virtio_console_do_init,
.close = virtio_console_close,
.reset = virtio_console_reset,
.notify_handlers =
{
[CONSOLE_QUEUE_RX] = virtio_console_rxq_notify_handler,
[CONSOLE_QUEUE_TX] = virtio_console_txq_notify_handler,
},
};

static int virtio_console_parse_params(const cJSON *json, void **out) {
(void)json;
*out = NULL;
return 0;
}

static void virtio_console_free_params(void *params) { (void)params; }

const struct virtio_config_ops virtio_console_config_ops = {
.parse = virtio_console_parse_params,
.free = virtio_console_free_params,
};
Loading
Loading