[PATCH 1/2] Add serial number support for virtio_blk, V4

2009-05-28 Thread john cooper
qemu-vblk-serial-4.patch



diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index 8dd3c7a..0b7ebe9 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -25,6 +25,7 @@ typedef struct VirtIOBlock
 BlockDriverState *bs;
 VirtQueue *vq;
 void *rq;
+char serial_str[BLOCK_SERIAL_STRLEN + 1];
 } VirtIOBlock;
 
 static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev)
@@ -285,6 +286,50 @@ static void virtio_blk_reset(VirtIODevice *vdev)
 qemu_aio_flush();
 }
 
+/* store identify data in little endian format
+ */
+static inline void put_le16(uint16_t *p, unsigned int v)
+{
+*p = cpu_to_le16(v);
+}
+
+/* copy to *dst from *src, nul pad dst tail as needed to len bytes
+ */
+static inline void padstr(char *dst, const char *src, int len)
+{
+while (len--)
+*dst++ = *src ? *src++ : '\0';
+}
+
+/* setup simulated identify data as appropriate for virtio block device
+ *
+ * ref: AT Attachment 8 - ATA/ATAPI Command Set (ATA8-ACS)
+ */
+static inline void virtio_identify_template(struct virtio_blk_config *bc)
+{
+uint16_t *p = bc-identify[0];
+uint64_t lba_sectors = bc-capacity;
+
+memset(p, 0, sizeof(bc-identify));
+put_le16(p + 0, 0x0);/* ATA device */
+padstr((char *)(p + 23), QEMU_VERSION, 8);   /* firmware revision */
+padstr((char *)(p + 27), QEMU VIRT_BLK, 40);   /* model# */
+put_le16(p + 47, 0x80ff);/* max xfer 255 sectors */
+put_le16(p + 49, 0x0b00);/* support IORDY/LBA/DMA 
*/
+put_le16(p + 59, 0x1ff); /* cur xfer 255 sectors */
+put_le16(p + 80, 0x1f0); /* support ATA8/7/6/5/4 */
+put_le16(p + 81, 0x16);
+put_le16(p + 82, 0x400);
+put_le16(p + 83, 0x400);
+put_le16(p + 100, lba_sectors);
+put_le16(p + 101, lba_sectors  16);
+put_le16(p + 102, lba_sectors  32);
+put_le16(p + 103, lba_sectors  48);
+}
+
+/* coalesce internal state, copy to pci i/o region 0
+ */
+
 static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
 {
 VirtIOBlock *s = to_virtio_blk(vdev);
@@ -299,11 +344,15 @@ static void virtio_blk_update_config(VirtIODevice *vdev, 
uint8_t *config)
 stw_raw(blkcfg.cylinders, cylinders);
 blkcfg.heads = heads;
 blkcfg.sectors = secs;
+virtio_identify_template(blkcfg);
+memcpy(blkcfg.identify[VIRTIO_BLK_ID_SN], s-serial_str,
+VIRTIO_BLK_ID_SN_BYTES);
 memcpy(config, blkcfg, sizeof(blkcfg));
 }
 
 static uint32_t virtio_blk_get_features(VirtIODevice *vdev)
 {
+VirtIOBlock *s = to_virtio_blk(vdev);
 uint32_t features = 0;
 
 features |= (1  VIRTIO_BLK_F_SEG_MAX);
@@ -311,6 +360,8 @@ static uint32_t virtio_blk_get_features(VirtIODevice *vdev)
 #ifdef __linux__
 features |= (1  VIRTIO_BLK_F_SCSI);
 #endif
+if (strcmp(s-serial_str, 0))
+features |= 1  VIRTIO_BLK_F_IDENTIFY;
 
 return features;
 }
@@ -354,6 +405,7 @@ VirtIODevice *virtio_blk_init(DeviceState *dev)
 int cylinders, heads, secs;
 static int virtio_blk_id;
 BlockDriverState *bs;
+char *ps;
 
 s = (VirtIOBlock *)virtio_common_init(virtio-blk, VIRTIO_ID_BLOCK,
   sizeof(struct virtio_blk_config),
@@ -365,6 +417,10 @@ VirtIODevice *virtio_blk_init(DeviceState *dev)
 s-vdev.reset = virtio_blk_reset;
 s-bs = bs;
 s-rq = NULL;
+if (strlen(ps = (char *)drive_get_serial(bs)))
+strncpy(s-serial_str, ps, sizeof(s-serial_str));
+else
+snprintf(s-serial_str, sizeof(s-serial_str), 0);
 bs-private = dev;
 bdrv_guess_geometry(s-bs, cylinders, heads, secs);
 bdrv_set_geometry_hint(s-bs, cylinders, heads, secs);
diff --git a/hw/virtio-blk.h b/hw/virtio-blk.h
index dff3e0c..1be4342 100644
--- a/hw/virtio-blk.h
+++ b/hw/virtio-blk.h
@@ -30,6 +30,11 @@
 #define VIRTIO_BLK_F_RO 5   /* Disk is read-only */
 #define VIRTIO_BLK_F_BLK_SIZE   6   /* Block size of disk is available*/
 #define VIRTIO_BLK_F_SCSI   7   /* Supports scsi command passthru */
+#define VIRTIO_BLK_F_IDENTIFY   8   /* ATA IDENTIFY supported */
+
+#define VIRTIO_BLK_ID_LEN   256 /* length of identify u16 array */
+#define VIRTIO_BLK_ID_SN10  /* start of char * serial# */
+#define VIRTIO_BLK_ID_SN_BYTES  20  /* length in bytes of serial# */
 
 struct virtio_blk_config
 {
@@ -39,6 +44,8 @@ struct virtio_blk_config
 uint16_t cylinders;
 uint8_t heads;
 uint8_t sectors;
+uint32_t _blk_size;/* structure pad, currently unused */
+uint16_t identify[VIRTIO_BLK_ID_LEN];
 } __attribute__((packed));
 
 /* These two define direction. */
diff --git a/sysemu.h b/sysemu.h
index 47d001e..d3df19f 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -152,6 +152,8 @@ typedef enum {
 BLOCK_ERR_STOP_ANY
 } BlockInterfaceErrorAction;
 
+#define BLOCK_SERIAL_STRLEN 20
+
 typedef struct DriveInfo {
 BlockDriverState *bdrv;
 

Re: [Qemu-devel] [PATCH 1/2] Add serial number support for virtio_blk, V3

2009-05-27 Thread Christoph Hellwig
Looks good to me.  In a couple of places you have spaces beforing
the opening brace as in:

+memcpy(blkcfg.serial, s-serial_str, sizeof (blkcfg.serial));

which is not the style used in the surrounding code, I'd suggest
removing them.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] Add serial number support for virtio_blk, V3

2009-05-26 Thread john cooper


--
john.coo...@redhat.com

diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index dad4ef0..90825a8 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -25,6 +25,7 @@ typedef struct VirtIOBlock
 BlockDriverState *bs;
 VirtQueue *vq;
 void *rq;
+char serial_str[BLOCK_SERIAL_STRLEN + 1];
 } VirtIOBlock;
 
 static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev)
@@ -285,6 +286,8 @@ static void virtio_blk_reset(VirtIODevice *vdev)
 qemu_aio_flush();
 }
 
+/* coalesce internal state, copy to pci i/o region 0
+ */
 static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
 {
 VirtIOBlock *s = to_virtio_blk(vdev);
@@ -299,11 +302,13 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
 stw_raw(blkcfg.cylinders, cylinders);
 blkcfg.heads = heads;
 blkcfg.sectors = secs;
+memcpy(blkcfg.serial, s-serial_str, sizeof (blkcfg.serial));
 memcpy(config, blkcfg, sizeof(blkcfg));
 }
 
 static uint32_t virtio_blk_get_features(VirtIODevice *vdev)
 {
+VirtIOBlock *s = to_virtio_blk(vdev);
 uint32_t features = 0;
 
 features |= (1  VIRTIO_BLK_F_SEG_MAX);
@@ -311,6 +316,8 @@ static uint32_t virtio_blk_get_features(VirtIODevice *vdev)
 #ifdef __linux__
 features |= (1  VIRTIO_BLK_F_SCSI);
 #endif
+if (strcmp(s-serial_str, 0))
+features |= 1  VIRTIO_BLK_F_SN;
 
 return features;
 }
@@ -353,6 +360,7 @@ void *virtio_blk_init(PCIBus *bus, BlockDriverState *bs)
 VirtIOBlock *s;
 int cylinders, heads, secs;
 static int virtio_blk_id;
+char *ps = drive_get_serial(bs);
 
 s = (VirtIOBlock *)virtio_init_pci(bus, virtio-blk,
PCI_VENDOR_ID_REDHAT_QUMRANET,
@@ -369,6 +377,10 @@ void *virtio_blk_init(PCIBus *bus, BlockDriverState *bs)
 s-vdev.reset = virtio_blk_reset;
 s-bs = bs;
 s-rq = NULL;
+if (strlen(ps))
+strncpy(s-serial_str, ps, sizeof (s-serial_str));
+else
+snprintf(s-serial_str, sizeof (s-serial_str), 0);
 bs-private = s-vdev.pci_dev;
 bdrv_guess_geometry(s-bs, cylinders, heads, secs);
 bdrv_set_geometry_hint(s-bs, cylinders, heads, secs);
diff --git a/hw/virtio-blk.h b/hw/virtio-blk.h
index 5ef6c36..3229394 100644
--- a/hw/virtio-blk.h
+++ b/hw/virtio-blk.h
@@ -31,6 +31,7 @@
 #define VIRTIO_BLK_F_RO 5   /* Disk is read-only */
 #define VIRTIO_BLK_F_BLK_SIZE   6   /* Block size of disk is available*/
 #define VIRTIO_BLK_F_SCSI   7   /* Supports scsi command passthru */
+#define VIRTIO_BLK_F_SN 8   /* serial number supported */
 
 struct virtio_blk_config
 {
@@ -40,6 +41,8 @@ struct virtio_blk_config
 uint16_t cylinders;
 uint8_t heads;
 uint8_t sectors;
+uint32_t _blk_size;/* structure pad, currently unused */
+uint8_t serial[BLOCK_SERIAL_STRLEN];
 } __attribute__((packed));
 
 /* These two define direction. */
diff --git a/sysemu.h b/sysemu.h
index 1f45fd6..185b4e3 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -141,6 +141,8 @@ typedef enum {
 BLOCK_ERR_STOP_ANY
 } BlockInterfaceErrorAction;
 
+#define BLOCK_SERIAL_STRLEN 20
+
 typedef struct DriveInfo {
 BlockDriverState *bdrv;
 BlockInterfaceType type;
@@ -149,7 +151,7 @@ typedef struct DriveInfo {
 int used;
 int drive_opt_idx;
 BlockInterfaceErrorAction onerror;
-char serial[21];
+char serial[BLOCK_SERIAL_STRLEN + 1];
 } DriveInfo;
 
 #define MAX_IDE_DEVS	2


[PATCH 1/2] Add serial number support for virtio_blk, V2

2009-05-13 Thread john cooper


--
john.coo...@redhat.com

diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index dad4ef0..90825a8 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -25,6 +25,7 @@ typedef struct VirtIOBlock
 BlockDriverState *bs;
 VirtQueue *vq;
 void *rq;
+char serial_str[BLOCK_SERIAL_STRLEN + 1];
 } VirtIOBlock;
 
 static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev)
@@ -285,6 +286,8 @@ static void virtio_blk_reset(VirtIODevice *vdev)
 qemu_aio_flush();
 }
 
+/* coalesce internal state, copy to pci i/o region 0
+ */
 static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
 {
 VirtIOBlock *s = to_virtio_blk(vdev);
@@ -299,11 +302,13 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
 stw_raw(blkcfg.cylinders, cylinders);
 blkcfg.heads = heads;
 blkcfg.sectors = secs;
+memcpy(blkcfg.serial, s-serial_str, sizeof (blkcfg.serial));
 memcpy(config, blkcfg, sizeof(blkcfg));
 }
 
 static uint32_t virtio_blk_get_features(VirtIODevice *vdev)
 {
+VirtIOBlock *s = to_virtio_blk(vdev);
 uint32_t features = 0;
 
 features |= (1  VIRTIO_BLK_F_SEG_MAX);
@@ -311,6 +316,8 @@ static uint32_t virtio_blk_get_features(VirtIODevice *vdev)
 #ifdef __linux__
 features |= (1  VIRTIO_BLK_F_SCSI);
 #endif
+if (strcmp(s-serial_str, 0))
+features |= 1  VIRTIO_BLK_F_SN;
 
 return features;
 }
@@ -353,6 +360,7 @@ void *virtio_blk_init(PCIBus *bus, BlockDriverState *bs)
 VirtIOBlock *s;
 int cylinders, heads, secs;
 static int virtio_blk_id;
+char *ps = drive_get_serial(bs);
 
 s = (VirtIOBlock *)virtio_init_pci(bus, virtio-blk,
PCI_VENDOR_ID_REDHAT_QUMRANET,
@@ -369,6 +377,10 @@ void *virtio_blk_init(PCIBus *bus, BlockDriverState *bs)
 s-vdev.reset = virtio_blk_reset;
 s-bs = bs;
 s-rq = NULL;
+if (strlen(ps))
+strncpy(s-serial_str, ps, sizeof (s-serial_str));
+else
+snprintf(s-serial_str, sizeof (s-serial_str), 0);
 bs-private = s-vdev.pci_dev;
 bdrv_guess_geometry(s-bs, cylinders, heads, secs);
 bdrv_set_geometry_hint(s-bs, cylinders, heads, secs);
diff --git a/hw/virtio-blk.h b/hw/virtio-blk.h
index 5ef6c36..3229394 100644
--- a/hw/virtio-blk.h
+++ b/hw/virtio-blk.h
@@ -31,6 +31,7 @@
 #define VIRTIO_BLK_F_RO 5   /* Disk is read-only */
 #define VIRTIO_BLK_F_BLK_SIZE   6   /* Block size of disk is available*/
 #define VIRTIO_BLK_F_SCSI   7   /* Supports scsi command passthru */
+#define VIRTIO_BLK_F_SN 8   /* serial number supported */
 
 struct virtio_blk_config
 {
@@ -40,6 +41,8 @@ struct virtio_blk_config
 uint16_t cylinders;
 uint8_t heads;
 uint8_t sectors;
+uint32_t _blk_size;/* structure pad, currently unused */
+uint8_t serial[BLOCK_SERIAL_STRLEN];
 } __attribute__((packed));
 
 /* These two define direction. */
diff --git a/sysemu.h b/sysemu.h
index 1f45fd6..185b4e3 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -141,6 +141,8 @@ typedef enum {
 BLOCK_ERR_STOP_ANY
 } BlockInterfaceErrorAction;
 
+#define BLOCK_SERIAL_STRLEN 20
+
 typedef struct DriveInfo {
 BlockDriverState *bdrv;
 BlockInterfaceType type;
@@ -149,7 +151,7 @@ typedef struct DriveInfo {
 int used;
 int drive_opt_idx;
 BlockInterfaceErrorAction onerror;
-char serial[21];
+char serial[BLOCK_SERIAL_STRLEN + 1];
 } DriveInfo;
 
 #define MAX_IDE_DEVS	2


[PATCH 1/2] Add serial number support for virtio_blk

2009-04-29 Thread john cooper


--
john.coo...@third-harmonic.com
 hw/virtio-blk.c |   15 ++-
 hw/virtio-blk.h |3 +++
 sysemu.h|4 +++-
 3 files changed, 20 insertions(+), 2 deletions(-)
=
--- a/qemu/hw/virtio-blk.h
+++ b/qemu/hw/virtio-blk.h
@@ -28,6 +28,7 @@
 #define VIRTIO_BLK_F_SIZE_MAX   1   /* Indicates maximum segment size */
 #define VIRTIO_BLK_F_SEG_MAX2   /* Indicates maximum # of segments */
 #define VIRTIO_BLK_F_GEOMETRY   4   /* Indicates support of legacy geometry */
+#define VIRTIO_BLK_F_SN		7   /* serial number supported */
 
 struct virtio_blk_config
 {
@@ -37,6 +38,8 @@ struct virtio_blk_config
 uint16_t cylinders;
 uint8_t heads;
 uint8_t sectors;
+uint32_t _blk_size;/* structure pad, currently unused */
+uint8_t serial[BLOCK_SERIAL_STRLEN];
 } __attribute__((packed));
 
 /* These two define direction. */
=
--- a/qemu/hw/virtio-blk.c
+++ b/qemu/hw/virtio-blk.c
@@ -22,6 +22,7 @@ typedef struct VirtIOBlock
 BlockDriverState *bs;
 VirtQueue *vq;
 void *rq;
+char serial_str[BLOCK_SERIAL_STRLEN + 1];
 } VirtIOBlock;
 
 static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev)
@@ -238,6 +239,8 @@ static void virtio_blk_reset(VirtIODevic
 qemu_aio_flush();
 }
 
+/* coalesce internal state, copy to pci i/o region 0
+ */
 static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
 {
 VirtIOBlock *s = to_virtio_blk(vdev);
@@ -252,12 +255,17 @@ static void virtio_blk_update_config(Vir
 stw_raw(blkcfg.cylinders, cylinders);
 blkcfg.heads = heads;
 blkcfg.sectors = secs;
+memcpy(blkcfg.serial, s-serial_str, sizeof (blkcfg.serial));
 memcpy(config, blkcfg, sizeof(blkcfg));
 }
 
 static uint32_t virtio_blk_get_features(VirtIODevice *vdev)
 {
-return (1  VIRTIO_BLK_F_SEG_MAX | 1  VIRTIO_BLK_F_GEOMETRY);
+VirtIOBlock *s = to_virtio_blk(vdev);
+char ser_set = strcmp(s-serial_str, 0);
+
+return (1  VIRTIO_BLK_F_SEG_MAX | 1  VIRTIO_BLK_F_GEOMETRY |
+(ser_set ? 1  VIRTIO_BLK_F_SN : 0));
 }
 
 static void virtio_blk_save(QEMUFile *f, void *opaque)
@@ -298,6 +306,7 @@ void *virtio_blk_init(PCIBus *bus, Block
 VirtIOBlock *s;
 int cylinders, heads, secs;
 static int virtio_blk_id;
+char *ps = drive_get_serial(bs);
 
 s = (VirtIOBlock *)virtio_init_pci(bus, virtio-blk,
PCI_VENDOR_ID_REDHAT_QUMRANET,
@@ -314,6 +323,10 @@ void *virtio_blk_init(PCIBus *bus, Block
 s-vdev.reset = virtio_blk_reset;
 s-bs = bs;
 s-rq = NULL;
+if (strlen(ps))
+strncpy(s-serial_str, ps, sizeof (s-serial_str));
+else
+snprintf(s-serial_str, sizeof (s-serial_str), 0);
 bs-devfn = s-vdev.pci_dev.devfn;
 bdrv_guess_geometry(s-bs, cylinders, heads, secs);
 bdrv_set_geometry_hint(s-bs, cylinders, heads, secs);
=
--- a/qemu/sysemu.h
+++ b/qemu/sysemu.h
@@ -133,13 +133,15 @@ typedef enum {
 BLOCK_ERR_STOP_ANY
 } BlockInterfaceErrorAction;
 
+#define BLOCK_SERIAL_STRLEN 20
+
 typedef struct DriveInfo {
 BlockDriverState *bdrv;
 BlockInterfaceType type;
 int bus;
 int unit;
 BlockInterfaceErrorAction onerror;
-char serial[21];
+char serial[BLOCK_SERIAL_STRLEN + 1];
 int used;
 int drive_opt_idx;
 } DriveInfo;


Re: [PATCH 1/2] Add serial number support for virtio_blk

2009-04-29 Thread Anthony Liguori

Hi John,

Please send this to qemu-devel.

Regards,

Anthony Liguori
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] Add serial number support for virtio_blk

2009-04-29 Thread john cooper


--
john.coo...@third-harmonic.com
 hw/virtio-blk.c |   15 ++-
 hw/virtio-blk.h |3 +++
 sysemu.h|4 +++-
 3 files changed, 20 insertions(+), 2 deletions(-)
=
--- a/qemu/hw/virtio-blk.h
+++ b/qemu/hw/virtio-blk.h
@@ -28,6 +28,7 @@
 #define VIRTIO_BLK_F_SIZE_MAX   1   /* Indicates maximum segment size */
 #define VIRTIO_BLK_F_SEG_MAX2   /* Indicates maximum # of segments */
 #define VIRTIO_BLK_F_GEOMETRY   4   /* Indicates support of legacy geometry */
+#define VIRTIO_BLK_F_SN		7   /* serial number supported */
 
 struct virtio_blk_config
 {
@@ -37,6 +38,8 @@ struct virtio_blk_config
 uint16_t cylinders;
 uint8_t heads;
 uint8_t sectors;
+uint32_t _blk_size;/* structure pad, currently unused */
+uint8_t serial[BLOCK_SERIAL_STRLEN];
 } __attribute__((packed));
 
 /* These two define direction. */
=
--- a/qemu/hw/virtio-blk.c
+++ b/qemu/hw/virtio-blk.c
@@ -22,6 +22,7 @@ typedef struct VirtIOBlock
 BlockDriverState *bs;
 VirtQueue *vq;
 void *rq;
+char serial_str[BLOCK_SERIAL_STRLEN + 1];
 } VirtIOBlock;
 
 static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev)
@@ -238,6 +239,8 @@ static void virtio_blk_reset(VirtIODevic
 qemu_aio_flush();
 }
 
+/* coalesce internal state, copy to pci i/o region 0
+ */
 static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
 {
 VirtIOBlock *s = to_virtio_blk(vdev);
@@ -252,12 +255,17 @@ static void virtio_blk_update_config(Vir
 stw_raw(blkcfg.cylinders, cylinders);
 blkcfg.heads = heads;
 blkcfg.sectors = secs;
+memcpy(blkcfg.serial, s-serial_str, sizeof (blkcfg.serial));
 memcpy(config, blkcfg, sizeof(blkcfg));
 }
 
 static uint32_t virtio_blk_get_features(VirtIODevice *vdev)
 {
-return (1  VIRTIO_BLK_F_SEG_MAX | 1  VIRTIO_BLK_F_GEOMETRY);
+VirtIOBlock *s = to_virtio_blk(vdev);
+char ser_set = strcmp(s-serial_str, 0);
+
+return (1  VIRTIO_BLK_F_SEG_MAX | 1  VIRTIO_BLK_F_GEOMETRY |
+(ser_set ? 1  VIRTIO_BLK_F_SN : 0));
 }
 
 static void virtio_blk_save(QEMUFile *f, void *opaque)
@@ -298,6 +306,7 @@ void *virtio_blk_init(PCIBus *bus, Block
 VirtIOBlock *s;
 int cylinders, heads, secs;
 static int virtio_blk_id;
+char *ps = drive_get_serial(bs);
 
 s = (VirtIOBlock *)virtio_init_pci(bus, virtio-blk,
PCI_VENDOR_ID_REDHAT_QUMRANET,
@@ -314,6 +323,10 @@ void *virtio_blk_init(PCIBus *bus, Block
 s-vdev.reset = virtio_blk_reset;
 s-bs = bs;
 s-rq = NULL;
+if (strlen(ps))
+strncpy(s-serial_str, ps, sizeof (s-serial_str));
+else
+snprintf(s-serial_str, sizeof (s-serial_str), 0);
 bs-devfn = s-vdev.pci_dev.devfn;
 bdrv_guess_geometry(s-bs, cylinders, heads, secs);
 bdrv_set_geometry_hint(s-bs, cylinders, heads, secs);
=
--- a/qemu/sysemu.h
+++ b/qemu/sysemu.h
@@ -133,13 +133,15 @@ typedef enum {
 BLOCK_ERR_STOP_ANY
 } BlockInterfaceErrorAction;
 
+#define BLOCK_SERIAL_STRLEN 20
+
 typedef struct DriveInfo {
 BlockDriverState *bdrv;
 BlockInterfaceType type;
 int bus;
 int unit;
 BlockInterfaceErrorAction onerror;
-char serial[21];
+char serial[BLOCK_SERIAL_STRLEN + 1];
 int used;
 int drive_opt_idx;
 } DriveInfo;