#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-misc.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 "hw/hw.h"
+#include "qom/object_interfaces.h"
#include "hw/xen/xen_common.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"
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;
g_free(ring_ref);
}
-static void xen_block_unrealize(XenDevice *xendev, Error **errp)
+static void xen_block_unrealize(XenDevice *xendev)
{
XenBlockDevice *blockdev = XEN_BLOCK_DEVICE(xendev);
XenBlockDeviceClass *blockdev_class =
blockdev->dataplane = NULL;
if (blockdev_class->unrealize) {
- blockdev_class->unrealize(blockdev, errp);
+ blockdev_class->unrealize(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) / XEN_BLKIF_SECTOR_SIZE;
+ 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);
const char *type = object_get_typename(OBJECT(blockdev));
XenBlockVdev *vdev = &blockdev->props.vdev;
BlockConf *conf = &blockdev->props.conf;
+ BlockBackend *blk = conf->blk;
Error *local_err = NULL;
if (vdev->type == XEN_BLOCK_VDEV_TYPE_INVALID) {
* The blkif protocol does not deal with removable media, so it must
* always be present, even for CDRom devices.
*/
- assert(conf->blk);
- if (!blk_is_inserted(conf->blk)) {
+ assert(blk);
+ if (!blk_is_inserted(blk)) {
error_setg(errp, "device needs media, but drive is empty");
return;
}
return;
}
- blkconf_blocksizes(conf);
-
- if (conf->logical_block_size != XEN_BLKIF_SECTOR_SIZE) {
- error_setg(errp, "logical_block_size != %u not supported",
- XEN_BLKIF_SECTOR_SIZE);
- return;
- }
-
- if (conf->logical_block_size > conf->physical_block_size) {
- error_setg(
- errp, "logical_block_size > physical_block_size not supported");
+ if (!blkconf_blocksizes(conf, errp)) {
return;
}
- blk_set_dev_ops(conf->blk, &xen_block_dev_ops, blockdev);
- blk_set_guest_block_size(conf->blk, conf->logical_block_size);
+ blk_set_dev_ops(blk, &xen_block_dev_ops, blockdev);
+ blk_set_guest_block_size(blk, conf->logical_block_size);
if (conf->discard_granularity == -1) {
conf->discard_granularity = conf->physical_block_size;
}
- if (blk_get_flags(conf->blk) & BDRV_O_UNMAP) {
+ 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);
blockdev->device_type);
xen_device_backend_printf(xendev, "sector-size", "%u",
- XEN_BLKIF_SECTOR_SIZE);
+ conf->logical_block_size);
xen_block_set_size(blockdev);
blockdev->dataplane =
- xen_block_dataplane_create(xendev, conf, blockdev->props.iothread);
+ xen_block_dataplane_create(xendev, blk, conf->logical_block_size,
+ blockdev->props.iothread);
}
static void xen_block_frontend_changed(XenDevice *xendev,
break;
case XenbusStateClosed:
+ case XenbusStateUnknown:
xen_block_disconnect(xendev, &local_err);
if (local_err) {
error_propagate(errp, local_err);
DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
XenBlockVdev *vdev = qdev_get_prop_ptr(dev, prop);
- Error *local_err = NULL;
char *str, *p;
const char *end;
return;
}
- visit_type_str(v, name, &str, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
+ if (!visit_type_str(v, name, &str, errp)) {
return;
}
xendev_class->frontend_changed = xen_block_frontend_changed;
xendev_class->unrealize = xen_block_unrealize;
- dev_class->props = xen_block_props;
+ device_class_set_props(dev_class, xen_block_props);
}
static const TypeInfo xen_block_type_info = {
.class_init = xen_block_class_init,
};
-static void xen_disk_unrealize(XenBlockDevice *blockdev, Error **errp)
+static void xen_disk_unrealize(XenBlockDevice *blockdev)
{
trace_xen_disk_unrealize();
}
.class_init = xen_disk_class_init,
};
-static void xen_cdrom_unrealize(XenBlockDevice *blockdev, Error **errp)
+static void xen_cdrom_unrealize(XenBlockDevice *blockdev)
{
trace_xen_cdrom_unrealize();
}
{
XenBlockIOThread *iothread = g_new(XenBlockIOThread, 1);
Error *local_err = NULL;
+ QDict *opts;
+ QObject *ret_data = NULL;
iothread->id = g_strdup(id);
- qmp_object_add(TYPE_IOTHREAD, id, false, NULL, &local_err);
+ opts = qdict_new();
+ qdict_put_str(opts, "qom-type", TYPE_IOTHREAD);
+ qdict_put_str(opts, "id", id);
+ qmp_object_add(opts, &ret_data, &local_err);
+ qobject_unref(opts);
+ qobject_unref(ret_data);
+
if (local_err) {
error_propagate(errp, local_err);
goto fail;
}
- xendev = XEN_DEVICE(qdev_create(BUS(xenbus), type));
+ xendev = XEN_DEVICE(qdev_new(type));
blockdev = XEN_BLOCK_DEVICE(xendev);
- object_property_set_str(OBJECT(xendev), vdev, "vdev", &local_err);
- if (local_err) {
+ if (!object_property_set_str(OBJECT(xendev), "vdev", vdev,
+ &local_err)) {
error_propagate_prepend(errp, local_err, "failed to set 'vdev': ");
goto fail;
}
- object_property_set_str(OBJECT(xendev),
- xen_block_drive_get_node_name(drive), "drive",
- &local_err);
- if (local_err) {
+ if (!object_property_set_str(OBJECT(xendev), "drive",
+ xen_block_drive_get_node_name(drive),
+ &local_err)) {
error_propagate_prepend(errp, local_err, "failed to set 'drive': ");
goto fail;
}
- object_property_set_str(OBJECT(xendev), iothread->id, "iothread",
- &local_err);
- if (local_err) {
+ if (!object_property_set_str(OBJECT(xendev), "iothread", iothread->id,
+ &local_err)) {
error_propagate_prepend(errp, local_err,
"failed to set 'iothread': ");
goto fail;
blockdev->iothread = iothread;
blockdev->drive = drive;
- object_property_set_bool(OBJECT(xendev), true, "realized", &local_err);
- if (local_err) {
+ if (!qdev_realize_and_unref(DEVICE(xendev), BUS(xenbus), &local_err)) {
error_propagate_prepend(errp, local_err,
"realization of device %s failed: ",
type);
XenBlockVdev *vdev = &blockdev->props.vdev;
XenBlockDrive *drive = blockdev->drive;
XenBlockIOThread *iothread = blockdev->iothread;
+ Error *local_err = NULL;
trace_xen_block_device_destroy(vdev->number);
object_unparent(OBJECT(xendev));
if (iothread) {
- Error *local_err = NULL;
-
xen_block_iothread_destroy(iothread, &local_err);
if (local_err) {
error_propagate_prepend(errp, local_err,
- "failed to destroy iothread: ");
+ "failed to destroy iothread: ");
return;
}
}
if (drive) {
- Error *local_err = NULL;
-
xen_block_drive_destroy(drive, &local_err);
if (local_err) {
error_propagate_prepend(errp, local_err,
- "failed to destroy drive: ");
+ "failed to destroy drive: ");
+ return;
}
}
}