diff --git a/hw/xen_backend.c b/hw/xen_backend.c index 24381b55e5..02693d7565 100644 --- a/hw/xen_backend.c +++ b/hw/xen_backend.c @@ -85,12 +85,20 @@ char *xenstore_read_str(const char *base, const char *node) int xenstore_write_int(const char *base, const char *node, int ival) { - char val[32]; + char val[12]; snprintf(val, sizeof(val), "%d", ival); return xenstore_write_str(base, node, val); } +int xenstore_write_int64(const char *base, const char *node, int64_t ival) +{ + char val[21]; + + snprintf(val, sizeof(val), "%"PRId64, ival); + return xenstore_write_str(base, node, val); +} + int xenstore_read_int(const char *base, const char *node, int *ival) { char *val; @@ -114,6 +122,11 @@ int xenstore_write_be_int(struct XenDevice *xendev, const char *node, int ival) return xenstore_write_int(xendev->be, node, ival); } +int xenstore_write_be_int64(struct XenDevice *xendev, const char *node, int64_t ival) +{ + return xenstore_write_int64(xendev->be, node, ival); +} + char *xenstore_read_be_str(struct XenDevice *xendev, const char *node) { return xenstore_read_str(xendev->be, node); diff --git a/hw/xen_backend.h b/hw/xen_backend.h index 6d5c699c51..d04b985d10 100644 --- a/hw/xen_backend.h +++ b/hw/xen_backend.h @@ -63,11 +63,13 @@ extern const char *xen_protocol; /* xenstore helper functions */ int xenstore_write_str(const char *base, const char *node, const char *val); int xenstore_write_int(const char *base, const char *node, int ival); +int xenstore_write_int64(const char *base, const char *node, int64_t ival); char *xenstore_read_str(const char *base, const char *node); int xenstore_read_int(const char *base, const char *node, int *ival); int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const char *val); int xenstore_write_be_int(struct XenDevice *xendev, const char *node, int ival); +int xenstore_write_be_int64(struct XenDevice *xendev, const char *node, int64_t ival); char *xenstore_read_be_str(struct XenDevice *xendev, const char *node); int xenstore_read_be_int(struct XenDevice *xendev, const char *node, int *ival); char *xenstore_read_fe_str(struct XenDevice *xendev, const char *node); diff --git a/hw/xen_disk.c b/hw/xen_disk.c index 83329e2e69..47a51cf014 100644 --- a/hw/xen_disk.c +++ b/hw/xen_disk.c @@ -700,7 +700,7 @@ static void blk_alloc(struct XenDevice *xendev) static int blk_init(struct XenDevice *xendev) { struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev); - int index, qflags, info = 0; + int info = 0; /* read xenstore entries */ if (blkdev->params == NULL) { @@ -743,10 +743,7 @@ static int blk_init(struct XenDevice *xendev) } /* read-only ? */ - qflags = BDRV_O_NOCACHE | BDRV_O_CACHE_WB | BDRV_O_NATIVE_AIO; - if (strcmp(blkdev->mode, "w") == 0) { - qflags |= BDRV_O_RDWR; - } else { + if (strcmp(blkdev->mode, "w")) { info |= VDISK_READONLY; } @@ -755,50 +752,14 @@ static int blk_init(struct XenDevice *xendev) info |= VDISK_CDROM; } - /* init qemu block driver */ - index = (blkdev->xendev.dev - 202 * 256) / 16; - blkdev->dinfo = drive_get(IF_XEN, 0, index); - if (!blkdev->dinfo) { - /* setup via xenbus -> create new block driver instance */ - xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n"); - blkdev->bs = bdrv_new(blkdev->dev); - if (blkdev->bs) { - if (bdrv_open(blkdev->bs, blkdev->filename, NULL, qflags, - bdrv_find_whitelisted_format(blkdev->fileproto)) != 0) { - bdrv_delete(blkdev->bs); - blkdev->bs = NULL; - } - } - if (!blkdev->bs) { - goto out_error; - } - } else { - /* setup via qemu cmdline -> already setup for us */ - xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n"); - blkdev->bs = blkdev->dinfo->bdrv; - } - bdrv_attach_dev_nofail(blkdev->bs, blkdev); blkdev->file_blk = BLOCK_SIZE; - blkdev->file_size = bdrv_getlength(blkdev->bs); - if (blkdev->file_size < 0) { - xen_be_printf(&blkdev->xendev, 1, "bdrv_getlength: %d (%s) | drv %s\n", - (int)blkdev->file_size, strerror(-blkdev->file_size), - bdrv_get_format_name(blkdev->bs) ?: "-"); - blkdev->file_size = 0; - } - xen_be_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\"," - " size %" PRId64 " (%" PRId64 " MB)\n", - blkdev->type, blkdev->fileproto, blkdev->filename, - blkdev->file_size, blkdev->file_size >> 20); - - /* fill info */ + /* fill info + * blk_connect supplies sector-size and sectors + */ xenstore_write_be_int(&blkdev->xendev, "feature-flush-cache", 1); xenstore_write_be_int(&blkdev->xendev, "feature-persistent", 1); - xenstore_write_be_int(&blkdev->xendev, "info", info); - xenstore_write_be_int(&blkdev->xendev, "sector-size", blkdev->file_blk); - xenstore_write_be_int(&blkdev->xendev, "sectors", - blkdev->file_size / blkdev->file_blk); + xenstore_write_be_int(&blkdev->xendev, "info", info); return 0; out_error: @@ -818,7 +779,54 @@ out_error: static int blk_connect(struct XenDevice *xendev) { struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev); - int pers; + int pers, index, qflags; + + /* read-only ? */ + qflags = BDRV_O_CACHE_WB | BDRV_O_NATIVE_AIO; + if (strcmp(blkdev->mode, "w") == 0) { + qflags |= BDRV_O_RDWR; + } + + /* init qemu block driver */ + index = (blkdev->xendev.dev - 202 * 256) / 16; + blkdev->dinfo = drive_get(IF_XEN, 0, index); + if (!blkdev->dinfo) { + /* setup via xenbus -> create new block driver instance */ + xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n"); + blkdev->bs = bdrv_new(blkdev->dev); + if (blkdev->bs) { + if (bdrv_open(blkdev->bs, blkdev->filename, NULL, qflags, + bdrv_find_whitelisted_format(blkdev->fileproto)) != 0) { + bdrv_delete(blkdev->bs); + blkdev->bs = NULL; + } + } + if (!blkdev->bs) { + return -1; + } + } else { + /* setup via qemu cmdline -> already setup for us */ + xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n"); + blkdev->bs = blkdev->dinfo->bdrv; + } + bdrv_attach_dev_nofail(blkdev->bs, blkdev); + blkdev->file_size = bdrv_getlength(blkdev->bs); + if (blkdev->file_size < 0) { + xen_be_printf(&blkdev->xendev, 1, "bdrv_getlength: %d (%s) | drv %s\n", + (int)blkdev->file_size, strerror(-blkdev->file_size), + bdrv_get_format_name(blkdev->bs) ?: "-"); + blkdev->file_size = 0; + } + + xen_be_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\"," + " size %" PRId64 " (%" PRId64 " MB)\n", + blkdev->type, blkdev->fileproto, blkdev->filename, + blkdev->file_size, blkdev->file_size >> 20); + + /* Fill in number of sector size and number of sectors */ + xenstore_write_be_int(&blkdev->xendev, "sector-size", blkdev->file_blk); + xenstore_write_be_int64(&blkdev->xendev, "sectors", + blkdev->file_size / blkdev->file_blk); if (xenstore_read_fe_int(&blkdev->xendev, "ring-ref", &blkdev->ring_ref) == -1) { return -1;