Revision a8686a9b

b/hw/s390-virtio-bus.c
128 128
{
129 129
    VirtIODevice *vdev;
130 130

  
131
    vdev = virtio_blk_init((DeviceState *)dev, &dev->block);
131
    vdev = virtio_blk_init((DeviceState *)dev, &dev->block,
132
                           &dev->block_serial);
132 133
    if (!vdev) {
133 134
        return -1;
134 135
    }
......
355 356
    .qdev.size = sizeof(VirtIOS390Device),
356 357
    .qdev.props = (Property[]) {
357 358
        DEFINE_BLOCK_PROPERTIES(VirtIOS390Device, block),
359
        DEFINE_PROP_STRING("serial", VirtIOS390Device, block_serial),
358 360
        DEFINE_PROP_END_OF_LIST(),
359 361
    },
360 362
};
b/hw/s390-virtio-bus.h
42 42
    uint8_t feat_len;
43 43
    VirtIODevice *vdev;
44 44
    BlockConf block;
45
    char *block_serial;
45 46
    NICConf nic;
46 47
    uint32_t host_features;
47 48
    virtio_serial_conf serial;
b/hw/virtio-blk.c
28 28
    void *rq;
29 29
    QEMUBH *bh;
30 30
    BlockConf *conf;
31
    char *serial;
31 32
    unsigned short sector_mask;
32
    char sn[BLOCK_SERIAL_STRLEN];
33 33
    DeviceState *qdev;
34 34
} VirtIOBlock;
35 35

  
......
362 362
    } else if (type & VIRTIO_BLK_T_GET_ID) {
363 363
        VirtIOBlock *s = req->dev;
364 364

  
365
        memcpy(req->elem.in_sg[0].iov_base, s->sn,
366
               MIN(req->elem.in_sg[0].iov_len, sizeof(s->sn)));
365
        /*
366
         * NB: per existing s/n string convention the string is
367
         * terminated by '\0' only when shorter than buffer.
368
         */
369
        strncpy(req->elem.in_sg[0].iov_base,
370
                s->serial ? s->serial : "",
371
                MIN(req->elem.in_sg[0].iov_len, VIRTIO_BLK_ID_BYTES));
367 372
        virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
368 373
    } else if (type & VIRTIO_BLK_T_OUT) {
369 374
        qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1],
......
531 536
    }
532 537
}
533 538

  
534
VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
539
VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf,
540
                              char **serial)
535 541
{
536 542
    VirtIOBlock *s;
537 543
    int cylinders, heads, secs;
......
547 553
        return NULL;
548 554
    }
549 555

  
556
    if (!*serial) {
557
        /* try to fall back to value set with legacy -drive serial=... */
558
        dinfo = drive_get_by_blockdev(conf->bs);
559
        if (*dinfo->serial) {
560
            *serial = strdup(dinfo->serial);
561
        }
562
    }
563

  
550 564
    s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
551 565
                                          sizeof(struct virtio_blk_config),
552 566
                                          sizeof(VirtIOBlock));
......
556 570
    s->vdev.reset = virtio_blk_reset;
557 571
    s->bs = conf->bs;
558 572
    s->conf = conf;
573
    s->serial = *serial;
559 574
    s->rq = NULL;
560 575
    s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;
561 576
    bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
562 577

  
563
    /* NB: per existing s/n string convention the string is terminated
564
     * by '\0' only when less than sizeof (s->sn)
565
     */
566
    dinfo = drive_get_by_blockdev(s->bs);
567
    strncpy(s->sn, dinfo->serial, sizeof (s->sn));
568

  
569 578
    s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
570 579

  
571 580
    qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
b/hw/virtio-blk.h
34 34
#define VIRTIO_BLK_F_WCACHE     9       /* write cache enabled */
35 35
#define VIRTIO_BLK_F_TOPOLOGY   10      /* Topology information is available */
36 36

  
37
#define VIRTIO_BLK_ID_BYTES     20      /* ID string length */
38

  
37 39
struct virtio_blk_config
38 40
{
39 41
    uint64_t capacity;
b/hw/virtio-pci.c
700 700
        proxy->class_code != PCI_CLASS_STORAGE_OTHER)
701 701
        proxy->class_code = PCI_CLASS_STORAGE_SCSI;
702 702

  
703
    vdev = virtio_blk_init(&pci_dev->qdev, &proxy->block);
703
    vdev = virtio_blk_init(&pci_dev->qdev, &proxy->block,
704
                           &proxy->block_serial);
704 705
    if (!vdev) {
705 706
        return -1;
706 707
    }
......
805 806
        .qdev.props = (Property[]) {
806 807
            DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
807 808
            DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block),
809
            DEFINE_PROP_STRING("serial", VirtIOPCIProxy, block_serial),
808 810
            DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
809 811
                            VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
810 812
            DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
b/hw/virtio-pci.h
26 26
    uint32_t class_code;
27 27
    uint32_t nvectors;
28 28
    BlockConf block;
29
    char *block_serial;
29 30
    NICConf nic;
30 31
    uint32_t host_features;
31 32
#ifdef CONFIG_LINUX
b/hw/virtio.h
197 197
                        void *opaque);
198 198

  
199 199
/* Base devices.  */
200
VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf);
200
VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf,
201
                              char **serial);
201 202
struct virtio_net_conf;
202 203
VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf,
203 204
                              struct virtio_net_conf *net);

Also available in: Unified diff