Revision a8686a9b hw/virtio-blk.c
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); |
Also available in: Unified diff