From: Paul Durrant Date: Tue, 24 Apr 2018 13:35:29 +0000 (+0100) Subject: Add get_name X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=027f7e672a50a3ad6ebeff65b3e1d1abece79af7;p=people%2Fpauldu%2Fqemu.git Add get_name Signed-off-by: Paul Durrant --- diff --git a/hw/block/xen_qdisk.c b/hw/block/xen_qdisk.c index f8ccb02628..4098333f1d 100644 --- a/hw/block/xen_qdisk.c +++ b/hw/block/xen_qdisk.c @@ -1,5 +1,6 @@ #include "qemu/osdep.h" #include "qapi/error.h" +#include "qapi/visitor.h" #include "hw/hw.h" #include "hw/block/block.h" #include "sysemu/blockdev.h" @@ -9,18 +10,82 @@ #include "xen_blkif.h" #include "trace.h" +typedef enum XenVdevType { + XEN_VDEV_TYPE_XVD, + XEN_VDEV_TYPE_HD, + XEN_VDEV_TYPE_SD, + XEN_VDEV_TYPE__MAX +} XenVdevType; + #define TYPE_XEN_QDISK_BACKEND "xen-qdisk" #define XEN_QDISK_BACKEND(obj) \ OBJECT_CHECK(XenQdiskBackend, (obj), TYPE_XEN_QDISK_BACKEND) typedef struct XenQdiskBackend { XenBackend xendev; + XenVdevType type; + int disk; + unsigned int partition; BlockConf conf; bool discard_enable; unsigned int max_ring_page_order; BlockBackend *blk; } XenQdiskBackend; +static char *xen_qdisk_get_name(XenBackend *dev, Error **errp) +{ + XenQdiskBackend *d = XEN_QDISK_BACKEND(dev); + unsigned int number; + + if (d->disk < 0) { + error_setg(errp, "invalid disk number (%d)", d->disk); + return NULL; + } + + switch (d->type) { + case XEN_VDEV_TYPE_XVD: + if (d->disk < (1 << 4) && d->partition < (1 << 4)) { + number = (202 << 8) | (d->disk << 4) | d->partition; + } else if (d->disk < (1 << 20) && d->partition < (1 << 8)) { + number = (1 << 28) | (d ->disk << 8) | d->partition; + } else { + error_setg(errp, "cannot use xvd encoding for d%up%u", d->disk, + d->partition); + return NULL; + } + break; + + case XEN_VDEV_TYPE_HD: + if ((d->disk == 0 || d->disk == 1) && d->partition < (1 << 4)) { + number = (3 << 8) | (d->disk << 6) | d->partition; + } else if ((d->disk == 2 || d->disk == 3) && + d->partition < (1 << 4)) { + number = (22 << 8) | ((d->disk - 2) << 6) | d->partition; + } else { + error_setg(errp, "cannot use hd encoding for d%up%u", d->disk, + d->partition); + return NULL; + } + break; + + case XEN_VDEV_TYPE_SD: + if (d->disk < (1 << 4) && d->partition < (1 << 4)) { + number = (8 << 8) | (d->disk << 4) | d->partition; + } else { + error_setg(errp, "cannot use sd encoding for d%up%u", d->disk, + d->partition); + return NULL; + } + break; + + default: + error_setg(errp, "invalid type"); + return NULL; + } + + return g_strdup_printf("%u", number); +} + static void xen_qdisk_realize(XenBackend *dev, Error **errp) { XenQdiskBackend *d = XEN_QDISK_BACKEND(dev); @@ -89,7 +154,65 @@ static void xen_qdisk_unrealize(XenBackend *dev, Error **errp) blockdev_mark_auto_del(d->blk); } +static void xen_vdev_get_type(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; + int *ptr = qdev_get_prop_ptr(dev, prop); + + visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp); +} + +static void xen_vdev_set_type(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; + int *ptr = qdev_get_prop_ptr(dev, prop); + + if (dev->realized) { + qdev_prop_set_after_realize(dev, name, errp); + return; + } + + visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp); +} + +static void xen_vdev_set_default_value_enum(Object *obj, + const Property *prop) +{ + object_property_set_str(obj, + qapi_enum_lookup(prop->info->enum_table, + prop->defval.i), + prop->name, &error_abort); +} + +static QEnumLookup xen_vdev_type_lookup = { + .array = (const char *const[]) { + "xvd", + "hd", + "sd", + }, + .size = XEN_VDEV_TYPE__MAX, +}; + +const PropertyInfo xen_qdisk_prop_type = { + .name = "str", + .description = "xvd/hd/sd", + .enum_table = &xen_vdev_type_lookup, + .get = xen_vdev_get_type, + .set = xen_vdev_set_type, + .set_default_value = xen_vdev_set_default_value_enum, +}; + static Property xen_qdisk_props[] = { + DEFINE_PROP_SIGNED("vdev-type", XenQdiskBackend, type, 0, + xen_qdisk_prop_type, XenVdevType), + DEFINE_PROP_INT32("disk", XenQdiskBackend, + disk, -1), + DEFINE_PROP_UINT32("partition", XenQdiskBackend, + partition, 0), DEFINE_BLOCK_PROPERTIES(XenQdiskBackend, conf), DEFINE_PROP_BOOL("discard-enable", XenQdiskBackend, discard_enable, false), @@ -104,6 +227,7 @@ static void xen_qdisk_class_init(ObjectClass *klass, void *data) XenBackendClass *k = XEN_BACKEND_CLASS(klass); k->device = "bar"; + k->get_name = xen_qdisk_get_name; k->realize = xen_qdisk_realize; k->initialize = xen_qdisk_initialize; k->disconnect = xen_qdisk_disconnect; diff --git a/hw/xen/xen_bus.c b/hw/xen/xen_bus.c index 81ea913ebc..edb48aa315 100644 --- a/hw/xen/xen_bus.c +++ b/hw/xen/xen_bus.c @@ -106,7 +106,7 @@ static int xenstore_vscanf(struct xs_handle *xsh, char *node, path = g_strdup_printf("%s/%s", node, key); value = xs_read(xsh, XBT_NULL, path, NULL); - rc = value ? vsscanf(value, fmt, ap) : -1; + rc = value ? vsscanf(value, fmt, ap) : EOF; free(value); g_free(path); @@ -380,8 +380,6 @@ static void xen_backend_realize(DeviceState *dev, Error **errp) const char *type = object_get_typename(OBJECT(d)); Error *local_err = NULL; - trace_xen_backend_realize(type, d->name); - if (d->frontend_id == DOMID_INVALID) d->frontend_id = xen_domid; @@ -390,11 +388,21 @@ static void xen_backend_realize(DeviceState *dev, Error **errp) return; } + if (!dc->get_name) + { + error_setg(errp, "get_name method not implemented"); + return; + } + + d->name = dc->get_name(d, &local_err); if (!d->name) { - error_setg(errp, "invalid name"); + error_propagate(errp, local_err); + error_prepend(errp, "failed to get backend name: "); return; } + trace_xen_backend_realize(type, d->name); + d->xsh = xs_open(0); if (!d->xsh) { error_setg(errp, "failed to open xenstore"); @@ -458,12 +466,13 @@ static void xen_backend_unrealize(DeviceState *dev, Error **errp) g_free(d->backend_path); xs_close(d->xsh); + + g_free(d->name); } static Property xen_backend_props[] = { DEFINE_PROP_UINT16("frontend-id", XenBackend, frontend_id, DOMID_INVALID), - DEFINE_PROP_STRING("name", XenBackend, name), DEFINE_PROP_END_OF_LIST() }; diff --git a/hw/xen/xen_foo.c b/hw/xen/xen_foo.c index 4911357dd8..fd5fc1f634 100644 --- a/hw/xen/xen_foo.c +++ b/hw/xen/xen_foo.c @@ -34,7 +34,6 @@ static void xen_foo_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); XenBackendClass *k = XEN_BACKEND_CLASS(klass); - k->type = "foo"; k->device = "bar"; k->realize = xen_foo_realize; k->unrealize = xen_foo_unrealize; diff --git a/include/hw/xen/xen_bus.h b/include/hw/xen/xen_bus.h index 7d044a257d..3827b89917 100644 --- a/include/hw/xen/xen_bus.h +++ b/include/hw/xen/xen_bus.h @@ -42,6 +42,7 @@ struct XenBackend { Notifier exit; }; +typedef char *(*XenBackendGetName)(XenBackend *dev, Error **errp); typedef void (*XenBackendRealize)(XenBackend *dev, Error **errp); typedef void (*XenBackendInitialize)(XenBackend *dev, Error **errp); typedef void (*XenBackendConnected)(XenBackend *dev, Error **errp); @@ -54,8 +55,8 @@ typedef struct XenBackendClass { /*< private >*/ DeviceClass parent_class; /*< public >*/ - const char *type; const char *device; + XenBackendGetName get_name; XenBackendRealize realize; XenBackendInitialize initialize; XenBackendConnected connected;