From 0458d1ca16af0a6903e3409634bcd3cb5d445ca6 Mon Sep 17 00:00:00 2001
Message-Id: <0458d1ca16af0a6903e3409634bcd3cb5d445ca6.1357726992.git.minovotn@redhat.com>
In-Reply-To: <4f8efce613a639a3c1e3022c521d6c70b7154de8.1357726992.git.minovotn@redhat.com>
References: <4f8efce613a639a3c1e3022c521d6c70b7154de8.1357726992.git.minovotn@redhat.com>
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Wed, 2 Jan 2013 15:02:34 +0100
Subject: [PATCH 11/16] virtio-blk: Turn drive serial into a qdev property

RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: <1357138959-1918-12-git-send-email-stefanha@redhat.com>
Patchwork-id: 45524
O-Subject: [RHEL6.4 qemu-kvm PATCH v5 11/16] virtio-blk: Turn drive serial into a qdev property
Bugzilla: 877836
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>

From: Markus Armbruster <armbru@redhat.com>

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>
(cherry picked from a8686a9b2b347d0619141e950221c4d6d0311d0b)

Conflicts:
	hw/s390-virtio-bus.c
	hw/virtio-blk.c
	hw/virtio-pci.h

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/s390-virtio-bus.c |  4 +++-
 hw/s390-virtio-bus.h |  1 +
 hw/virtio-blk.c      | 29 +++++++++++++++++++----------
 hw/virtio-blk.h      |  2 ++
 hw/virtio-pci.c      |  5 ++++-
 hw/virtio.h          |  3 ++-
 6 files changed, 31 insertions(+), 13 deletions(-)

Signed-off-by: Michal Novotny <minovotn@redhat.com>
---
 hw/s390-virtio-bus.c |  4 +++-
 hw/s390-virtio-bus.h |  1 +
 hw/virtio-blk.c      | 29 +++++++++++++++++++----------
 hw/virtio-blk.h      |  2 ++
 hw/virtio-pci.c      |  5 ++++-
 hw/virtio.h          |  3 ++-
 6 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index 68b595c..d18f916 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -124,7 +124,8 @@ static int s390_virtio_blk_init(VirtIOS390Device *dev)
 {
     VirtIODevice *vdev;
 
-    vdev = virtio_blk_init((DeviceState *)dev, dev->block.dinfo);
+    vdev = virtio_blk_init((DeviceState *)dev, &dev->block,
+                           &dev->block_serial);
     if (!vdev) {
         return -1;
     }
@@ -344,6 +345,7 @@ static VirtIOS390DeviceInfo s390_virtio_blk = {
     .qdev.size = sizeof(VirtIOS390Device),
     .qdev.props = (Property[]) {
         DEFINE_BLOCK_PROPERTIES(VirtIOS390Device, block),
+        DEFINE_PROP_STRING("serial", VirtIOS390Device, block_serial),
         DEFINE_PROP_END_OF_LIST(),
     },
 };
diff --git a/hw/s390-virtio-bus.h b/hw/s390-virtio-bus.h
index 0357dd3..bb0b9a7 100644
--- a/hw/s390-virtio-bus.h
+++ b/hw/s390-virtio-bus.h
@@ -39,6 +39,7 @@ typedef struct VirtIOS390Device {
     uint8_t feat_len;
     VirtIODevice *vdev;
     BlockConf block;
+    char *block_serial;
     NICConf nic;
     uint32_t host_features;
     /* Max. number of ports we can have for a the virtio-serial device */
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index 218bd7b..8b3be64 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;
 
@@ -392,8 +392,13 @@ static void virtio_blk_handle_request(VirtIOBlockReq *req,
     } else if (req->out->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);
         qemu_free(req);
     } else if (req->out->type & VIRTIO_BLK_T_OUT) {
@@ -586,7 +591,8 @@ static const BlockDevOps virtio_block_ops = {
     .resize_cb = virtio_blk_resize,
 };
 
-VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
+VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf,
+                              char **serial)
 {
     VirtIOBlock *s;
     int cylinders, heads, secs;
@@ -602,6 +608,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));
@@ -611,17 +625,12 @@ 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 / 512) - 1;
     bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
     bdrv_set_geometry_hint(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);
diff --git a/hw/virtio-blk.h b/hw/virtio-blk.h
index fff46da..5645d2b 100644
--- a/hw/virtio-blk.h
+++ b/hw/virtio-blk.h
@@ -34,6 +34,8 @@
 #define VIRTIO_BLK_F_WCACHE     9       /* write cache enabled */
 #define VIRTIO_BLK_F_TOPOLOGY   10      /* Topology information is available */
 
+#define VIRTIO_BLK_ID_BYTES     20      /* ID string length */
+
 struct virtio_blk_config
 {
     uint64_t capacity;
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index e8c08bf..9e001d2 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -114,6 +114,7 @@ typedef struct {
     uint32_t class_code;
     uint32_t nvectors;
     BlockConf block;
+    char *block_serial;
     NICConf nic;
     VirtIOSCSIConf scsi;
     uint32_t host_features;
@@ -826,7 +827,8 @@ static int virtio_blk_init_pci(PCIDevice *pci_dev)
         proxy->class_code != PCI_CLASS_STORAGE_OTHER)
         proxy->class_code = PCI_CLASS_STORAGE_SCSI;
 
-    vdev = virtio_blk_init(&pci_dev->qdev, &proxy->block);
+    vdev = virtio_blk_init(&pci_dev->qdev, &proxy->block,
+                           &proxy->block_serial);
     if (!vdev) {
         return -1;
     }
@@ -987,6 +989,7 @@ static PCIDeviceInfo virtio_info[] = {
         .qdev.props = (Property[]) {
             DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
             DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block),
+            DEFINE_PROP_STRING("serial", VirtIOPCIProxy, block_serial),
             DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
                             VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
             DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
diff --git a/hw/virtio.h b/hw/virtio.h
index d0ddb44..dadf563 100644
--- a/hw/virtio.h
+++ b/hw/virtio.h
@@ -196,7 +196,8 @@ void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding,
                         void *opaque);
 
 /* Base devices.  */
-VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf);
+VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf,
+                              char **serial);
 struct virtio_net_conf;
 VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf,
                               struct virtio_net_conf *net);
-- 
1.7.11.7

