]> xenbits.xensource.com Git - people/pauldu/qemu.git/commitdiff
Add get_name
authorPaul Durrant <paul.durrant@citrix.com>
Tue, 24 Apr 2018 13:35:29 +0000 (14:35 +0100)
committerPaul Durrant <paul.durrant@citrix.com>
Thu, 26 Apr 2018 10:11:19 +0000 (11:11 +0100)
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
hw/block/xen_qdisk.c
hw/xen/xen_bus.c
hw/xen/xen_foo.c
include/hw/xen/xen_bus.h

index f8ccb02628b4fc912b83ddec8a0b65ef33e952f9..4098333f1d359fe1ee3116a425d612c2c49403ed 100644 (file)
@@ -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"
 #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;
index 81ea913ebcc1877a8d7c48f30b4d317d38228e4a..edb48aa31528983376af9dd960de40974e2285cb 100644 (file)
@@ -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()
 };
 
index 4911357dd876b9d3324342730e80e99edcb4a0e2..fd5fc1f634c90a9fc6e10335ac1471d113c5cdf3 100644 (file)
@@ -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;
index 7d044a257d668d885bd58bcd0cc49c3eb962c01c..3827b89917e489cc928323dc7cbdab9815681bde 100644 (file)
@@ -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;