/*
 * Copyright (c) 2018  Citrix Systems Inc.
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "qemu/cutils.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "qemu/option.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-block-core.h"
#include "qapi/qapi-commands-qom.h"
#include "qapi/qapi-visit-block-core.h"
#include "qapi/qobject-input-visitor.h"
#include "qapi/visitor.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qstring.h"
#include "qom/object_interfaces.h"
#include "hw/block/xen_blkif.h"
#include "hw/qdev-properties.h"
#include "hw/xen/xen-block.h"
#include "hw/xen/xen-backend.h"
#include "sysemu/blockdev.h"
#include "sysemu/block-backend.h"
#include "sysemu/iothread.h"
#include "dataplane/xen-block.h"
#include "hw/xen/interface/io/xs_wire.h"
#include "trace.h"

#define XVDA_MAJOR 202
#define XVDQ_MAJOR (1 << 20)
#define XVDBGQCV_MAJOR ((1 << 21) - 1)
#define HDA_MAJOR 3
#define HDC_MAJOR 22
#define SDA_MAJOR 8


static int vdev_to_diskno(unsigned int vdev_nr)
{
    switch (vdev_nr >> 8) {
    case XVDA_MAJOR:
    case SDA_MAJOR:
        return (vdev_nr >> 4) & 0x15;

    case HDA_MAJOR:
        return (vdev_nr >> 6) & 1;

    case HDC_MAJOR:
        return ((vdev_nr >> 6) & 1) + 2;

    case XVDQ_MAJOR ... XVDBGQCV_MAJOR:
        return (vdev_nr >> 8) & 0xfffff;

    default:
        return -1;
    }
}

#define MAX_AUTO_VDEV 4096

/*
 * Find a free device name in the xvda → xvdfan range and set it in
 * blockdev->props.vdev. Our definition of "free" is that there must
 * be no other disk or partition with the same disk number.
 *
 * You are technically permitted to have all of hda, hda1, sda, sda1,
 * xvda and xvda1 as *separate* PV block devices with separate backing
 * stores. That doesn't make it a good idea. This code will skip xvda
 * if *any* of those "conflicting" devices already exists.
 *
 * The limit of xvdfan (disk 4095) is fairly arbitrary just to avoid a
 * stupidly sized bitmap, but Linux as of v6.6 doesn't support anything
 * higher than that anyway.
 */
static bool xen_block_find_free_vdev(XenBlockDevice *blockdev, Error **errp)
{
    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(blockdev)));
    unsigned long used_devs[BITS_TO_LONGS(MAX_AUTO_VDEV)];
    XenBlockVdev *vdev = &blockdev->props.vdev;
    char fe_path[XENSTORE_ABS_PATH_MAX + 1];
    char **existing_frontends;
    unsigned int nr_existing = 0;
    unsigned int vdev_nr;
    int i, disk = 0;

    snprintf(fe_path, sizeof(fe_path), "/local/domain/%u/device/vbd",
             blockdev->xendev.frontend_id);

    existing_frontends = qemu_xen_xs_directory(xenbus->xsh, XBT_NULL, fe_path,
                                               &nr_existing);
    if (!existing_frontends) {
        if (errno == ENOENT) {
            /*
             * If the frontend directory doesn't exist because there are
             * no existing vbd devices, that's fine. Just ensure that we
             * don't dereference the NULL existing_frontends pointer, by
             * checking that nr_existing is zero so the loop below is not
             * entered.
             *
             * In fact this is redundant since nr_existing is initialized
             * to zero, but setting it again here makes it abundantly clear
             * to Coverity, and to the human reader who doesn't know the
             * semantics of qemu_xen_xs_directory() off the top of their
             * head.
             */
            nr_existing = 0;
        } else {
            /* All other errors accessing the frontend directory are fatal. */
            error_setg_errno(errp, errno, "cannot read %s", fe_path);
            return false;
        }
    }

    memset(used_devs, 0, sizeof(used_devs));
    for (i = 0; i < nr_existing; i++) {
        if (qemu_strtoui(existing_frontends[i], NULL, 10, &vdev_nr)) {
            free(existing_frontends[i]);
            continue;
        }

        free(existing_frontends[i]);

        disk = vdev_to_diskno(vdev_nr);
        if (disk < 0 || disk >= MAX_AUTO_VDEV) {
            continue;
        }

        set_bit(disk, used_devs);
    }
    free(existing_frontends);

    disk = find_first_zero_bit(used_devs, MAX_AUTO_VDEV);
    if (disk == MAX_AUTO_VDEV) {
        error_setg(errp, "cannot find device vdev for block device");
        return false;
    }

    vdev->type = XEN_BLOCK_VDEV_TYPE_XVD;
    vdev->partition = 0;
    vdev->disk = disk;
    if (disk < (1 << 4)) {
        vdev->number = (XVDA_MAJOR << 8) | (disk << 4);
    } else {
        vdev->number = (XVDQ_MAJOR << 8) | (disk << 8);
    }
    return true;
}

static char *xen_block_get_name(XenDevice *xendev, Error **errp)
{
    XenBlockDevice *blockdev = XEN_BLOCK_DEVICE(xendev);
    XenBlockVdev *vdev = &blockdev->props.vdev;

    if (vdev->type == XEN_BLOCK_VDEV_TYPE_INVALID &&
        !xen_block_find_free_vdev(blockdev, errp)) {
        return NULL;
    }
    return g_strdup_printf("%lu", vdev->number);
}

static void xen_block_disconnect(XenDevice *xendev, Error **errp)
{
    XenBlockDevice *blockdev = XEN_BLOCK_DEVICE(xendev);
    const char *type = object_get_typename(OBJECT(blockdev));
    XenBlockVdev *vdev = &blockdev->props.vdev;

    trace_xen_block_disconnect(type, vdev->disk, vdev->partition);

    xen_block_dataplane_stop(blockdev->dataplane);
}

static void xen_block_connect(XenDevice *xendev, Error **errp)
{
    XenBlockDevice *blockdev = XEN_BLOCK_DEVICE(xendev);
    const char *type = object_get_typename(OBJECT(blockdev));
    XenBlockVdev *vdev = &blockdev->props.vdev;
    BlockConf *conf = &blockdev->props.conf;
    unsigned int feature_large_sector_size;
    unsigned int order, nr_ring_ref, *ring_ref, event_channel, protocol;
    char *str;

    trace_xen_block_connect(type, vdev->disk, vdev->partition);

    if (xen_device_frontend_scanf(xendev, "feature-large-sector-size", "%u",
                                  &feature_large_sector_size) != 1) {
        feature_large_sector_size = 0;
    }

    if (feature_large_sector_size != 1 &&
        conf->logical_block_size != XEN_BLKIF_SECTOR_SIZE) {
        error_setg(errp, "logical_block_size != %u not supported by frontend",
                   XEN_BLKIF_SECTOR_SIZE);
        return;
    }

    if (xen_device_frontend_scanf(xendev, "ring-page-order", "%u",
                                  &order) != 1) {
        nr_ring_ref = 1;
        ring_ref = g_new(unsigned int, nr_ring_ref);

        if (xen_device_frontend_scanf(xendev, "ring-ref", "%u",
                                      &ring_ref[0]) != 1) {
            error_setg(errp, "failed to read ring-ref");
            g_free(ring_ref);
            return;
        }
    } else if (qemu_xen_gnttab_can_map_multi() &&
               order <= blockdev->props.max_ring_page_order) {
        unsigned int i;

        nr_ring_ref = 1 << order;
        ring_ref = g_new(unsigned int, nr_ring_ref);

        for (i = 0; i < nr_ring_ref; i++) {
            const char *key = g_strdup_printf("ring-ref%u", i);

            if (xen_device_frontend_scanf(xendev, key, "%u",
                                          &ring_ref[i]) != 1) {
                error_setg(errp, "failed to read %s", key);
                g_free((gpointer)key);
                g_free(ring_ref);
                return;
            }

            g_free((gpointer)key);
        }
    } else {
        error_setg(errp, "invalid ring-page-order (%d)", order);
        return;
    }

    if (xen_device_frontend_scanf(xendev, "event-channel", "%u",
                                  &event_channel) != 1) {
        error_setg(errp, "failed to read event-channel");
        g_free(ring_ref);
        return;
    }

    if (xen_device_frontend_scanf(xendev, "protocol", "%ms", &str) != 1) {
        /* x86 defaults to the 32-bit protocol even for 64-bit guests. */
        if (object_dynamic_cast(OBJECT(qdev_get_machine()), "x86-machine")) {
            protocol = BLKIF_PROTOCOL_X86_32;
        } else {
            protocol = BLKIF_PROTOCOL_NATIVE;
        }
    } else {
        if (strcmp(str, XEN_IO_PROTO_ABI_X86_32) == 0) {
            protocol = BLKIF_PROTOCOL_X86_32;
        } else if (strcmp(str, XEN_IO_PROTO_ABI_X86_64) == 0) {
            protocol = BLKIF_PROTOCOL_X86_64;
        } else {
            protocol = BLKIF_PROTOCOL_NATIVE;
        }

        free(str);
    }

    xen_block_dataplane_start(blockdev->dataplane, ring_ref, nr_ring_ref,
                              event_channel, protocol, errp);

    g_free(ring_ref);
}

static void xen_block_unrealize(XenDevice *xendev)
{
    XenBlockDevice *blockdev = XEN_BLOCK_DEVICE(xendev);
    XenBlockDeviceClass *blockdev_class =
        XEN_BLOCK_DEVICE_GET_CLASS(xendev);
    const char *type = object_get_typename(OBJECT(blockdev));
    XenBlockVdev *vdev = &blockdev->props.vdev;

    if (vdev->type == XEN_BLOCK_VDEV_TYPE_INVALID) {
        return;
    }

    trace_xen_block_unrealize(type, vdev->disk, vdev->partition);

    /* Disconnect from the frontend in case this has not already happened */
    xen_block_disconnect(xendev, NULL);

    xen_block_dataplane_destroy(blockdev->dataplane);
    blockdev->dataplane = NULL;

    if (blockdev_class->unrealize) {
        blockdev_class->unrealize(blockdev);
    }
}

static void xen_block_set_size(XenBlockDevice *blockdev)
{
    const char *type = object_get_typename(OBJECT(blockdev));
    XenBlockVdev *vdev = &blockdev->props.vdev;
    BlockConf *conf = &blockdev->props.conf;
    int64_t sectors = blk_getlength(conf->blk) / conf->logical_block_size;
    XenDevice *xendev = XEN_DEVICE(blockdev);

    trace_xen_block_size(type, vdev->disk, vdev->partition, sectors);

    xen_device_backend_printf(xendev, "sectors", "%"PRIi64, sectors);
}

static void xen_block_resize_cb(void *opaque)
{
    XenBlockDevice *blockdev = opaque;
    XenDevice *xendev = XEN_DEVICE(blockdev);
    enum xenbus_state state = xen_device_backend_get_state(xendev);

    xen_block_set_size(blockdev);

    /*
     * Mimic the behaviour of Linux xen-blkback and re-write the state
     * to trigger the frontend watch.
     */
    xen_device_backend_printf(xendev, "state", "%u", state);
}

/* Suspend request handling */
static void xen_block_drained_begin(void *opaque)
{
    XenBlockDevice *blockdev = opaque;

    xen_block_dataplane_detach(blockdev->dataplane);
}

/* Resume request handling */
static void xen_block_drained_end(void *opaque)
{
    XenBlockDevice *blockdev = opaque;

    xen_block_dataplane_attach(blockdev->dataplane);
}

static const BlockDevOps xen_block_dev_ops = {
    .resize_cb     = xen_block_resize_cb,
    .drained_begin = xen_block_drained_begin,
    .drained_end   = xen_block_drained_end,
};

static void xen_block_realize(XenDevice *xendev, Error **errp)
{
    ERRP_GUARD();
    XenBlockDevice *blockdev = XEN_BLOCK_DEVICE(xendev);
    XenBlockDeviceClass *blockdev_class =
        XEN_BLOCK_DEVICE_GET_CLASS(xendev);
    const char *type = object_get_typename(OBJECT(blockdev));
    XenBlockVdev *vdev = &blockdev->props.vdev;
    BlockConf *conf = &blockdev->props.conf;
    BlockBackend *blk = conf->blk;

    if (vdev->type == XEN_BLOCK_VDEV_TYPE_INVALID) {
        error_setg(errp, "vdev property not set");
        return;
    }

    trace_xen_block_realize(type, vdev->disk, vdev->partition);

    if (blockdev_class->realize) {
        blockdev_class->realize(blockdev, errp);
        if (*errp) {
            return;
        }
    }

    /*
     * The blkif protocol does not deal with removable media, so it must
     * always be present, even for CDRom devices.
     */
    assert(blk);
    if (!blk_is_inserted(blk)) {
        error_setg(errp, "device needs media, but drive is empty");
        return;
    }

    if (!blkconf_apply_backend_options(conf, blockdev->info & VDISK_READONLY,
                                       true, errp)) {
        return;
    }

    if (!(blockdev->info & VDISK_CDROM) &&
        !blkconf_geometry(conf, NULL, 65535, 255, 255, errp)) {
        return;
    }

    if (!blkconf_blocksizes(conf, errp)) {
        return;
    }

    if (conf->discard_granularity == -1) {
        conf->discard_granularity = conf->physical_block_size;
    }

    if (blk_get_flags(blk) & BDRV_O_UNMAP) {
        xen_device_backend_printf(xendev, "feature-discard", "%u", 1);
        xen_device_backend_printf(xendev, "discard-granularity", "%u",
                                  conf->discard_granularity);
        xen_device_backend_printf(xendev, "discard-alignment", "%u", 0);
    }

    xen_device_backend_printf(xendev, "feature-flush-cache", "%u", 1);

    if (qemu_xen_gnttab_can_map_multi()) {
        xen_device_backend_printf(xendev, "max-ring-page-order", "%u",
                                  blockdev->props.max_ring_page_order);
    }

    xen_device_backend_printf(xendev, "info", "%u", blockdev->info);

    xen_device_frontend_printf(xendev, "virtual-device", "%lu",
                               vdev->number);
    xen_device_frontend_printf(xendev, "device-type", "%s",
                               blockdev->device_type);

    xen_device_backend_printf(xendev, "sector-size", "%u",
                              conf->logical_block_size);

    xen_block_set_size(blockdev);

    blockdev->dataplane =
        xen_block_dataplane_create(xendev, blk, conf->logical_block_size,
                                   blockdev->props.iothread);

    blk_set_dev_ops(blk, &xen_block_dev_ops, blockdev);
}

static void xen_block_frontend_changed(XenDevice *xendev,
                                       enum xenbus_state frontend_state,
                                       Error **errp)
{
    ERRP_GUARD();
    enum xenbus_state backend_state = xen_device_backend_get_state(xendev);

    switch (frontend_state) {
    case XenbusStateInitialised:
    case XenbusStateConnected:
        if (backend_state == XenbusStateConnected) {
            break;
        }

        xen_block_disconnect(xendev, errp);
        if (*errp) {
            break;
        }

        xen_block_connect(xendev, errp);
        if (*errp) {
            break;
        }

        xen_device_backend_set_state(xendev, XenbusStateConnected);
        break;

    case XenbusStateClosing:
        xen_device_backend_set_state(xendev, XenbusStateClosing);
        break;

    case XenbusStateClosed:
    case XenbusStateUnknown:
        xen_block_disconnect(xendev, errp);
        if (*errp) {
            break;
        }

        xen_device_backend_set_state(xendev, XenbusStateClosed);
        break;

    default:
        break;
    }
}

static char *disk_to_vbd_name(unsigned int disk)
{
    char *name, *prefix = (disk >= 26) ?
        disk_to_vbd_name((disk / 26) - 1) : g_strdup("");

    name = g_strdup_printf("%s%c", prefix, 'a' + disk % 26);
    g_free(prefix);

    return name;
}

static void xen_block_get_vdev(Object *obj, Visitor *v, const char *name,
                               void *opaque, Error **errp)
{
    Property *prop = opaque;
    XenBlockVdev *vdev = object_field_prop_ptr(obj, prop);
    char *str;

    switch (vdev->type) {
    case XEN_BLOCK_VDEV_TYPE_DP:
        str = g_strdup_printf("d%lup%lu", vdev->disk, vdev->partition);
        break;

    case XEN_BLOCK_VDEV_TYPE_XVD:
    case XEN_BLOCK_VDEV_TYPE_HD:
    case XEN_BLOCK_VDEV_TYPE_SD: {
        char *vbd_name = disk_to_vbd_name(vdev->disk);

        str = g_strdup_printf("%s%s%lu",
                              (vdev->type == XEN_BLOCK_VDEV_TYPE_XVD) ?
                              "xvd" :
                              (vdev->type == XEN_BLOCK_VDEV_TYPE_HD) ?
                              "hd" :
                              "sd",
                              vbd_name, vdev->partition);
        g_free(vbd_name);
        break;
    }
    default:
        error_setg(errp, "invalid vdev type");
        return;
    }

    visit_type_str(v, name, &str, errp);
    g_free(str);
}

static int vbd_name_to_disk(const char *name, const char **endp,
                            unsigned long *disk)
{
    unsigned int n = 0;

    while (*name != '\0') {
        if (!g_ascii_isalpha(*name) || !g_ascii_islower(*name)) {
            break;
        }

        n *= 26;
        n += *name++ - 'a' + 1;
    }
    *endp = name;

    if (!n) {
        return -1;
    }

    *disk = n - 1;

    return 0;
}

static void xen_block_set_vdev(Object *obj, Visitor *v, const char *name,
                               void *opaque, Error **errp)
{
    Property *prop = opaque;
    XenBlockVdev *vdev = object_field_prop_ptr(obj, prop);
    char *str, *p;
    const char *end;

    if (!visit_type_str(v, name, &str, errp)) {
        return;
    }

    p = strchr(str, 'd');
    if (!p) {
        goto invalid;
    }

    *p++ = '\0';
    if (*str == '\0') {
        vdev->type = XEN_BLOCK_VDEV_TYPE_DP;
    } else if (strcmp(str, "xv") == 0) {
        vdev->type = XEN_BLOCK_VDEV_TYPE_XVD;
    } else if (strcmp(str, "h") == 0) {
        vdev->type = XEN_BLOCK_VDEV_TYPE_HD;
    } else if (strcmp(str, "s") == 0) {
        vdev->type = XEN_BLOCK_VDEV_TYPE_SD;
    } else {
        goto invalid;
    }

    if (vdev->type == XEN_BLOCK_VDEV_TYPE_DP) {
        if (qemu_strtoul(p, &end, 10, &vdev->disk)) {
            goto invalid;
        }

        if (*end == 'p') {
            if (*(++end) == '\0') {
                goto invalid;
            }
        }
    } else {
        if (vbd_name_to_disk(p, &end, &vdev->disk)) {
            goto invalid;
        }
    }

    if (*end != '\0') {
        p = (char *)end;

        if (qemu_strtoul(p, &end, 10, &vdev->partition)) {
            goto invalid;
        }

        if (*end != '\0') {
            goto invalid;
        }
    } else {
        vdev->partition = 0;
    }

    switch (vdev->type) {
    case XEN_BLOCK_VDEV_TYPE_DP:
    case XEN_BLOCK_VDEV_TYPE_XVD:
        if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) {
            vdev->number = (XVDA_MAJOR << 8) | (vdev->disk << 4) |
                vdev->partition;
        } else if (vdev->disk < (1 << 20) && vdev->partition < (1 << 8)) {
            vdev->number = (XVDQ_MAJOR << 8) | (vdev->disk << 8) |
                vdev->partition;
        } else {
            goto invalid;
        }
        break;

    case XEN_BLOCK_VDEV_TYPE_HD:
        if ((vdev->disk == 0 || vdev->disk == 1) &&
            vdev->partition < (1 << 6)) {
            vdev->number = (HDA_MAJOR << 8) | (vdev->disk << 6) |
                vdev->partition;
        } else if ((vdev->disk == 2 || vdev->disk == 3) &&
                   vdev->partition < (1 << 6)) {
            vdev->number = (HDC_MAJOR << 8) | ((vdev->disk - 2) << 6) |
                vdev->partition;
        } else {
            goto invalid;
        }
        break;

    case XEN_BLOCK_VDEV_TYPE_SD:
        if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) {
            vdev->number = (SDA_MAJOR << 8) | (vdev->disk << 4) |
                vdev->partition;
        } else {
            goto invalid;
        }
        break;

    default:
        goto invalid;
    }

    g_free(str);
    return;

invalid:
    error_setg(errp, "invalid virtual disk specifier");

    vdev->type = XEN_BLOCK_VDEV_TYPE_INVALID;
    g_free(str);
}

/*
 * This property deals with 'vdev' names adhering to the Xen VBD naming
 * scheme described in:
 *
 * https://xenbits.xen.org/docs/unstable/man/xen-vbd-interface.7.html
 */
const PropertyInfo xen_block_prop_vdev = {
    .name  = "str",
    .description = "Virtual Disk specifier: d*p*/xvd*/hd*/sd*",
    .get = xen_block_get_vdev,
    .set = xen_block_set_vdev,
};

static Property xen_block_props[] = {
    DEFINE_PROP("vdev", XenBlockDevice, props.vdev,
                xen_block_prop_vdev, XenBlockVdev),
    DEFINE_BLOCK_PROPERTIES(XenBlockDevice, props.conf),
    DEFINE_PROP_UINT32("max-ring-page-order", XenBlockDevice,
                       props.max_ring_page_order, 4),
    DEFINE_PROP_LINK("iothread", XenBlockDevice, props.iothread,
                     TYPE_IOTHREAD, IOThread *),
    DEFINE_PROP_END_OF_LIST()
};

static void xen_block_class_init(ObjectClass *class, void *data)
{
    DeviceClass *dev_class = DEVICE_CLASS(class);
    XenDeviceClass *xendev_class = XEN_DEVICE_CLASS(class);

    xendev_class->backend = "qdisk";
    xendev_class->device = "vbd";
    xendev_class->get_name = xen_block_get_name;
    xendev_class->realize = xen_block_realize;
    xendev_class->frontend_changed = xen_block_frontend_changed;
    xendev_class->unrealize = xen_block_unrealize;

    device_class_set_props(dev_class, xen_block_props);
}

static const TypeInfo xen_block_type_info = {
    .name = TYPE_XEN_BLOCK_DEVICE,
    .parent = TYPE_XEN_DEVICE,
    .instance_size = sizeof(XenBlockDevice),
    .abstract = true,
    .class_size = sizeof(XenBlockDeviceClass),
    .class_init = xen_block_class_init,
};

static void xen_disk_unrealize(XenBlockDevice *blockdev)
{
    trace_xen_disk_unrealize();
}

static void xen_disk_realize(XenBlockDevice *blockdev, Error **errp)
{
    BlockConf *conf = &blockdev->props.conf;

    trace_xen_disk_realize();

    blockdev->device_type = "disk";

    if (!conf->blk) {
        error_setg(errp, "drive property not set");
        return;
    }

    blockdev->info = blk_supports_write_perm(conf->blk) ? 0 : VDISK_READONLY;
}

static void xen_disk_class_init(ObjectClass *class, void *data)
{
    DeviceClass *dev_class = DEVICE_CLASS(class);
    XenBlockDeviceClass *blockdev_class = XEN_BLOCK_DEVICE_CLASS(class);

    blockdev_class->realize = xen_disk_realize;
    blockdev_class->unrealize = xen_disk_unrealize;

    dev_class->desc = "Xen Disk Device";
}

static const TypeInfo xen_disk_type_info = {
    .name = TYPE_XEN_DISK_DEVICE,
    .parent = TYPE_XEN_BLOCK_DEVICE,
    .instance_size = sizeof(XenDiskDevice),
    .class_init = xen_disk_class_init,
};

static void xen_cdrom_unrealize(XenBlockDevice *blockdev)
{
    trace_xen_cdrom_unrealize();
}

static void xen_cdrom_realize(XenBlockDevice *blockdev, Error **errp)
{
    BlockConf *conf = &blockdev->props.conf;

    trace_xen_cdrom_realize();

    blockdev->device_type = "cdrom";

    if (!conf->blk) {
        int rc;

        /* Set up an empty drive */
        conf->blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);

        rc = blk_attach_dev(conf->blk, DEVICE(blockdev));
        if (!rc) {
            error_setg_errno(errp, -rc, "failed to create drive");
            return;
        }
    }

    blockdev->info = VDISK_READONLY | VDISK_CDROM;
}

static void xen_cdrom_class_init(ObjectClass *class, void *data)
{
    DeviceClass *dev_class = DEVICE_CLASS(class);
    XenBlockDeviceClass *blockdev_class = XEN_BLOCK_DEVICE_CLASS(class);

    blockdev_class->realize = xen_cdrom_realize;
    blockdev_class->unrealize = xen_cdrom_unrealize;

    dev_class->desc = "Xen CD-ROM Device";
}

static const TypeInfo xen_cdrom_type_info = {
    .name = TYPE_XEN_CDROM_DEVICE,
    .parent = TYPE_XEN_BLOCK_DEVICE,
    .instance_size = sizeof(XenCDRomDevice),
    .class_init = xen_cdrom_class_init,
};

static void xen_block_register_types(void)
{
    type_register_static(&xen_block_type_info);
    type_register_static(&xen_disk_type_info);
    type_register_static(&xen_cdrom_type_info);
}

type_init(xen_block_register_types)

static void xen_block_blockdev_del(const char *node_name, Error **errp)
{
    trace_xen_block_blockdev_del(node_name);

    qmp_blockdev_del(node_name, errp);
}

static char *xen_block_blockdev_add(const char *id, QDict *qdict,
                                    Error **errp)
{
    ERRP_GUARD();
    const char *driver = qdict_get_try_str(qdict, "driver");
    BlockdevOptions *options = NULL;
    char *node_name;
    Visitor *v;

    if (!driver) {
        error_setg(errp, "no 'driver' parameter");
        return NULL;
    }

    node_name = g_strdup_printf("%s-%s", id, driver);
    qdict_put_str(qdict, "node-name", node_name);

    trace_xen_block_blockdev_add(node_name);

    v = qobject_input_visitor_new(QOBJECT(qdict));
    visit_type_BlockdevOptions(v, NULL, &options, errp);
    visit_free(v);
    if (!options) {
        goto fail;
    }

    qmp_blockdev_add(options, errp);

    if (*errp) {
        goto fail;
    }

    qapi_free_BlockdevOptions(options);

    return node_name;

fail:
    if (options) {
        qapi_free_BlockdevOptions(options);
    }
    g_free(node_name);

    return NULL;
}

static void xen_block_drive_destroy(XenBlockDrive *drive, Error **errp)
{
    ERRP_GUARD();
    char *node_name = drive->node_name;

    if (node_name) {
        xen_block_blockdev_del(node_name, errp);
        if (*errp) {
            return;
        }
        g_free(node_name);
        drive->node_name = NULL;
    }
    g_free(drive->id);
    g_free(drive);
}

static XenBlockDrive *xen_block_drive_create(const char *id,
                                             const char *device_type,
                                             QDict *opts, Error **errp)
{
    ERRP_GUARD();
    const char *params = qdict_get_try_str(opts, "params");
    const char *mode = qdict_get_try_str(opts, "mode");
    const char *direct_io_safe = qdict_get_try_str(opts, "direct-io-safe");
    const char *discard_enable = qdict_get_try_str(opts, "discard-enable");
    char *driver = NULL;
    char *filename = NULL;
    XenBlockDrive *drive = NULL;
    QDict *file_layer;
    QDict *driver_layer;
    struct stat st;
    int rc;

    if (params) {
        char **v = g_strsplit(params, ":", 2);

        if (v[1] == NULL) {
            filename = g_strdup(v[0]);
            driver = g_strdup("raw");
        } else {
            if (strcmp(v[0], "aio") == 0) {
                driver = g_strdup("raw");
            } else if (strcmp(v[0], "vhd") == 0) {
                driver = g_strdup("vpc");
            } else {
                driver = g_strdup(v[0]);
            }
            filename = g_strdup(v[1]);
        }

        g_strfreev(v);
    } else {
        error_setg(errp, "no params");
        goto done;
    }

    assert(filename);
    assert(driver);

    drive = g_new0(XenBlockDrive, 1);
    drive->id = g_strdup(id);

    rc = stat(filename, &st);
    if (rc) {
        error_setg_errno(errp, errno, "Could not stat file '%s'", filename);
        goto done;
    }

    file_layer = qdict_new();
    driver_layer = qdict_new();

    if (S_ISBLK(st.st_mode)) {
        qdict_put_str(file_layer, "driver", "host_device");
    } else {
        qdict_put_str(file_layer, "driver", "file");
    }

    qdict_put_str(file_layer, "filename", filename);

    if (mode && *mode != 'w') {
        qdict_put_bool(file_layer, "read-only", true);
    }

    if (direct_io_safe) {
        unsigned long value;

        if (!qemu_strtoul(direct_io_safe, NULL, 2, &value) && !!value) {
            QDict *cache_qdict = qdict_new();

            qdict_put_bool(cache_qdict, "direct", true);
            qdict_put(file_layer, "cache", cache_qdict);

            qdict_put_str(file_layer, "aio", "native");
        }
    }

    if (discard_enable) {
        unsigned long value;

        if (!qemu_strtoul(discard_enable, NULL, 2, &value) && !!value) {
            qdict_put_str(file_layer, "discard", "unmap");
            qdict_put_str(driver_layer, "discard", "unmap");
        }
    }

    /*
     * It is necessary to turn file locking off as an emulated device
     * may have already opened the same image file.
     */
    qdict_put_str(file_layer, "locking", "off");

    qdict_put_str(driver_layer, "driver", driver);

    qdict_put(driver_layer, "file", file_layer);

    g_assert(!drive->node_name);
    drive->node_name = xen_block_blockdev_add(drive->id, driver_layer,
                                              errp);

    qobject_unref(driver_layer);

done:
    g_free(filename);
    g_free(driver);
    if (*errp) {
        xen_block_drive_destroy(drive, NULL);
        return NULL;
    }

    return drive;
}

static const char *xen_block_drive_get_node_name(XenBlockDrive *drive)
{
    return drive->node_name ? drive->node_name : "";
}

static void xen_block_iothread_destroy(XenBlockIOThread *iothread,
                                       Error **errp)
{
    qmp_object_del(iothread->id, errp);

    g_free(iothread->id);
    g_free(iothread);
}

static XenBlockIOThread *xen_block_iothread_create(const char *id,
                                                   Error **errp)
{
    ERRP_GUARD();
    XenBlockIOThread *iothread = g_new(XenBlockIOThread, 1);
    ObjectOptions *opts;

    iothread->id = g_strdup(id);

    opts = g_new(ObjectOptions, 1);
    *opts = (ObjectOptions) {
        .qom_type = OBJECT_TYPE_IOTHREAD,
        .id = g_strdup(id),
    };
    qmp_object_add(opts, errp);
    qapi_free_ObjectOptions(opts);

    if (*errp) {
        g_free(iothread->id);
        g_free(iothread);
        return NULL;
    }

    return iothread;
}

static void xen_block_device_create(XenBackendInstance *backend,
                                    QDict *opts, Error **errp)
{
    ERRP_GUARD();
    XenBus *xenbus = xen_backend_get_bus(backend);
    const char *name = xen_backend_get_name(backend);
    unsigned long number;
    const char *vdev, *device_type;
    XenBlockDrive *drive = NULL;
    XenBlockIOThread *iothread = NULL;
    XenDevice *xendev = NULL;
    const char *type;
    XenBlockDevice *blockdev;

    if (qemu_strtoul(name, NULL, 10, &number)) {
        error_setg(errp, "failed to parse name '%s'", name);
        goto fail;
    }

    trace_xen_block_device_create(number);

    vdev = qdict_get_try_str(opts, "dev");
    if (!vdev) {
        error_setg(errp, "no dev parameter");
        goto fail;
    }

    device_type = qdict_get_try_str(opts, "device-type");
    if (!device_type) {
        error_setg(errp, "no device-type parameter");
        goto fail;
    }

    if (!strcmp(device_type, "disk")) {
        type = TYPE_XEN_DISK_DEVICE;
    } else if (!strcmp(device_type, "cdrom")) {
        type = TYPE_XEN_CDROM_DEVICE;
    } else {
        error_setg(errp, "invalid device-type parameter '%s'", device_type);
        goto fail;
    }

    drive = xen_block_drive_create(vdev, device_type, opts, errp);
    if (!drive) {
        error_prepend(errp, "failed to create drive: ");
        goto fail;
    }

    iothread = xen_block_iothread_create(vdev, errp);
    if (*errp) {
        error_prepend(errp, "failed to create iothread: ");
        goto fail;
    }

    xendev = XEN_DEVICE(qdev_new(type));
    blockdev = XEN_BLOCK_DEVICE(xendev);

    if (!object_property_set_str(OBJECT(xendev), "vdev", vdev,
                                 errp)) {
        error_prepend(errp, "failed to set 'vdev': ");
        goto fail;
    }

    if (!object_property_set_str(OBJECT(xendev), "drive",
                                 xen_block_drive_get_node_name(drive),
                                 errp)) {
        error_prepend(errp, "failed to set 'drive': ");
        goto fail;
    }

    if (!object_property_set_str(OBJECT(xendev), "iothread", iothread->id,
                                 errp)) {
        error_prepend(errp, "failed to set 'iothread': ");
        goto fail;
    }

    blockdev->iothread = iothread;
    blockdev->drive = drive;

    if (!qdev_realize_and_unref(DEVICE(xendev), BUS(xenbus), errp)) {
        error_prepend(errp, "realization of device %s failed: ", type);
        goto fail;
    }

    xen_backend_set_device(backend, xendev);
    return;

fail:
    if (xendev) {
        object_unparent(OBJECT(xendev));
    }

    if (iothread) {
        xen_block_iothread_destroy(iothread, NULL);
    }

    if (drive) {
        xen_block_drive_destroy(drive, NULL);
    }
}

static void xen_block_device_destroy(XenBackendInstance *backend,
                                     Error **errp)
{
    ERRP_GUARD();
    XenDevice *xendev = xen_backend_get_device(backend);
    XenBlockDevice *blockdev = XEN_BLOCK_DEVICE(xendev);
    XenBlockVdev *vdev = &blockdev->props.vdev;
    XenBlockDrive *drive = blockdev->drive;
    XenBlockIOThread *iothread = blockdev->iothread;

    trace_xen_block_device_destroy(vdev->number);

    object_unparent(OBJECT(xendev));

    /*
     * Drain all pending RCU callbacks as object_unparent() frees `xendev'
     * in a RCU callback.
     * And due to the property "drive" still existing in `xendev', we
     * can't destroy the XenBlockDrive associated with `xendev' with
     * xen_block_drive_destroy() below.
     */
    drain_call_rcu();

    if (iothread) {
        xen_block_iothread_destroy(iothread, errp);
        if (*errp) {
            error_prepend(errp, "failed to destroy iothread: ");
            return;
        }
    }

    if (drive) {
        xen_block_drive_destroy(drive, errp);
        if (*errp) {
            error_prepend(errp, "failed to destroy drive: ");
            return;
        }
    }
}

static const XenBackendInfo xen_block_backend_info = {
    .type = "qdisk",
    .create = xen_block_device_create,
    .destroy = xen_block_device_destroy,
};

static void xen_block_register_backend(void)
{
    xen_backend_register(&xen_block_backend_info);
}

xen_backend_init(xen_block_register_backend);
