Lines Matching +full:- +full:- +full:enable +full:- +full:trace +full:- +full:backend

5  * See the COPYING file in the top-level directory.
10 #include "qemu/main-loop.h"
14 #include "qapi/qapi-commands-block-core.h"
15 #include "qapi/qapi-commands-qom.h"
16 #include "qapi/qapi-visit-block-core.h"
17 #include "qapi/qobject-input-visitor.h"
23 #include "hw/qdev-properties.h"
24 #include "hw/xen/xen-block.h"
25 #include "hw/xen/xen-backend.h"
27 #include "system/block-backend.h"
29 #include "dataplane/xen-block.h"
31 #include "trace.h"
35 #define XVDBGQCV_MAJOR ((1 << 21) - 1)
58 return -1; in vdev_to_diskno()
66 * blockdev->props.vdev. Our definition of "free" is that there must
82 XenBlockVdev *vdev = &blockdev->props.vdev; in xen_block_find_free_vdev()
90 blockdev->xendev.frontend_id); in xen_block_find_free_vdev()
92 existing_frontends = qemu_xen_xs_directory(xenbus->xsh, XBT_NULL, fe_path, in xen_block_find_free_vdev()
141 vdev->type = XEN_BLOCK_VDEV_TYPE_XVD; in xen_block_find_free_vdev()
142 vdev->partition = 0; in xen_block_find_free_vdev()
143 vdev->disk = disk; in xen_block_find_free_vdev()
145 vdev->number = (XVDA_MAJOR << 8) | (disk << 4); in xen_block_find_free_vdev()
147 vdev->number = (XVDQ_MAJOR << 8) | (disk << 8); in xen_block_find_free_vdev()
155 XenBlockVdev *vdev = &blockdev->props.vdev; in xen_block_get_name()
157 if (vdev->type == XEN_BLOCK_VDEV_TYPE_INVALID && in xen_block_get_name()
161 return g_strdup_printf("%lu", vdev->number); in xen_block_get_name()
168 XenBlockVdev *vdev = &blockdev->props.vdev; in xen_block_disconnect()
170 trace_xen_block_disconnect(type, vdev->disk, vdev->partition); in xen_block_disconnect()
172 xen_block_dataplane_stop(blockdev->dataplane); in xen_block_disconnect()
179 XenBlockVdev *vdev = &blockdev->props.vdev; in xen_block_connect()
180 BlockConf *conf = &blockdev->props.conf; in xen_block_connect()
185 trace_xen_block_connect(type, vdev->disk, vdev->partition); in xen_block_connect()
187 if (xen_device_frontend_scanf(xendev, "feature-large-sector-size", "%u", in xen_block_connect()
193 conf->logical_block_size != XEN_BLKIF_SECTOR_SIZE) { in xen_block_connect()
199 if (xen_device_frontend_scanf(xendev, "ring-page-order", "%u", in xen_block_connect()
204 if (xen_device_frontend_scanf(xendev, "ring-ref", "%u", in xen_block_connect()
206 error_setg(errp, "failed to read ring-ref"); in xen_block_connect()
211 order <= blockdev->props.max_ring_page_order) { in xen_block_connect()
218 const char *key = g_strdup_printf("ring-ref%u", i); in xen_block_connect()
231 error_setg(errp, "invalid ring-page-order (%d)", order); in xen_block_connect()
235 if (xen_device_frontend_scanf(xendev, "event-channel", "%u", in xen_block_connect()
237 error_setg(errp, "failed to read event-channel"); in xen_block_connect()
244 /* x86 defaults to the 32-bit protocol even for 64-bit guests. */ in xen_block_connect()
245 if (object_dynamic_cast(OBJECT(qdev_get_machine()), "x86-machine")) { in xen_block_connect()
262 xen_block_dataplane_start(blockdev->dataplane, ring_ref, nr_ring_ref, in xen_block_connect()
274 XenBlockVdev *vdev = &blockdev->props.vdev; in xen_block_unrealize()
276 if (vdev->type == XEN_BLOCK_VDEV_TYPE_INVALID) { in xen_block_unrealize()
280 trace_xen_block_unrealize(type, vdev->disk, vdev->partition); in xen_block_unrealize()
285 xen_block_dataplane_destroy(blockdev->dataplane); in xen_block_unrealize()
286 blockdev->dataplane = NULL; in xen_block_unrealize()
288 if (blockdev_class->unrealize) { in xen_block_unrealize()
289 blockdev_class->unrealize(blockdev); in xen_block_unrealize()
296 XenBlockVdev *vdev = &blockdev->props.vdev; in xen_block_set_size()
297 BlockConf *conf = &blockdev->props.conf; in xen_block_set_size()
298 int64_t sectors = blk_getlength(conf->blk) / conf->logical_block_size; in xen_block_set_size()
301 trace_xen_block_size(type, vdev->disk, vdev->partition, sectors); in xen_block_set_size()
315 * Mimic the behaviour of Linux xen-blkback and re-write the state in xen_block_resize_cb()
326 xen_block_dataplane_detach(blockdev->dataplane); in xen_block_drained_begin()
334 xen_block_dataplane_attach(blockdev->dataplane); in xen_block_drained_end()
350 XenBlockVdev *vdev = &blockdev->props.vdev; in xen_block_realize()
351 BlockConf *conf = &blockdev->props.conf; in xen_block_realize()
352 BlockBackend *blk = conf->blk; in xen_block_realize()
354 if (vdev->type == XEN_BLOCK_VDEV_TYPE_INVALID) { in xen_block_realize()
359 trace_xen_block_realize(type, vdev->disk, vdev->partition); in xen_block_realize()
361 if (blockdev_class->realize) { in xen_block_realize()
362 blockdev_class->realize(blockdev, errp); in xen_block_realize()
378 if (!blkconf_apply_backend_options(conf, blockdev->info & VDISK_READONLY, in xen_block_realize()
383 if (!(blockdev->info & VDISK_CDROM) && in xen_block_realize()
392 if (conf->discard_granularity == -1) { in xen_block_realize()
393 conf->discard_granularity = conf->physical_block_size; in xen_block_realize()
397 xen_device_backend_printf(xendev, "feature-discard", "%u", 1); in xen_block_realize()
398 xen_device_backend_printf(xendev, "discard-granularity", "%u", in xen_block_realize()
399 conf->discard_granularity); in xen_block_realize()
400 xen_device_backend_printf(xendev, "discard-alignment", "%u", 0); in xen_block_realize()
403 xen_device_backend_printf(xendev, "feature-flush-cache", "%u", 1); in xen_block_realize()
406 xen_device_backend_printf(xendev, "max-ring-page-order", "%u", in xen_block_realize()
407 blockdev->props.max_ring_page_order); in xen_block_realize()
410 xen_device_backend_printf(xendev, "info", "%u", blockdev->info); in xen_block_realize()
412 (blockdev->info & VDISK_READONLY) ? "r" : "w"); in xen_block_realize()
414 xen_device_frontend_printf(xendev, "virtual-device", "%lu", in xen_block_realize()
415 vdev->number); in xen_block_realize()
416 xen_device_frontend_printf(xendev, "device-type", "%s", in xen_block_realize()
417 blockdev->device_type); in xen_block_realize()
419 xen_device_backend_printf(xendev, "sector-size", "%u", in xen_block_realize()
420 conf->logical_block_size); in xen_block_realize()
424 blockdev->dataplane = in xen_block_realize()
425 xen_block_dataplane_create(xendev, blk, conf->logical_block_size, in xen_block_realize()
426 blockdev->props.iothread); in xen_block_realize()
480 disk_to_vbd_name((disk / 26) - 1) : g_strdup(""); in disk_to_vbd_name()
495 switch (vdev->type) { in xen_block_get_vdev()
497 str = g_strdup_printf("d%lup%lu", vdev->disk, vdev->partition); in xen_block_get_vdev()
503 char *vbd_name = disk_to_vbd_name(vdev->disk); in xen_block_get_vdev()
506 (vdev->type == XEN_BLOCK_VDEV_TYPE_XVD) ? in xen_block_get_vdev()
508 (vdev->type == XEN_BLOCK_VDEV_TYPE_HD) ? in xen_block_get_vdev()
511 vbd_name, vdev->partition); in xen_block_get_vdev()
535 n += *name++ - 'a' + 1; in vbd_name_to_disk()
540 return -1; in vbd_name_to_disk()
543 *disk = n - 1; in vbd_name_to_disk()
567 vdev->type = XEN_BLOCK_VDEV_TYPE_DP; in xen_block_set_vdev()
569 vdev->type = XEN_BLOCK_VDEV_TYPE_XVD; in xen_block_set_vdev()
571 vdev->type = XEN_BLOCK_VDEV_TYPE_HD; in xen_block_set_vdev()
573 vdev->type = XEN_BLOCK_VDEV_TYPE_SD; in xen_block_set_vdev()
578 if (vdev->type == XEN_BLOCK_VDEV_TYPE_DP) { in xen_block_set_vdev()
579 if (qemu_strtoul(p, &end, 10, &vdev->disk)) { in xen_block_set_vdev()
589 if (vbd_name_to_disk(p, &end, &vdev->disk)) { in xen_block_set_vdev()
597 if (qemu_strtoul(p, &end, 10, &vdev->partition)) { in xen_block_set_vdev()
605 vdev->partition = 0; in xen_block_set_vdev()
608 switch (vdev->type) { in xen_block_set_vdev()
611 if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) { in xen_block_set_vdev()
612 vdev->number = (XVDA_MAJOR << 8) | (vdev->disk << 4) | in xen_block_set_vdev()
613 vdev->partition; in xen_block_set_vdev()
614 } else if (vdev->disk < (1 << 20) && vdev->partition < (1 << 8)) { in xen_block_set_vdev()
615 vdev->number = (XVDQ_MAJOR << 8) | (vdev->disk << 8) | in xen_block_set_vdev()
616 vdev->partition; in xen_block_set_vdev()
623 if ((vdev->disk == 0 || vdev->disk == 1) && in xen_block_set_vdev()
624 vdev->partition < (1 << 6)) { in xen_block_set_vdev()
625 vdev->number = (HDA_MAJOR << 8) | (vdev->disk << 6) | in xen_block_set_vdev()
626 vdev->partition; in xen_block_set_vdev()
627 } else if ((vdev->disk == 2 || vdev->disk == 3) && in xen_block_set_vdev()
628 vdev->partition < (1 << 6)) { in xen_block_set_vdev()
629 vdev->number = (HDC_MAJOR << 8) | ((vdev->disk - 2) << 6) | in xen_block_set_vdev()
630 vdev->partition; in xen_block_set_vdev()
637 if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) { in xen_block_set_vdev()
638 vdev->number = (SDA_MAJOR << 8) | (vdev->disk << 4) | in xen_block_set_vdev()
639 vdev->partition; in xen_block_set_vdev()
655 vdev->type = XEN_BLOCK_VDEV_TYPE_INVALID; in xen_block_set_vdev()
663 * https://xenbits.xen.org/docs/unstable/man/xen-vbd-interface.7.html
676 DEFINE_PROP_UINT32("max-ring-page-order", XenBlockDevice,
687 xendev_class->backend = "qdisk"; in xen_block_class_init()
688 xendev_class->device = "vbd"; in xen_block_class_init()
689 xendev_class->get_name = xen_block_get_name; in xen_block_class_init()
690 xendev_class->realize = xen_block_realize; in xen_block_class_init()
691 xendev_class->frontend_changed = xen_block_frontend_changed; in xen_block_class_init()
692 xendev_class->unrealize = xen_block_unrealize; in xen_block_class_init()
713 BlockConf *conf = &blockdev->props.conf; in xen_disk_realize()
717 blockdev->device_type = "disk"; in xen_disk_realize()
719 if (!conf->blk) { in xen_disk_realize()
724 blockdev->info = blk_supports_write_perm(conf->blk) ? 0 : VDISK_READONLY; in xen_disk_realize()
732 blockdev_class->realize = xen_disk_realize; in xen_disk_class_init()
733 blockdev_class->unrealize = xen_disk_unrealize; in xen_disk_class_init()
735 dev_class->desc = "Xen Disk Device"; in xen_disk_class_init()
752 BlockConf *conf = &blockdev->props.conf; in xen_cdrom_realize()
756 blockdev->device_type = "cdrom"; in xen_cdrom_realize()
758 if (!conf->blk) { in xen_cdrom_realize()
762 conf->blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL); in xen_cdrom_realize()
764 rc = blk_attach_dev(conf->blk, DEVICE(blockdev)); in xen_cdrom_realize()
766 error_setg_errno(errp, -rc, "failed to create drive"); in xen_cdrom_realize()
771 blockdev->info = VDISK_READONLY | VDISK_CDROM; in xen_cdrom_realize()
779 blockdev_class->realize = xen_cdrom_realize; in xen_cdrom_class_init()
780 blockdev_class->unrealize = xen_cdrom_unrealize; in xen_cdrom_class_init()
782 dev_class->desc = "Xen CD-ROM Device"; in xen_cdrom_class_init()
822 node_name = g_strdup_printf("%s-%s", id, driver); in xen_block_blockdev_add()
823 qdict_put_str(qdict, "node-name", node_name); in xen_block_blockdev_add()
856 char *node_name = drive->node_name; in xen_block_drive_destroy()
864 drive->node_name = NULL; in xen_block_drive_destroy()
866 g_free(drive->id); in xen_block_drive_destroy()
877 const char *direct_io_safe = qdict_get_try_str(opts, "direct-io-safe"); in xen_block_drive_create()
878 const char *discard_enable = qdict_get_try_str(opts, "discard-enable"); in xen_block_drive_create()
914 drive->id = g_strdup(id); in xen_block_drive_create()
934 qdict_put_bool(file_layer, "read-only", true); in xen_block_drive_create()
969 g_assert(!drive->node_name); in xen_block_drive_create()
970 drive->node_name = xen_block_blockdev_add(drive->id, driver_layer, in xen_block_drive_create()
988 return drive->node_name ? drive->node_name : ""; in xen_block_drive_get_node_name()
994 qmp_object_del(iothread->id, errp); in xen_block_iothread_destroy()
996 g_free(iothread->id); in xen_block_iothread_destroy()
1007 iothread->id = g_strdup(id); in xen_block_iothread_create()
1018 g_free(iothread->id); in xen_block_iothread_create()
1026 static void xen_block_device_create(XenBackendInstance *backend, in xen_block_device_create() argument
1030 XenBus *xenbus = xen_backend_get_bus(backend); in xen_block_device_create()
1031 const char *name = xen_backend_get_name(backend); in xen_block_device_create()
1053 device_type = qdict_get_try_str(opts, "device-type"); in xen_block_device_create()
1055 error_setg(errp, "no device-type parameter"); in xen_block_device_create()
1064 error_setg(errp, "invalid device-type parameter '%s'", device_type); in xen_block_device_create()
1096 if (!object_property_set_str(OBJECT(xendev), "iothread", iothread->id, in xen_block_device_create()
1102 blockdev->iothread = iothread; in xen_block_device_create()
1103 blockdev->drive = drive; in xen_block_device_create()
1110 xen_backend_set_device(backend, xendev); in xen_block_device_create()
1127 static void xen_block_device_destroy(XenBackendInstance *backend, in xen_block_device_destroy() argument
1131 XenDevice *xendev = xen_backend_get_device(backend); in xen_block_device_destroy()
1133 XenBlockVdev *vdev = &blockdev->props.vdev; in xen_block_device_destroy()
1134 XenBlockDrive *drive = blockdev->drive; in xen_block_device_destroy()
1135 XenBlockIOThread *iothread = blockdev->iothread; in xen_block_device_destroy()
1137 trace_xen_block_device_destroy(vdev->number); in xen_block_device_destroy()