Skip to content

Commit

Permalink
Merge remote-tracking branch 'bonzini/virtio' into staging
Browse files Browse the repository at this point in the history
# By Andreas Färber (18) and Paolo Bonzini (12)
# Via Paolo Bonzini
* bonzini/virtio: (30 commits)
  virtio: Convert exit to unrealize
  virtio: Complete converting VirtioDevice to QOM realize
  virtio-scsi: Convert to QOM realize
  virtio-rng: Convert to QOM realize
  virtio-balloon: Convert to QOM realize
  virtio-net: Convert to QOM realize
  virtio-serial: Convert to QOM realize
  virtio-blk: Convert to QOM realize
  virtio-9p: Convert to QOM realize
  virtio: Start converting VirtioDevice to QOM realize
  virtio-scsi: QOM realize preparations
  virtio-rng: QOM realize preparations
  virtio-balloon: QOM realize preparations
  virtio-net: QOM realize preparations
  virtio-serial: QOM realize preparations
  virtio-blk: QOM realize preparations
  virtio-9p: QOM realize preparations
  virtio-blk-dataplane: Improve error reporting
  virtio-pci: add device_unplugged callback
  virtio-rng: switch exit callback to VirtioDeviceClass
  ...
  • Loading branch information
Anthony Liguori committed Dec 13, 2013
2 parents 5d0e228 + 306ec6c commit e157b8f
Show file tree
Hide file tree
Showing 22 changed files with 413 additions and 334 deletions.
43 changes: 21 additions & 22 deletions hw/9pfs/virtio-9p-device.c
Expand Up @@ -41,15 +41,16 @@ static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config)
g_free(cfg);
}

static int virtio_9p_device_init(VirtIODevice *vdev)
static void virtio_9p_device_realize(DeviceState *dev, Error **errp)
{
V9fsState *s = VIRTIO_9P(vdev);
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
V9fsState *s = VIRTIO_9P(dev);
int i, len;
struct stat stat;
FsDriverEntry *fse;
V9fsPath path;

virtio_init(VIRTIO_DEVICE(s), "virtio-9p", VIRTIO_ID_9P,
virtio_init(vdev, "virtio-9p", VIRTIO_ID_9P,
sizeof(struct virtio_9p_config) + MAX_TAG_LEN);

/* initialize pdu allocator */
Expand All @@ -67,16 +68,16 @@ static int virtio_9p_device_init(VirtIODevice *vdev)

if (!fse) {
/* We don't have a fsdev identified by fsdev_id */
fprintf(stderr, "Virtio-9p device couldn't find fsdev with the "
"id = %s\n",
s->fsconf.fsdev_id ? s->fsconf.fsdev_id : "NULL");
error_setg(errp, "Virtio-9p device couldn't find fsdev with the "
"id = %s",
s->fsconf.fsdev_id ? s->fsconf.fsdev_id : "NULL");
goto out;
}

if (!s->fsconf.tag) {
/* we haven't specified a mount_tag */
fprintf(stderr, "fsdev with id %s needs mount_tag arguments\n",
s->fsconf.fsdev_id);
error_setg(errp, "fsdev with id %s needs mount_tag arguments",
s->fsconf.fsdev_id);
goto out;
}

Expand All @@ -85,8 +86,8 @@ static int virtio_9p_device_init(VirtIODevice *vdev)
s->ctx.exops.get_st_gen = NULL;
len = strlen(s->fsconf.tag);
if (len > MAX_TAG_LEN - 1) {
fprintf(stderr, "mount tag '%s' (%d bytes) is longer than "
"maximum (%d bytes)", s->fsconf.tag, len, MAX_TAG_LEN - 1);
error_setg(errp, "mount tag '%s' (%d bytes) is longer than "
"maximum (%d bytes)", s->fsconf.tag, len, MAX_TAG_LEN - 1);
goto out;
}

Expand All @@ -99,12 +100,12 @@ static int virtio_9p_device_init(VirtIODevice *vdev)
qemu_co_rwlock_init(&s->rename_lock);

if (s->ops->init(&s->ctx) < 0) {
fprintf(stderr, "Virtio-9p Failed to initialize fs-driver with id:%s"
" and export path:%s\n", s->fsconf.fsdev_id, s->ctx.fs_root);
error_setg(errp, "Virtio-9p Failed to initialize fs-driver with id:%s"
" and export path:%s", s->fsconf.fsdev_id, s->ctx.fs_root);
goto out;
}
if (v9fs_init_worker_threads() < 0) {
fprintf(stderr, "worker thread initialization failed\n");
error_setg(errp, "worker thread initialization failed");
goto out;
}

Expand All @@ -114,28 +115,25 @@ static int virtio_9p_device_init(VirtIODevice *vdev)
* use co-routines here.
*/
if (s->ops->name_to_path(&s->ctx, NULL, "/", &path) < 0) {
fprintf(stderr,
"error in converting name to path %s", strerror(errno));
error_setg(errp,
"error in converting name to path %s", strerror(errno));
goto out;
}
if (s->ops->lstat(&s->ctx, &path, &stat)) {
fprintf(stderr, "share path %s does not exist\n", fse->path);
error_setg(errp, "share path %s does not exist", fse->path);
goto out;
} else if (!S_ISDIR(stat.st_mode)) {
fprintf(stderr, "share path %s is not a directory\n", fse->path);
error_setg(errp, "share path %s is not a directory", fse->path);
goto out;
}
v9fs_path_free(&path);

return 0;
return;
out:
g_free(s->ctx.fs_root);
g_free(s->tag);
virtio_cleanup(vdev);
v9fs_path_free(&path);

return -1;

}

/* virtio-9p device */
Expand All @@ -149,9 +147,10 @@ static void virtio_9p_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);

dc->props = virtio_9p_properties;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
vdc->init = virtio_9p_device_init;
vdc->realize = virtio_9p_device_realize;
vdc->get_features = virtio_9p_get_features;
vdc->get_config = virtio_9p_get_config;
}
Expand Down
30 changes: 16 additions & 14 deletions hw/block/dataplane/virtio-blk.c
Expand Up @@ -380,42 +380,45 @@ static void start_data_plane_bh(void *opaque)
s, QEMU_THREAD_JOINABLE);
}

bool virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
VirtIOBlockDataPlane **dataplane)
void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
VirtIOBlockDataPlane **dataplane,
Error **errp)
{
VirtIOBlockDataPlane *s;
int fd;

*dataplane = NULL;

if (!blk->data_plane) {
return true;
return;
}

if (blk->scsi) {
error_report("device is incompatible with x-data-plane, use scsi=off");
return false;
error_setg(errp,
"device is incompatible with x-data-plane, use scsi=off");
return;
}

if (blk->config_wce) {
error_report("device is incompatible with x-data-plane, "
"use config-wce=off");
return false;
error_setg(errp, "device is incompatible with x-data-plane, "
"use config-wce=off");
return;
}

/* If dataplane is (re-)enabled while the guest is running there could be
* block jobs that can conflict.
*/
if (bdrv_in_use(blk->conf.bs)) {
error_report("cannot start dataplane thread while device is in use");
return false;
error_setg(errp,
"cannot start dataplane thread while device is in use");
return;
}

fd = raw_get_aio_fd(blk->conf.bs);
if (fd < 0) {
error_report("drive is incompatible with x-data-plane, "
"use format=raw,cache=none,aio=native");
return false;
error_setg(errp, "drive is incompatible with x-data-plane, "
"use format=raw,cache=none,aio=native");
return;
}

s = g_new0(VirtIOBlockDataPlane, 1);
Expand All @@ -427,7 +430,6 @@ bool virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
bdrv_set_in_use(blk->conf.bs, 1);

*dataplane = s;
return true;
}

void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s)
Expand Down
5 changes: 3 additions & 2 deletions hw/block/dataplane/virtio-blk.h
Expand Up @@ -19,8 +19,9 @@

typedef struct VirtIOBlockDataPlane VirtIOBlockDataPlane;

bool virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
VirtIOBlockDataPlane **dataplane);
void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
VirtIOBlockDataPlane **dataplane,
Error **errp);
void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s);
void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s);
void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s);
Expand Down
47 changes: 29 additions & 18 deletions hw/block/virtio-blk.c
Expand Up @@ -657,6 +657,7 @@ static void virtio_blk_migration_state_changed(Notifier *notifier, void *data)
VirtIOBlock *s = container_of(notifier, VirtIOBlock,
migration_state_notifier);
MigrationState *mig = data;
Error *err = NULL;

if (migration_in_setup(mig)) {
if (!s->dataplane) {
Expand All @@ -671,31 +672,39 @@ static void virtio_blk_migration_state_changed(Notifier *notifier, void *data)
}
bdrv_drain_all(); /* complete in-flight non-dataplane requests */
virtio_blk_data_plane_create(VIRTIO_DEVICE(s), &s->blk,
&s->dataplane);
&s->dataplane, &err);
if (err != NULL) {
error_report("%s", error_get_pretty(err));
error_free(err);
}
}
}
#endif /* CONFIG_VIRTIO_BLK_DATA_PLANE */

static int virtio_blk_device_init(VirtIODevice *vdev)
static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
{
DeviceState *qdev = DEVICE(vdev);
VirtIOBlock *s = VIRTIO_BLK(vdev);
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VirtIOBlock *s = VIRTIO_BLK(dev);
VirtIOBlkConf *blk = &(s->blk);
#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
Error *err = NULL;
#endif
static int virtio_blk_id;

if (!blk->conf.bs) {
error_report("drive property not set");
return -1;
error_setg(errp, "drive property not set");
return;
}
if (!bdrv_is_inserted(blk->conf.bs)) {
error_report("Device needs media, but drive is empty");
return -1;
error_setg(errp, "Device needs media, but drive is empty");
return;
}

blkconf_serial(&blk->conf, &blk->serial);
s->original_wce = bdrv_enable_write_cache(blk->conf.bs);
if (blkconf_geometry(&blk->conf, NULL, 65535, 255, 255) < 0) {
return -1;
error_setg(errp, "Error setting geometry");
return;
}

virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK,
Expand All @@ -708,30 +717,32 @@ static int virtio_blk_device_init(VirtIODevice *vdev)

s->vq = virtio_add_queue(vdev, 128, virtio_blk_handle_output);
#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
if (!virtio_blk_data_plane_create(vdev, blk, &s->dataplane)) {
virtio_blk_data_plane_create(vdev, blk, &s->dataplane, &err);
if (err != NULL) {
error_propagate(errp, err);
virtio_cleanup(vdev);
return -1;
return;
}
s->migration_state_notifier.notify = virtio_blk_migration_state_changed;
add_migration_state_change_notifier(&s->migration_state_notifier);
#endif

s->change = qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
register_savevm(qdev, "virtio-blk", virtio_blk_id++, 2,
register_savevm(dev, "virtio-blk", virtio_blk_id++, 2,
virtio_blk_save, virtio_blk_load, s);
bdrv_set_dev_ops(s->bs, &virtio_block_ops, s);
bdrv_set_buffer_alignment(s->bs, s->conf->logical_block_size);

bdrv_iostatus_enable(s->bs);

add_boot_device_path(s->conf->bootindex, qdev, "/disk@0,0");
return 0;
add_boot_device_path(s->conf->bootindex, dev, "/disk@0,0");
}

static int virtio_blk_device_exit(DeviceState *dev)
static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VirtIOBlock *s = VIRTIO_BLK(dev);

#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
remove_migration_state_change_notifier(&s->migration_state_notifier);
virtio_blk_data_plane_destroy(s->dataplane);
Expand All @@ -741,7 +752,6 @@ static int virtio_blk_device_exit(DeviceState *dev)
unregister_savevm(dev, "virtio-blk", s);
blockdev_mark_auto_del(s->bs);
virtio_cleanup(vdev);
return 0;
}

static Property virtio_blk_properties[] = {
Expand All @@ -753,10 +763,11 @@ static void virtio_blk_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
dc->exit = virtio_blk_device_exit;

dc->props = virtio_blk_properties;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
vdc->init = virtio_blk_device_init;
vdc->realize = virtio_blk_device_realize;
vdc->unrealize = virtio_blk_device_unrealize;
vdc->get_config = virtio_blk_update_config;
vdc->set_config = virtio_blk_set_config;
vdc->get_features = virtio_blk_get_features;
Expand Down

0 comments on commit e157b8f

Please sign in to comment.