summaryrefslogtreecommitdiff
path: root/hw/virtio-blk.c
diff options
context:
space:
mode:
authorMarkus Armbruster <armbru@redhat.com>2011-06-20 11:35:18 +0200
committerKevin Wolf <kwolf@redhat.com>2011-07-05 11:23:29 +0200
commita8686a9b2b347d0619141e950221c4d6d0311d0b (patch)
tree0e41513d813d57577210b5e10518ffab250156ee /hw/virtio-blk.c
parent343f85685ce3f9613c13e4d0f884698194b6a4f6 (diff)
downloadqemu-a8686a9b2b347d0619141e950221c4d6d0311d0b.tar.gz
virtio-blk: Turn drive serial into a qdev property
It needs to be a qdev property, because it belongs to the drive's guest part. Precedence: commit a0fef654 and 6ced55a5. Bonus: info qtree now shows the serial number. Signed-off-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'hw/virtio-blk.c')
-rw-r--r--hw/virtio-blk.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index 91e0394af9..6471ac85ab 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -28,8 +28,8 @@ typedef struct VirtIOBlock
void *rq;
QEMUBH *bh;
BlockConf *conf;
+ char *serial;
unsigned short sector_mask;
- char sn[BLOCK_SERIAL_STRLEN];
DeviceState *qdev;
} VirtIOBlock;
@@ -362,8 +362,13 @@ static void virtio_blk_handle_request(VirtIOBlockReq *req,
} else if (type & VIRTIO_BLK_T_GET_ID) {
VirtIOBlock *s = req->dev;
- memcpy(req->elem.in_sg[0].iov_base, s->sn,
- MIN(req->elem.in_sg[0].iov_len, sizeof(s->sn)));
+ /*
+ * NB: per existing s/n string convention the string is
+ * terminated by '\0' only when shorter than buffer.
+ */
+ strncpy(req->elem.in_sg[0].iov_base,
+ s->serial ? s->serial : "",
+ MIN(req->elem.in_sg[0].iov_len, VIRTIO_BLK_ID_BYTES));
virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
} else if (type & VIRTIO_BLK_T_OUT) {
qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1],
@@ -531,7 +536,8 @@ static void virtio_blk_change_cb(void *opaque, int reason)
}
}
-VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
+VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf,
+ char **serial)
{
VirtIOBlock *s;
int cylinders, heads, secs;
@@ -547,6 +553,14 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
return NULL;
}
+ if (!*serial) {
+ /* try to fall back to value set with legacy -drive serial=... */
+ dinfo = drive_get_by_blockdev(conf->bs);
+ if (*dinfo->serial) {
+ *serial = strdup(dinfo->serial);
+ }
+ }
+
s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
sizeof(struct virtio_blk_config),
sizeof(VirtIOBlock));
@@ -556,16 +570,11 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
s->vdev.reset = virtio_blk_reset;
s->bs = conf->bs;
s->conf = conf;
+ s->serial = *serial;
s->rq = NULL;
s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;
bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
- /* NB: per existing s/n string convention the string is terminated
- * by '\0' only when less than sizeof (s->sn)
- */
- dinfo = drive_get_by_blockdev(s->bs);
- strncpy(s->sn, dinfo->serial, sizeof (s->sn));
-
s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);