All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification'
@ 2018-11-21 15:11 Paul Durrant
  2018-11-21 15:11   ` Paul Durrant
                   ` (25 more replies)
  0 siblings, 26 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:11 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Paul Durrant, Anthony Perard, Eduardo Habkost, Gerd Hoffmann,
	Greg Kurz, Jason Wang, Kevin Wolf, Marc-André Lureau,
	Marcel Apfelbaum, Max Reitz, Michael S. Tsirkin, Paolo Bonzini,
	Richard Henderson, Stefan Hajnoczi, Stefano Stabellini,
	Tim Smith

This series introduces a new QOM compliant framework for Xen PV backends.
This is achieved by first moving the current non-compliant framework aside,
before building up a new framework incrementally.

This series was prompted by a thread [1] started by Kevin Wolf in response
to patches against xen_disk.c posted by Tim Smith. Therefore, alongside
the patches introducing the new framework, other patches build up a QOM
compliant replacement for 'xen_disk', called 'xen-qdisk'. Patch #16 swaps
this new device into place (having establisheda mechanism to auto-
instantiate devices that is compliant with existing Xen toolstacks in
patch #15) and patch #18 then removes the old xen_disk code.

Subsequent series will port other Xen PV backends across to the new
framework.

The series is also available as a repository branch [2] on xenbits.xen.org.

[1] https://lists.gnu.org/archive/html/qemu-devel/2018-11/msg00259.html
[2] http://xenbits.xen.org/gitweb/?p=people/pauldu/qemu.git;a=shortlog;h=refs/heads/qom23

Paul Durrant (18):
  xen: re-name XenDevice to XenLegacyDevice...
  xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
  xen: introduce 'xen-qdisk'
  xen: create xenstore areas for XenDevice-s
  xen: add xenstore watcher infratructure
  xen: add grant table interface for XenDevice-s
  xen: add event channel interface for XenDevice-s
  xen: duplicate xen_disk.c as basis of dataplane/xen-qdisk.c
  xen: remove unnecessary code from dataplane/xen-qdisk.c
  xen: add header and build dataplane/xen-qdisk.c
  xen: remove 'XenBlkDev' and 'blkdev' names from dataplane/xen-qdisk
  xen: remove 'ioreq' struct/varable/field names from
    dataplane/xen-qdisk.c
  xen: purge 'blk' and 'ioreq' from function names in
    dataplane/xen-qdisk.c
  xen: add implementations of xen-qdisk connect and disconnect
    functions...
  xen: add a mechanism to automatically create XenDevice-s...
  xen: automatically create XenQdiskDevice-s
  MAINTAINERS: add myself as a Xen maintainer
  xen: remove the legacy 'xen_disk' backend

 MAINTAINERS                                        |    5 +-
 hw/9pfs/xen-9p-backend.c                           |   16 +-
 hw/block/Makefile.objs                             |    2 +-
 hw/block/dataplane/Makefile.objs                   |    1 +
 hw/block/dataplane/xen-qdisk.c                     |  756 +++++++++++++++
 hw/block/dataplane/xen-qdisk.h                     |   25 +
 hw/block/trace-events                              |    7 +
 hw/block/xen-qdisk.c                               |  698 +++++++++++++
 hw/block/xen_disk.c                                | 1011 -------------------
 hw/char/xen_console.c                              |   12 +-
 hw/display/xenfb.c                                 |   25 +-
 hw/i386/xen/xen-hvm.c                              |    5 +-
 hw/i386/xen/xen-mapcache.c                         |    2 +-
 hw/i386/xen/xen_platform.c                         |    2 +-
 hw/net/xen_nic.c                                   |   14 +-
 hw/usb/xen-usb.c                                   |   25 +-
 hw/xen/Makefile.objs                               |    2 +-
 hw/xen/trace-events                                |   17 +
 hw/xen/xen-backend.c                               |   67 ++
 hw/xen/xen-bus-helper.c                            |  152 +++
 hw/xen/xen-bus.c                                   | 1021 ++++++++++++++++++++
 hw/xen/xen-common.c                                |    2 +-
 hw/xen/{xen_backend.c => xen-legacy-backend.c}     |   74 +-
 hw/xen/xen_devconfig.c                             |    2 +-
 hw/xen/xen_pt.c                                    |    2 +-
 hw/xen/xen_pt_config_init.c                        |    2 +-
 hw/xen/xen_pt_graphics.c                           |    2 +-
 hw/xen/xen_pt_msi.c                                |    2 +-
 hw/xen/xen_pvdev.c                                 |   20 +-
 hw/xenpv/xen_domainbuild.c                         |    2 +-
 hw/xenpv/xen_machine_pv.c                          |    5 +-
 include/hw/xen/xen-backend.h                       |   24 +
 include/hw/xen/xen-bus-helper.h                    |   31 +
 include/hw/xen/xen-bus.h                           |  132 +++
 .../hw/xen/{xen_backend.h => xen-legacy-backend.h} |   43 +-
 include/hw/xen/xen-qdisk.h                         |   51 +
 include/hw/xen/xen_pvdev.h                         |   38 +-
 include/qemu/module.h                              |    3 +
 38 files changed, 3150 insertions(+), 1150 deletions(-)
 create mode 100644 hw/block/dataplane/xen-qdisk.c
 create mode 100644 hw/block/dataplane/xen-qdisk.h
 create mode 100644 hw/block/xen-qdisk.c
 delete mode 100644 hw/block/xen_disk.c
 create mode 100644 hw/xen/xen-backend.c
 create mode 100644 hw/xen/xen-bus-helper.c
 create mode 100644 hw/xen/xen-bus.c
 rename hw/xen/{xen_backend.c => xen-legacy-backend.c} (89%)
 create mode 100644 include/hw/xen/xen-backend.h
 create mode 100644 include/hw/xen/xen-bus-helper.h
 create mode 100644 include/hw/xen/xen-bus.h
 rename include/hw/xen/{xen_backend.h => xen-legacy-backend.h} (61%)
 create mode 100644 include/hw/xen/xen-qdisk.h
---
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Greg Kurz <groug@kaod.org>
Cc: Jason Wang <jasowang@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: "Marc-André Lureau" <marcandre.lureau@redhat.com>
Cc: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
Cc: Max Reitz <mreitz@redhat.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Tim Smith <tim.smith@citrix.com>
-- 
2.11.0

^ permalink raw reply	[flat|nested] 157+ messages in thread

* [Qemu-devel] [PATCH 01/18] xen: re-name XenDevice to XenLegacyDevice...
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
@ 2018-11-21 15:11   ` Paul Durrant
  2018-11-21 15:11 ` [Qemu-devel] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy Paul Durrant
                     ` (24 subsequent siblings)
  25 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:11 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Paul Durrant, Stefano Stabellini, Anthony Perard, Greg Kurz,
	Kevin Wolf, Max Reitz, Marc-André Lureau, Paolo Bonzini,
	Richard Henderson, Eduardo Habkost, Michael S. Tsirkin,
	Marcel Apfelbaum, Jason Wang, Gerd Hoffmann

...and xen_backend.h to xen-legacy-backend.h

Rather than attempting to convert the existing backend infrastructure to
be QOM compliant (which would be hard to do in an incremental fashion),
subsequent patches will introduce a completely new framework for Xen PV
backends. Hence it is necessary to re-name parts of existing code to avoid
name clashes. The re-named 'legacy' infrastructure will be removed once all
backends have been ported to the new framework.

This patch is purely cosmetic. No functional change.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Greg Kurz <groug@kaod.org>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
Cc: "Marc-André Lureau" <marcandre.lureau@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/9pfs/xen-9p-backend.c                           | 16 ++---
 hw/block/xen_disk.c                                | 24 +++----
 hw/char/xen_console.c                              | 12 ++--
 hw/display/xenfb.c                                 | 25 ++++----
 hw/i386/xen/xen-hvm.c                              |  2 +-
 hw/i386/xen/xen-mapcache.c                         |  2 +-
 hw/i386/xen/xen_platform.c                         |  2 +-
 hw/net/xen_nic.c                                   | 14 ++---
 hw/usb/xen-usb.c                                   | 25 ++++----
 hw/xen/Makefile.objs                               |  2 +-
 hw/xen/xen-common.c                                |  2 +-
 hw/xen/{xen_backend.c => xen-legacy-backend.c}     | 73 ++++++++++++----------
 hw/xen/xen_devconfig.c                             |  2 +-
 hw/xen/xen_pt.c                                    |  2 +-
 hw/xen/xen_pt_config_init.c                        |  2 +-
 hw/xen/xen_pt_graphics.c                           |  2 +-
 hw/xen/xen_pt_msi.c                                |  2 +-
 hw/xen/xen_pvdev.c                                 | 20 +++---
 hw/xenpv/xen_domainbuild.c                         |  2 +-
 hw/xenpv/xen_machine_pv.c                          |  2 +-
 .../hw/xen/{xen_backend.h => xen-legacy-backend.h} | 43 +++++++------
 include/hw/xen/xen_pvdev.h                         | 38 +++++------
 22 files changed, 166 insertions(+), 148 deletions(-)
 rename hw/xen/{xen_backend.c => xen-legacy-backend.c} (89%)
 rename include/hw/xen/{xen_backend.h => xen-legacy-backend.h} (61%)

diff --git a/hw/9pfs/xen-9p-backend.c b/hw/9pfs/xen-9p-backend.c
index 3f54a21c76..3859a06fe7 100644
--- a/hw/9pfs/xen-9p-backend.c
+++ b/hw/9pfs/xen-9p-backend.c
@@ -12,7 +12,7 @@
 
 #include "hw/hw.h"
 #include "hw/9pfs/9p.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "hw/9pfs/xen-9pfs.h"
 #include "qapi/error.h"
 #include "qemu/config-file.h"
@@ -45,7 +45,7 @@ typedef struct Xen9pfsRing {
 } Xen9pfsRing;
 
 typedef struct Xen9pfsDev {
-    struct XenDevice xendev;  /* must be first */
+    struct XenLegacyDevice xendev;  /* must be first */
     V9fsState state;
     char *path;
     char *security_model;
@@ -56,7 +56,7 @@ typedef struct Xen9pfsDev {
     Xen9pfsRing *rings;
 } Xen9pfsDev;
 
-static void xen_9pfs_disconnect(struct XenDevice *xendev);
+static void xen_9pfs_disconnect(struct XenLegacyDevice *xendev);
 
 static void xen_9pfs_in_sg(Xen9pfsRing *ring,
                            struct iovec *in_sg,
@@ -243,7 +243,7 @@ static const V9fsTransport xen_9p_transport = {
     .push_and_notify = xen_9pfs_push_and_notify,
 };
 
-static int xen_9pfs_init(struct XenDevice *xendev)
+static int xen_9pfs_init(struct XenLegacyDevice *xendev)
 {
     return 0;
 }
@@ -305,7 +305,7 @@ static void xen_9pfs_evtchn_event(void *opaque)
     qemu_bh_schedule(ring->bh);
 }
 
-static void xen_9pfs_disconnect(struct XenDevice *xendev)
+static void xen_9pfs_disconnect(struct XenLegacyDevice *xendev)
 {
     Xen9pfsDev *xen_9pdev = container_of(xendev, Xen9pfsDev, xendev);
     int i;
@@ -321,7 +321,7 @@ static void xen_9pfs_disconnect(struct XenDevice *xendev)
     }
 }
 
-static int xen_9pfs_free(struct XenDevice *xendev)
+static int xen_9pfs_free(struct XenLegacyDevice *xendev)
 {
     Xen9pfsDev *xen_9pdev = container_of(xendev, Xen9pfsDev, xendev);
     int i;
@@ -354,7 +354,7 @@ static int xen_9pfs_free(struct XenDevice *xendev)
     return 0;
 }
 
-static int xen_9pfs_connect(struct XenDevice *xendev)
+static int xen_9pfs_connect(struct XenLegacyDevice *xendev)
 {
     Error *err = NULL;
     int i;
@@ -467,7 +467,7 @@ out:
     return -1;
 }
 
-static void xen_9pfs_alloc(struct XenDevice *xendev)
+static void xen_9pfs_alloc(struct XenLegacyDevice *xendev)
 {
     xenstore_write_be_str(xendev, "versions", VERSIONS);
     xenstore_write_be_int(xendev, "max-rings", MAX_RINGS);
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 36eff94f84..75fe55f2ae 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -25,7 +25,7 @@
 #include <sys/uio.h>
 
 #include "hw/hw.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "xen_blkif.h"
 #include "sysemu/blockdev.h"
 #include "sysemu/iothread.h"
@@ -63,7 +63,7 @@ struct ioreq {
 #define MAX_RING_PAGE_ORDER 4
 
 struct XenBlkDev {
-    struct XenDevice    xendev;  /* must be first */
+    struct XenLegacyDevice    xendev;  /* must be first */
     char                *params;
     char                *mode;
     char                *type;
@@ -179,7 +179,7 @@ static void ioreq_release(struct ioreq *ioreq, bool finish)
 static int ioreq_parse(struct ioreq *ioreq)
 {
     struct XenBlkDev *blkdev = ioreq->blkdev;
-    struct XenDevice *xendev = &blkdev->xendev;
+    struct XenLegacyDevice *xendev = &blkdev->xendev;
     size_t len;
     int i;
 
@@ -243,7 +243,7 @@ err:
 static int ioreq_grant_copy(struct ioreq *ioreq)
 {
     struct XenBlkDev *blkdev = ioreq->blkdev;
-    struct XenDevice *xendev = &blkdev->xendev;
+    struct XenLegacyDevice *xendev = &blkdev->xendev;
     XenGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
     int i, count, rc;
     int64_t file_blk = blkdev->file_blk;
@@ -289,7 +289,7 @@ static void qemu_aio_complete(void *opaque, int ret)
 {
     struct ioreq *ioreq = opaque;
     struct XenBlkDev *blkdev = ioreq->blkdev;
-    struct XenDevice *xendev = &blkdev->xendev;
+    struct XenLegacyDevice *xendev = &blkdev->xendev;
 
     aio_context_acquire(blkdev->ctx);
 
@@ -608,7 +608,7 @@ static void blk_bh(void *opaque)
     aio_context_release(blkdev->ctx);
 }
 
-static void blk_alloc(struct XenDevice *xendev)
+static void blk_alloc(struct XenLegacyDevice *xendev)
 {
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
     Error *err = NULL;
@@ -628,7 +628,7 @@ static void blk_alloc(struct XenDevice *xendev)
 
 static void blk_parse_discard(struct XenBlkDev *blkdev)
 {
-    struct XenDevice *xendev = &blkdev->xendev;
+    struct XenLegacyDevice *xendev = &blkdev->xendev;
     int enable;
 
     blkdev->feature_discard = true;
@@ -642,7 +642,7 @@ static void blk_parse_discard(struct XenBlkDev *blkdev)
     }
 }
 
-static int blk_init(struct XenDevice *xendev)
+static int blk_init(struct XenLegacyDevice *xendev)
 {
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
     int info = 0;
@@ -737,7 +737,7 @@ out_error:
     return -1;
 }
 
-static int blk_connect(struct XenDevice *xendev)
+static int blk_connect(struct XenLegacyDevice *xendev)
 {
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
     int index, qflags;
@@ -941,7 +941,7 @@ static int blk_connect(struct XenDevice *xendev)
     return 0;
 }
 
-static void blk_disconnect(struct XenDevice *xendev)
+static void blk_disconnect(struct XenLegacyDevice *xendev)
 {
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
 
@@ -966,7 +966,7 @@ static void blk_disconnect(struct XenDevice *xendev)
     }
 }
 
-static int blk_free(struct XenDevice *xendev)
+static int blk_free(struct XenLegacyDevice *xendev)
 {
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
     struct ioreq *ioreq;
@@ -992,7 +992,7 @@ static int blk_free(struct XenDevice *xendev)
     return 0;
 }
 
-static void blk_event(struct XenDevice *xendev)
+static void blk_event(struct XenLegacyDevice *xendev)
 {
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
 
diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c
index 44f7236382..460adc1ba1 100644
--- a/hw/char/xen_console.c
+++ b/hw/char/xen_console.c
@@ -26,7 +26,7 @@
 #include "qapi/error.h"
 #include "hw/hw.h"
 #include "chardev/char-fe.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 
 #include <xen/io/console.h>
 
@@ -39,7 +39,7 @@ struct buffer {
 };
 
 struct XenConsole {
-    struct XenDevice  xendev;  /* must be first */
+    struct XenLegacyDevice  xendev;  /* must be first */
     struct buffer     buffer;
     char              console[XEN_BUFSIZE];
     int               ring_ref;
@@ -173,7 +173,7 @@ static void xencons_send(struct XenConsole *con)
 
 /* -------------------------------------------------------------------- */
 
-static int con_init(struct XenDevice *xendev)
+static int con_init(struct XenLegacyDevice *xendev)
 {
     struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
     char *type, *dom, label[32];
@@ -222,7 +222,7 @@ out:
     return ret;
 }
 
-static int con_initialise(struct XenDevice *xendev)
+static int con_initialise(struct XenLegacyDevice *xendev)
 {
     struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
     int limit;
@@ -259,7 +259,7 @@ static int con_initialise(struct XenDevice *xendev)
     return 0;
 }
 
-static void con_disconnect(struct XenDevice *xendev)
+static void con_disconnect(struct XenLegacyDevice *xendev)
 {
     struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
 
@@ -276,7 +276,7 @@ static void con_disconnect(struct XenDevice *xendev)
     }
 }
 
-static void con_event(struct XenDevice *xendev)
+static void con_event(struct XenLegacyDevice *xendev)
 {
     struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
 
diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c
index 0330dc6f61..6202f1150e 100644
--- a/hw/display/xenfb.c
+++ b/hw/display/xenfb.c
@@ -30,7 +30,7 @@
 #include "hw/hw.h"
 #include "ui/input.h"
 #include "ui/console.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 
 #include <xen/event_channel.h>
 #include <xen/io/fbif.h>
@@ -46,7 +46,7 @@
 /* -------------------------------------------------------------------- */
 
 struct common {
-    struct XenDevice  xendev;  /* must be first */
+    struct XenLegacyDevice  xendev;  /* must be first */
     void              *page;
 };
 
@@ -342,14 +342,14 @@ static QemuInputHandler xenfb_rel_mouse = {
     .sync  = xenfb_mouse_sync,
 };
 
-static int input_init(struct XenDevice *xendev)
+static int input_init(struct XenLegacyDevice *xendev)
 {
     xenstore_write_be_int(xendev, "feature-abs-pointer", 1);
     xenstore_write_be_int(xendev, "feature-raw-pointer", 1);
     return 0;
 }
 
-static int input_initialise(struct XenDevice *xendev)
+static int input_initialise(struct XenLegacyDevice *xendev)
 {
     struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);
     int rc;
@@ -361,7 +361,7 @@ static int input_initialise(struct XenDevice *xendev)
     return 0;
 }
 
-static void input_connected(struct XenDevice *xendev)
+static void input_connected(struct XenLegacyDevice *xendev)
 {
     struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);
 
@@ -395,7 +395,7 @@ static void input_connected(struct XenDevice *xendev)
     }
 }
 
-static void input_disconnect(struct XenDevice *xendev)
+static void input_disconnect(struct XenLegacyDevice *xendev)
 {
     struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);
 
@@ -410,7 +410,7 @@ static void input_disconnect(struct XenDevice *xendev)
     common_unbind(&in->c);
 }
 
-static void input_event(struct XenDevice *xendev)
+static void input_event(struct XenLegacyDevice *xendev)
 {
     struct XenInput *xenfb = container_of(xendev, struct XenInput, c.xendev);
     struct xenkbd_page *page = xenfb->c.page;
@@ -867,7 +867,7 @@ static void xenfb_handle_events(struct XenFB *xenfb)
     page->out_cons = cons;
 }
 
-static int fb_init(struct XenDevice *xendev)
+static int fb_init(struct XenLegacyDevice *xendev)
 {
 #ifdef XENFB_TYPE_RESIZE
     xenstore_write_be_int(xendev, "feature-resize", 1);
@@ -875,7 +875,7 @@ static int fb_init(struct XenDevice *xendev)
     return 0;
 }
 
-static int fb_initialise(struct XenDevice *xendev)
+static int fb_initialise(struct XenLegacyDevice *xendev)
 {
     struct XenFB *fb = container_of(xendev, struct XenFB, c.xendev);
     struct xenfb_page *fb_page;
@@ -912,7 +912,7 @@ static int fb_initialise(struct XenDevice *xendev)
     return 0;
 }
 
-static void fb_disconnect(struct XenDevice *xendev)
+static void fb_disconnect(struct XenLegacyDevice *xendev)
 {
     struct XenFB *fb = container_of(xendev, struct XenFB, c.xendev);
 
@@ -935,7 +935,8 @@ static void fb_disconnect(struct XenDevice *xendev)
     fb->bug_trigger    = 0;
 }
 
-static void fb_frontend_changed(struct XenDevice *xendev, const char *node)
+static void fb_frontend_changed(struct XenLegacyDevice *xendev,
+                                const char *node)
 {
     struct XenFB *fb = container_of(xendev, struct XenFB, c.xendev);
 
@@ -953,7 +954,7 @@ static void fb_frontend_changed(struct XenDevice *xendev, const char *node)
     }
 }
 
-static void fb_event(struct XenDevice *xendev)
+static void fb_event(struct XenLegacyDevice *xendev)
 {
     struct XenFB *xenfb = container_of(xendev, struct XenFB, c.xendev);
 
diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
index 935a3676c8..1d637639c7 100644
--- a/hw/i386/xen/xen-hvm.c
+++ b/hw/i386/xen/xen-hvm.c
@@ -16,7 +16,7 @@
 #include "hw/i386/pc.h"
 #include "hw/i386/apic-msidef.h"
 #include "hw/xen/xen_common.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "qapi/error.h"
 #include "qapi/qapi-commands-misc.h"
 #include "qemu/error-report.h"
diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
index 4e4f069a24..9134a7bfef 100644
--- a/hw/i386/xen/xen-mapcache.c
+++ b/hw/i386/xen/xen-mapcache.c
@@ -14,7 +14,7 @@
 
 #include <sys/resource.h>
 
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "qemu/bitmap.h"
 
 #include <xen/hvm/params.h>
diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c
index deb7a0c374..16afb54fee 100644
--- a/hw/i386/xen/xen_platform.c
+++ b/hw/i386/xen/xen_platform.c
@@ -30,7 +30,7 @@
 #include "hw/pci/pci.h"
 #include "hw/irq.h"
 #include "hw/xen/xen_common.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "trace.h"
 #include "exec/address-spaces.h"
 #include "sysemu/block-backend.h"
diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c
index 46a8dbfc90..37cda8e4be 100644
--- a/hw/net/xen_nic.c
+++ b/hw/net/xen_nic.c
@@ -28,14 +28,14 @@
 #include "net/net.h"
 #include "net/checksum.h"
 #include "net/util.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 
 #include <xen/io/netif.h>
 
 /* ------------------------------------------------------------- */
 
 struct XenNetDev {
-    struct XenDevice      xendev;  /* must be first */
+    struct XenLegacyDevice      xendev;  /* must be first */
     char                  *mac;
     int                   tx_work;
     int                   tx_ring_ref;
@@ -276,7 +276,7 @@ static NetClientInfo net_xen_info = {
     .receive = net_rx_packet,
 };
 
-static int net_init(struct XenDevice *xendev)
+static int net_init(struct XenLegacyDevice *xendev)
 {
     struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);
 
@@ -308,7 +308,7 @@ static int net_init(struct XenDevice *xendev)
     return 0;
 }
 
-static int net_connect(struct XenDevice *xendev)
+static int net_connect(struct XenLegacyDevice *xendev)
 {
     struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);
     int rx_copy;
@@ -363,7 +363,7 @@ static int net_connect(struct XenDevice *xendev)
     return 0;
 }
 
-static void net_disconnect(struct XenDevice *xendev)
+static void net_disconnect(struct XenLegacyDevice *xendev)
 {
     struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);
 
@@ -379,14 +379,14 @@ static void net_disconnect(struct XenDevice *xendev)
     }
 }
 
-static void net_event(struct XenDevice *xendev)
+static void net_event(struct XenLegacyDevice *xendev)
 {
     struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);
     net_tx_packets(netdev);
     qemu_flush_queued_packets(qemu_get_queue(netdev->nic));
 }
 
-static int net_free(struct XenDevice *xendev)
+static int net_free(struct XenLegacyDevice *xendev)
 {
     struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);
 
diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c
index 5b2e21ed18..9b2da6e75d 100644
--- a/hw/usb/xen-usb.c
+++ b/hw/usb/xen-usb.c
@@ -27,7 +27,7 @@
 #include "qemu/option.h"
 #include "hw/sysbus.h"
 #include "hw/usb.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "monitor/qdev.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qstring.h"
@@ -99,7 +99,7 @@ struct usbback_hotplug {
 };
 
 struct usbback_info {
-    struct XenDevice         xendev;  /* must be first */
+    struct XenLegacyDevice         xendev;  /* must be first */
     USBBus                   bus;
     void                     *urb_sring;
     void                     *conn_sring;
@@ -142,7 +142,7 @@ static int usbback_gnttab_map(struct usbback_req *usbback_req)
     unsigned int nr_segs, i, prot;
     uint32_t ref[USBIF_MAX_SEGMENTS_PER_REQUEST];
     struct usbback_info *usbif = usbback_req->usbif;
-    struct XenDevice *xendev = &usbif->xendev;
+    struct XenLegacyDevice *xendev = &usbif->xendev;
     struct usbif_request_segment *seg;
     void *addr;
 
@@ -220,7 +220,7 @@ static int usbback_gnttab_map(struct usbback_req *usbback_req)
 
 static int usbback_init_packet(struct usbback_req *usbback_req)
 {
-    struct XenDevice *xendev = &usbback_req->usbif->xendev;
+    struct XenLegacyDevice *xendev = &usbback_req->usbif->xendev;
     USBPacket *packet = &usbback_req->packet;
     USBDevice *dev = usbback_req->stub->dev;
     USBEndpoint *ep;
@@ -279,7 +279,7 @@ static void usbback_do_response(struct usbback_req *usbback_req, int32_t status,
 {
     struct usbback_info *usbif;
     struct usbif_urb_response *res;
-    struct XenDevice *xendev;
+    struct XenLegacyDevice *xendev;
     unsigned int notify;
 
     usbif = usbback_req->usbif;
@@ -824,7 +824,7 @@ static void usbback_process_port(struct usbback_info *usbif, unsigned port)
     g_free(busid);
 }
 
-static void usbback_disconnect(struct XenDevice *xendev)
+static void usbback_disconnect(struct XenLegacyDevice *xendev)
 {
     struct usbback_info *usbif;
     unsigned int i;
@@ -853,7 +853,7 @@ static void usbback_disconnect(struct XenDevice *xendev)
     TR_BUS(xendev, "finished\n");
 }
 
-static int usbback_connect(struct XenDevice *xendev)
+static int usbback_connect(struct XenLegacyDevice *xendev)
 {
     struct usbback_info *usbif;
     struct usbif_urb_sring *urb_sring;
@@ -909,7 +909,8 @@ static int usbback_connect(struct XenDevice *xendev)
     return 0;
 }
 
-static void usbback_backend_changed(struct XenDevice *xendev, const char *node)
+static void usbback_backend_changed(struct XenLegacyDevice *xendev,
+                                    const char *node)
 {
     struct usbback_info *usbif;
     unsigned int i;
@@ -922,7 +923,7 @@ static void usbback_backend_changed(struct XenDevice *xendev, const char *node)
     }
 }
 
-static int usbback_init(struct XenDevice *xendev)
+static int usbback_init(struct XenLegacyDevice *xendev)
 {
     struct usbback_info *usbif;
 
@@ -1001,7 +1002,7 @@ static USBPortOps xen_usb_port_ops = {
 static USBBusOps xen_usb_bus_ops = {
 };
 
-static void usbback_alloc(struct XenDevice *xendev)
+static void usbback_alloc(struct XenLegacyDevice *xendev)
 {
     struct usbback_info *usbif;
     USBPort *p;
@@ -1027,7 +1028,7 @@ static void usbback_alloc(struct XenDevice *xendev)
     xen_be_set_max_grant_refs(xendev, max_grants);
 }
 
-static int usbback_free(struct XenDevice *xendev)
+static int usbback_free(struct XenLegacyDevice *xendev)
 {
     struct usbback_info *usbif;
     struct usbback_req *usbback_req;
@@ -1066,7 +1067,7 @@ static int usbback_free(struct XenDevice *xendev)
     return 0;
 }
 
-static void usbback_event(struct XenDevice *xendev)
+static void usbback_event(struct XenLegacyDevice *xendev)
 {
     struct usbback_info *usbif;
 
diff --git a/hw/xen/Makefile.objs b/hw/xen/Makefile.objs
index 9ea5c73423..3f64a44051 100644
--- a/hw/xen/Makefile.objs
+++ b/hw/xen/Makefile.objs
@@ -1,5 +1,5 @@
 # xen backend driver support
-common-obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o xen_pvdev.o xen-common.o
+common-obj-$(CONFIG_XEN) += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o xen-common.o
 
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_graphics.o xen_pt_msi.o
diff --git a/hw/xen/xen-common.c b/hw/xen/xen-common.c
index 6ec14c73ca..ef130b2850 100644
--- a/hw/xen/xen-common.c
+++ b/hw/xen/xen-common.c
@@ -10,7 +10,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu/error-report.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "chardev/char.h"
 #include "sysemu/accel.h"
 #include "migration/misc.h"
diff --git a/hw/xen/xen_backend.c b/hw/xen/xen-legacy-backend.c
similarity index 89%
rename from hw/xen/xen_backend.c
rename to hw/xen/xen-legacy-backend.c
index 9a8e8771ec..2d748665a6 100644
--- a/hw/xen/xen_backend.c
+++ b/hw/xen/xen-legacy-backend.c
@@ -30,7 +30,7 @@
 #include "hw/boards.h"
 #include "qemu/log.h"
 #include "qapi/error.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "hw/xen/xen_pvdev.h"
 #include "monitor/qdev.h"
 
@@ -49,42 +49,47 @@ const char *xen_protocol;
 static bool xen_feature_grant_copy;
 static int debug;
 
-int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const char *val)
+int xenstore_write_be_str(struct XenLegacyDevice *xendev, const char *node,
+                          const char *val)
 {
     return xenstore_write_str(xendev->be, node, val);
 }
 
-int xenstore_write_be_int(struct XenDevice *xendev, const char *node, int ival)
+int xenstore_write_be_int(struct XenLegacyDevice *xendev, const char *node,
+                          int ival)
 {
     return xenstore_write_int(xendev->be, node, ival);
 }
 
-int xenstore_write_be_int64(struct XenDevice *xendev, const char *node, int64_t ival)
+int xenstore_write_be_int64(struct XenLegacyDevice *xendev, const char *node,
+                            int64_t ival)
 {
     return xenstore_write_int64(xendev->be, node, ival);
 }
 
-char *xenstore_read_be_str(struct XenDevice *xendev, const char *node)
+char *xenstore_read_be_str(struct XenLegacyDevice *xendev, const char *node)
 {
     return xenstore_read_str(xendev->be, node);
 }
 
-int xenstore_read_be_int(struct XenDevice *xendev, const char *node, int *ival)
+int xenstore_read_be_int(struct XenLegacyDevice *xendev, const char *node,
+                         int *ival)
 {
     return xenstore_read_int(xendev->be, node, ival);
 }
 
-char *xenstore_read_fe_str(struct XenDevice *xendev, const char *node)
+char *xenstore_read_fe_str(struct XenLegacyDevice *xendev, const char *node)
 {
     return xenstore_read_str(xendev->fe, node);
 }
 
-int xenstore_read_fe_int(struct XenDevice *xendev, const char *node, int *ival)
+int xenstore_read_fe_int(struct XenLegacyDevice *xendev, const char *node,
+                         int *ival)
 {
     return xenstore_read_int(xendev->fe, node, ival);
 }
 
-int xenstore_read_fe_uint64(struct XenDevice *xendev, const char *node,
+int xenstore_read_fe_uint64(struct XenLegacyDevice *xendev, const char *node,
                             uint64_t *uval)
 {
     return xenstore_read_uint64(xendev->fe, node, uval);
@@ -92,7 +97,7 @@ int xenstore_read_fe_uint64(struct XenDevice *xendev, const char *node,
 
 /* ------------------------------------------------------------- */
 
-int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state)
+int xen_be_set_state(struct XenLegacyDevice *xendev, enum xenbus_state state)
 {
     int rc;
 
@@ -106,7 +111,7 @@ int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state)
     return 0;
 }
 
-void xen_be_set_max_grant_refs(struct XenDevice *xendev,
+void xen_be_set_max_grant_refs(struct XenLegacyDevice *xendev,
                                unsigned int nr_refs)
 {
     assert(xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV);
@@ -117,7 +122,7 @@ void xen_be_set_max_grant_refs(struct XenDevice *xendev,
     }
 }
 
-void *xen_be_map_grant_refs(struct XenDevice *xendev, uint32_t *refs,
+void *xen_be_map_grant_refs(struct XenLegacyDevice *xendev, uint32_t *refs,
                             unsigned int nr_refs, int prot)
 {
     void *ptr;
@@ -135,7 +140,7 @@ void *xen_be_map_grant_refs(struct XenDevice *xendev, uint32_t *refs,
     return ptr;
 }
 
-void xen_be_unmap_grant_refs(struct XenDevice *xendev, void *ptr,
+void xen_be_unmap_grant_refs(struct XenLegacyDevice *xendev, void *ptr,
                              unsigned int nr_refs)
 {
     assert(xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV);
@@ -146,7 +151,7 @@ void xen_be_unmap_grant_refs(struct XenDevice *xendev, void *ptr,
     }
 }
 
-static int compat_copy_grant_refs(struct XenDevice *xendev,
+static int compat_copy_grant_refs(struct XenLegacyDevice *xendev,
                                   bool to_domain,
                                   XenGrantCopySegment segs[],
                                   unsigned int nr_segs)
@@ -195,7 +200,7 @@ static int compat_copy_grant_refs(struct XenDevice *xendev,
     return 0;
 }
 
-int xen_be_copy_grant_refs(struct XenDevice *xendev,
+int xen_be_copy_grant_refs(struct XenLegacyDevice *xendev,
                            bool to_domain,
                            XenGrantCopySegment segs[],
                            unsigned int nr_segs)
@@ -259,10 +264,11 @@ int xen_be_copy_grant_refs(struct XenDevice *xendev,
 /*
  * get xen backend device, allocate a new one if it doesn't exist.
  */
-static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
-                                           struct XenDevOps *ops)
+static struct XenLegacyDevice *xen_be_get_xendev(const char *type, int dom,
+                                                 int dev,
+                                                 struct XenDevOps *ops)
 {
-    struct XenDevice *xendev;
+    struct XenLegacyDevice *xendev;
 
     xendev = xen_pv_find_xendev(type, dom, dev);
     if (xendev) {
@@ -314,7 +320,8 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
  * Node specifies the changed field.  node = NULL means
  * update all fields (used for initialization).
  */
-static void xen_be_backend_changed(struct XenDevice *xendev, const char *node)
+static void xen_be_backend_changed(struct XenLegacyDevice *xendev,
+                                   const char *node)
 {
     if (node == NULL  ||  strcmp(node, "online") == 0) {
         if (xenstore_read_be_int(xendev, "online", &xendev->online) == -1) {
@@ -330,7 +337,8 @@ static void xen_be_backend_changed(struct XenDevice *xendev, const char *node)
     }
 }
 
-static void xen_be_frontend_changed(struct XenDevice *xendev, const char *node)
+static void xen_be_frontend_changed(struct XenLegacyDevice *xendev,
+                                    const char *node)
 {
     int fe_state;
 
@@ -373,7 +381,7 @@ static void xen_be_frontend_changed(struct XenDevice *xendev, const char *node)
  * only affects the xendev->be_state variable as xenbus should
  * already be put into that state by xend.
  */
-static int xen_be_try_setup(struct XenDevice *xendev)
+static int xen_be_try_setup(struct XenLegacyDevice *xendev)
 {
     char token[XEN_BUFSIZE];
     int be_state;
@@ -417,7 +425,7 @@ static int xen_be_try_setup(struct XenDevice *xendev)
  *
  * Goes to InitWait on success.
  */
-static int xen_be_try_init(struct XenDevice *xendev)
+static int xen_be_try_init(struct XenLegacyDevice *xendev)
 {
     int rc = 0;
 
@@ -446,7 +454,7 @@ static int xen_be_try_init(struct XenDevice *xendev)
  *
  * Goes to Connected on success.
  */
-static int xen_be_try_initialise(struct XenDevice *xendev)
+static int xen_be_try_initialise(struct XenLegacyDevice *xendev)
 {
     int rc = 0;
 
@@ -487,7 +495,7 @@ static int xen_be_try_initialise(struct XenDevice *xendev)
  * frontend being Connected.  Note that this may be called more
  * than once since the backend state is not modified.
  */
-static void xen_be_try_connected(struct XenDevice *xendev)
+static void xen_be_try_connected(struct XenLegacyDevice *xendev)
 {
     if (!xendev->ops->connected) {
         return;
@@ -510,7 +518,8 @@ static void xen_be_try_connected(struct XenDevice *xendev)
  *
  * Goes to Closed when done.
  */
-static void xen_be_disconnect(struct XenDevice *xendev, enum xenbus_state state)
+static void xen_be_disconnect(struct XenLegacyDevice *xendev,
+                              enum xenbus_state state)
 {
     if (xendev->be_state != XenbusStateClosing &&
         xendev->be_state != XenbusStateClosed  &&
@@ -529,7 +538,7 @@ static void xen_be_disconnect(struct XenDevice *xendev, enum xenbus_state state)
 /*
  * Try to reset xendev, for reconnection by another frontend instance.
  */
-static int xen_be_try_reset(struct XenDevice *xendev)
+static int xen_be_try_reset(struct XenLegacyDevice *xendev)
 {
     if (xendev->fe_state != XenbusStateInitialising) {
         return -1;
@@ -543,7 +552,7 @@ static int xen_be_try_reset(struct XenDevice *xendev)
 /*
  * state change dispatcher function
  */
-void xen_be_check_state(struct XenDevice *xendev)
+void xen_be_check_state(struct XenLegacyDevice *xendev)
 {
     int rc = 0;
 
@@ -587,7 +596,7 @@ void xen_be_check_state(struct XenDevice *xendev)
 
 static int xenstore_scan(const char *type, int dom, struct XenDevOps *ops)
 {
-    struct XenDevice *xendev;
+    struct XenLegacyDevice *xendev;
     char path[XEN_BUFSIZE], token[XEN_BUFSIZE];
     char **dev = NULL;
     unsigned int cdev, j;
@@ -620,7 +629,7 @@ static int xenstore_scan(const char *type, int dom, struct XenDevOps *ops)
 void xenstore_update_be(char *watch, char *type, int dom,
                         struct XenDevOps *ops)
 {
-    struct XenDevice *xendev;
+    struct XenLegacyDevice *xendev;
     char path[XEN_BUFSIZE], *bepath;
     unsigned int len, dev;
 
@@ -651,7 +660,7 @@ void xenstore_update_be(char *watch, char *type, int dom,
     }
 }
 
-void xenstore_update_fe(char *watch, struct XenDevice *xendev)
+void xenstore_update_fe(char *watch, struct XenLegacyDevice *xendev)
 {
     char *node;
     unsigned int len;
@@ -753,7 +762,7 @@ void xen_be_register_common(void)
 #endif
 }
 
-int xen_be_bind_evtchn(struct XenDevice *xendev)
+int xen_be_bind_evtchn(struct XenLegacyDevice *xendev)
 {
     if (xendev->local_port != -1) {
         return 0;
@@ -789,7 +798,7 @@ static const TypeInfo xendev_type_info = {
     .name          = TYPE_XENBACKEND,
     .parent        = TYPE_XENSYSDEV,
     .class_init    = xendev_class_init,
-    .instance_size = sizeof(struct XenDevice),
+    .instance_size = sizeof(struct XenLegacyDevice),
 };
 
 static void xen_sysbus_class_init(ObjectClass *klass, void *data)
diff --git a/hw/xen/xen_devconfig.c b/hw/xen/xen_devconfig.c
index aebc19bd71..1b30bd7691 100644
--- a/hw/xen/xen_devconfig.c
+++ b/hw/xen/xen_devconfig.c
@@ -1,5 +1,5 @@
 #include "qemu/osdep.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "qemu/option.h"
 #include "sysemu/blockdev.h"
 
diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
index f1f3a3727c..b20bf3a453 100644
--- a/hw/xen/xen_pt.c
+++ b/hw/xen/xen_pt.c
@@ -59,7 +59,7 @@
 #include "hw/pci/pci.h"
 #include "hw/xen/xen.h"
 #include "hw/i386/pc.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "xen_pt.h"
 #include "qemu/range.h"
 #include "exec/address-spaces.h"
diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
index 47f9010c75..81112049b6 100644
--- a/hw/xen/xen_pt_config_init.c
+++ b/hw/xen/xen_pt_config_init.c
@@ -15,7 +15,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qemu/timer.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "xen_pt.h"
 
 #define XEN_PT_MERGE_VALUE(value, data, val_mask) \
diff --git a/hw/xen/xen_pt_graphics.c b/hw/xen/xen_pt_graphics.c
index 135c8df1e7..130cc6cbf0 100644
--- a/hw/xen/xen_pt_graphics.c
+++ b/hw/xen/xen_pt_graphics.c
@@ -5,7 +5,7 @@
 #include "qapi/error.h"
 #include "xen_pt.h"
 #include "xen-host-pci-device.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 
 static unsigned long igd_guest_opregion;
 static unsigned long igd_host_opregion;
diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c
index cc514f9157..fb4b887b92 100644
--- a/hw/xen/xen_pt_msi.c
+++ b/hw/xen/xen_pt_msi.c
@@ -11,7 +11,7 @@
 
 #include "qemu/osdep.h"
 
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "xen_pt.h"
 #include "hw/i386/apic-msidef.h"
 
diff --git a/hw/xen/xen_pvdev.c b/hw/xen/xen_pvdev.c
index aed783e844..61de091002 100644
--- a/hw/xen/xen_pvdev.c
+++ b/hw/xen/xen_pvdev.c
@@ -20,7 +20,7 @@
 #include "qemu/osdep.h"
 #include "qemu/log.h"
 #include "hw/qdev-core.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "hw/xen/xen_pvdev.h"
 
 /* private */
@@ -34,7 +34,7 @@ struct xs_dirs {
 static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup =
     QTAILQ_HEAD_INITIALIZER(xs_cleanup);
 
-static QTAILQ_HEAD(XenDeviceHead, XenDevice) xendevs =
+static QTAILQ_HEAD(XenLegacyDeviceHead, XenLegacyDevice) xendevs =
     QTAILQ_HEAD_INITIALIZER(xendevs);
 
 /* ------------------------------------------------------------- */
@@ -195,7 +195,7 @@ const char *xenbus_strstate(enum xenbus_state state)
  *  2 == noisy debug messages (logfile only).
  *  3 == will flood your log (logfile only).
  */
-void xen_pv_printf(struct XenDevice *xendev, int msg_level,
+void xen_pv_printf(struct XenLegacyDevice *xendev, int msg_level,
                    const char *fmt, ...)
 {
     va_list args;
@@ -230,7 +230,7 @@ void xen_pv_printf(struct XenDevice *xendev, int msg_level,
 
 void xen_pv_evtchn_event(void *opaque)
 {
-    struct XenDevice *xendev = opaque;
+    struct XenLegacyDevice *xendev = opaque;
     evtchn_port_t port;
 
     port = xenevtchn_pending(xendev->evtchndev);
@@ -247,7 +247,7 @@ void xen_pv_evtchn_event(void *opaque)
     }
 }
 
-void xen_pv_unbind_evtchn(struct XenDevice *xendev)
+void xen_pv_unbind_evtchn(struct XenLegacyDevice *xendev)
 {
     if (xendev->local_port == -1) {
         return;
@@ -258,16 +258,16 @@ void xen_pv_unbind_evtchn(struct XenDevice *xendev)
     xendev->local_port = -1;
 }
 
-int xen_pv_send_notify(struct XenDevice *xendev)
+int xen_pv_send_notify(struct XenLegacyDevice *xendev)
 {
     return xenevtchn_notify(xendev->evtchndev, xendev->local_port);
 }
 
 /* ------------------------------------------------------------- */
 
-struct XenDevice *xen_pv_find_xendev(const char *type, int dom, int dev)
+struct XenLegacyDevice *xen_pv_find_xendev(const char *type, int dom, int dev)
 {
-    struct XenDevice *xendev;
+    struct XenLegacyDevice *xendev;
 
     QTAILQ_FOREACH(xendev, &xendevs, next) {
         if (xendev->dom != dom) {
@@ -287,7 +287,7 @@ struct XenDevice *xen_pv_find_xendev(const char *type, int dom, int dev)
 /*
  * release xen backend device.
  */
-void xen_pv_del_xendev(struct XenDevice *xendev)
+void xen_pv_del_xendev(struct XenLegacyDevice *xendev)
 {
     if (xendev->ops->free) {
         xendev->ops->free(xendev);
@@ -312,7 +312,7 @@ void xen_pv_del_xendev(struct XenDevice *xendev)
     qdev_unplug(&xendev->qdev, NULL);
 }
 
-void xen_pv_insert_xendev(struct XenDevice *xendev)
+void xen_pv_insert_xendev(struct XenLegacyDevice *xendev)
 {
     QTAILQ_INSERT_TAIL(&xendevs, xendev, next);
 }
diff --git a/hw/xenpv/xen_domainbuild.c b/hw/xenpv/xen_domainbuild.c
index 188acaca16..deb28cf596 100644
--- a/hw/xenpv/xen_domainbuild.c
+++ b/hw/xenpv/xen_domainbuild.c
@@ -1,6 +1,6 @@
 #include "qemu/osdep.h"
 #include "qemu/units.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "xen_domainbuild.h"
 #include "qemu/timer.h"
 #include "qemu/log.h"
diff --git a/hw/xenpv/xen_machine_pv.c b/hw/xenpv/xen_machine_pv.c
index 44d67b87c4..8c86fb7031 100644
--- a/hw/xenpv/xen_machine_pv.c
+++ b/hw/xenpv/xen_machine_pv.c
@@ -26,7 +26,7 @@
 #include "qemu/error-report.h"
 #include "hw/hw.h"
 #include "hw/boards.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "xen_domainbuild.h"
 #include "sysemu/block-backend.h"
 
diff --git a/include/hw/xen/xen_backend.h b/include/hw/xen/xen-legacy-backend.h
similarity index 61%
rename from include/hw/xen/xen_backend.h
rename to include/hw/xen/xen-legacy-backend.h
index 9c17fdd85d..20cb47b5bf 100644
--- a/include/hw/xen/xen_backend.h
+++ b/include/hw/xen/xen-legacy-backend.h
@@ -11,7 +11,7 @@
 #define TYPE_XENBACKEND "xen-backend"
 
 #define XENBACKEND_DEVICE(obj) \
-    OBJECT_CHECK(XenDevice, (obj), TYPE_XENBACKEND)
+    OBJECT_CHECK(XenLegacyDevice, (obj), TYPE_XENBACKEND)
 
 /* variables */
 extern struct xs_handle *xenstore;
@@ -20,32 +20,37 @@ extern DeviceState *xen_sysdev;
 extern BusState *xen_sysbus;
 
 int xenstore_mkdir(char *path, int p);
-int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const char *val);
-int xenstore_write_be_int(struct XenDevice *xendev, const char *node, int ival);
-int xenstore_write_be_int64(struct XenDevice *xendev, const char *node, int64_t ival);
-char *xenstore_read_be_str(struct XenDevice *xendev, const char *node);
-int xenstore_read_be_int(struct XenDevice *xendev, const char *node, int *ival);
-void xenstore_update_fe(char *watch, struct XenDevice *xendev);
+int xenstore_write_be_str(struct XenLegacyDevice *xendev, const char *node,
+                          const char *val);
+int xenstore_write_be_int(struct XenLegacyDevice *xendev, const char *node,
+                          int ival);
+int xenstore_write_be_int64(struct XenLegacyDevice *xendev, const char *node,
+                            int64_t ival);
+char *xenstore_read_be_str(struct XenLegacyDevice *xendev, const char *node);
+int xenstore_read_be_int(struct XenLegacyDevice *xendev, const char *node,
+                         int *ival);
+void xenstore_update_fe(char *watch, struct XenLegacyDevice *xendev);
 void xenstore_update_be(char *watch, char *type, int dom,
                         struct XenDevOps *ops);
-char *xenstore_read_fe_str(struct XenDevice *xendev, const char *node);
-int xenstore_read_fe_int(struct XenDevice *xendev, const char *node, int *ival);
-int xenstore_read_fe_uint64(struct XenDevice *xendev, const char *node,
+char *xenstore_read_fe_str(struct XenLegacyDevice *xendev, const char *node);
+int xenstore_read_fe_int(struct XenLegacyDevice *xendev, const char *node,
+                         int *ival);
+int xenstore_read_fe_uint64(struct XenLegacyDevice *xendev, const char *node,
                             uint64_t *uval);
 
-void xen_be_check_state(struct XenDevice *xendev);
+void xen_be_check_state(struct XenLegacyDevice *xendev);
 
 /* xen backend driver bits */
 int xen_be_init(void);
 void xen_be_register_common(void);
 int xen_be_register(const char *type, struct XenDevOps *ops);
-int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state);
-int xen_be_bind_evtchn(struct XenDevice *xendev);
-void xen_be_set_max_grant_refs(struct XenDevice *xendev,
+int xen_be_set_state(struct XenLegacyDevice *xendev, enum xenbus_state state);
+int xen_be_bind_evtchn(struct XenLegacyDevice *xendev);
+void xen_be_set_max_grant_refs(struct XenLegacyDevice *xendev,
                                unsigned int nr_refs);
-void *xen_be_map_grant_refs(struct XenDevice *xendev, uint32_t *refs,
+void *xen_be_map_grant_refs(struct XenLegacyDevice *xendev, uint32_t *refs,
                             unsigned int nr_refs, int prot);
-void xen_be_unmap_grant_refs(struct XenDevice *xendev, void *ptr,
+void xen_be_unmap_grant_refs(struct XenLegacyDevice *xendev, void *ptr,
                              unsigned int nr_refs);
 
 typedef struct XenGrantCopySegment {
@@ -59,17 +64,17 @@ typedef struct XenGrantCopySegment {
     size_t len;
 } XenGrantCopySegment;
 
-int xen_be_copy_grant_refs(struct XenDevice *xendev,
+int xen_be_copy_grant_refs(struct XenLegacyDevice *xendev,
                            bool to_domain, XenGrantCopySegment segs[],
                            unsigned int nr_segs);
 
-static inline void *xen_be_map_grant_ref(struct XenDevice *xendev,
+static inline void *xen_be_map_grant_ref(struct XenLegacyDevice *xendev,
                                          uint32_t ref, int prot)
 {
     return xen_be_map_grant_refs(xendev, &ref, 1, prot);
 }
 
-static inline void xen_be_unmap_grant_ref(struct XenDevice *xendev,
+static inline void xen_be_unmap_grant_ref(struct XenLegacyDevice *xendev,
                                           void *ptr)
 {
     return xen_be_unmap_grant_refs(xendev, ptr, 1);
diff --git a/include/hw/xen/xen_pvdev.h b/include/hw/xen/xen_pvdev.h
index d473e9b34d..83e5174d90 100644
--- a/include/hw/xen/xen_pvdev.h
+++ b/include/hw/xen/xen_pvdev.h
@@ -6,7 +6,7 @@
 
 #define XEN_BUFSIZE 1024
 
-struct XenDevice;
+struct XenLegacyDevice;
 
 /* driver uses grant tables  ->  open gntdev device (xendev->gnttabdev) */
 #define DEVOPS_FLAG_NEED_GNTDEV   1
@@ -16,19 +16,21 @@ struct XenDevice;
 struct XenDevOps {
     size_t    size;
     uint32_t  flags;
-    void      (*alloc)(struct XenDevice *xendev);
-    int       (*init)(struct XenDevice *xendev);
-    int       (*initialise)(struct XenDevice *xendev);
-    void      (*connected)(struct XenDevice *xendev);
-    void      (*event)(struct XenDevice *xendev);
-    void      (*disconnect)(struct XenDevice *xendev);
-    int       (*free)(struct XenDevice *xendev);
-    void      (*backend_changed)(struct XenDevice *xendev, const char *node);
-    void      (*frontend_changed)(struct XenDevice *xendev, const char *node);
+    void      (*alloc)(struct XenLegacyDevice *xendev);
+    int       (*init)(struct XenLegacyDevice *xendev);
+    int       (*initialise)(struct XenLegacyDevice *xendev);
+    void      (*connected)(struct XenLegacyDevice *xendev);
+    void      (*event)(struct XenLegacyDevice *xendev);
+    void      (*disconnect)(struct XenLegacyDevice *xendev);
+    int       (*free)(struct XenLegacyDevice *xendev);
+    void      (*backend_changed)(struct XenLegacyDevice *xendev,
+                                 const char *node);
+    void      (*frontend_changed)(struct XenLegacyDevice *xendev,
+                                  const char *node);
     int       (*backend_register)(void);
 };
 
-struct XenDevice {
+struct XenLegacyDevice {
     DeviceState        qdev;
     const char         *type;
     int                dom;
@@ -49,7 +51,7 @@ struct XenDevice {
     xengnttab_handle   *gnttabdev;
 
     struct XenDevOps   *ops;
-    QTAILQ_ENTRY(XenDevice) next;
+    QTAILQ_ENTRY(XenLegacyDevice) next;
 };
 
 /* ------------------------------------------------------------- */
@@ -66,14 +68,14 @@ void xenstore_update(void *unused);
 const char *xenbus_strstate(enum xenbus_state state);
 
 void xen_pv_evtchn_event(void *opaque);
-void xen_pv_insert_xendev(struct XenDevice *xendev);
-void xen_pv_del_xendev(struct XenDevice *xendev);
-struct XenDevice *xen_pv_find_xendev(const char *type, int dom, int dev);
+void xen_pv_insert_xendev(struct XenLegacyDevice *xendev);
+void xen_pv_del_xendev(struct XenLegacyDevice *xendev);
+struct XenLegacyDevice *xen_pv_find_xendev(const char *type, int dom, int dev);
 
-void xen_pv_unbind_evtchn(struct XenDevice *xendev);
-int xen_pv_send_notify(struct XenDevice *xendev);
+void xen_pv_unbind_evtchn(struct XenLegacyDevice *xendev);
+int xen_pv_send_notify(struct XenLegacyDevice *xendev);
 
-void xen_pv_printf(struct XenDevice *xendev, int msg_level,
+void xen_pv_printf(struct XenLegacyDevice *xendev, int msg_level,
                    const char *fmt, ...)  GCC_FMT_ATTR(3, 4);
 
 #endif /* QEMU_HW_XEN_PVDEV_H */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [PATCH 01/18] xen: re-name XenDevice to XenLegacyDevice...
@ 2018-11-21 15:11   ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:11 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Kevin Wolf, Stefano Stabellini, Eduardo Habkost,
	Michael S. Tsirkin, Jason Wang, Greg Kurz, Max Reitz,
	Paul Durrant, Gerd Hoffmann, Marcel Apfelbaum, Paolo Bonzini,
	Anthony Perard, Marc-André Lureau, Richard Henderson

...and xen_backend.h to xen-legacy-backend.h

Rather than attempting to convert the existing backend infrastructure to
be QOM compliant (which would be hard to do in an incremental fashion),
subsequent patches will introduce a completely new framework for Xen PV
backends. Hence it is necessary to re-name parts of existing code to avoid
name clashes. The re-named 'legacy' infrastructure will be removed once all
backends have been ported to the new framework.

This patch is purely cosmetic. No functional change.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Greg Kurz <groug@kaod.org>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
Cc: "Marc-André Lureau" <marcandre.lureau@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/9pfs/xen-9p-backend.c                           | 16 ++---
 hw/block/xen_disk.c                                | 24 +++----
 hw/char/xen_console.c                              | 12 ++--
 hw/display/xenfb.c                                 | 25 ++++----
 hw/i386/xen/xen-hvm.c                              |  2 +-
 hw/i386/xen/xen-mapcache.c                         |  2 +-
 hw/i386/xen/xen_platform.c                         |  2 +-
 hw/net/xen_nic.c                                   | 14 ++---
 hw/usb/xen-usb.c                                   | 25 ++++----
 hw/xen/Makefile.objs                               |  2 +-
 hw/xen/xen-common.c                                |  2 +-
 hw/xen/{xen_backend.c => xen-legacy-backend.c}     | 73 ++++++++++++----------
 hw/xen/xen_devconfig.c                             |  2 +-
 hw/xen/xen_pt.c                                    |  2 +-
 hw/xen/xen_pt_config_init.c                        |  2 +-
 hw/xen/xen_pt_graphics.c                           |  2 +-
 hw/xen/xen_pt_msi.c                                |  2 +-
 hw/xen/xen_pvdev.c                                 | 20 +++---
 hw/xenpv/xen_domainbuild.c                         |  2 +-
 hw/xenpv/xen_machine_pv.c                          |  2 +-
 .../hw/xen/{xen_backend.h => xen-legacy-backend.h} | 43 +++++++------
 include/hw/xen/xen_pvdev.h                         | 38 +++++------
 22 files changed, 166 insertions(+), 148 deletions(-)
 rename hw/xen/{xen_backend.c => xen-legacy-backend.c} (89%)
 rename include/hw/xen/{xen_backend.h => xen-legacy-backend.h} (61%)

diff --git a/hw/9pfs/xen-9p-backend.c b/hw/9pfs/xen-9p-backend.c
index 3f54a21c76..3859a06fe7 100644
--- a/hw/9pfs/xen-9p-backend.c
+++ b/hw/9pfs/xen-9p-backend.c
@@ -12,7 +12,7 @@
 
 #include "hw/hw.h"
 #include "hw/9pfs/9p.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "hw/9pfs/xen-9pfs.h"
 #include "qapi/error.h"
 #include "qemu/config-file.h"
@@ -45,7 +45,7 @@ typedef struct Xen9pfsRing {
 } Xen9pfsRing;
 
 typedef struct Xen9pfsDev {
-    struct XenDevice xendev;  /* must be first */
+    struct XenLegacyDevice xendev;  /* must be first */
     V9fsState state;
     char *path;
     char *security_model;
@@ -56,7 +56,7 @@ typedef struct Xen9pfsDev {
     Xen9pfsRing *rings;
 } Xen9pfsDev;
 
-static void xen_9pfs_disconnect(struct XenDevice *xendev);
+static void xen_9pfs_disconnect(struct XenLegacyDevice *xendev);
 
 static void xen_9pfs_in_sg(Xen9pfsRing *ring,
                            struct iovec *in_sg,
@@ -243,7 +243,7 @@ static const V9fsTransport xen_9p_transport = {
     .push_and_notify = xen_9pfs_push_and_notify,
 };
 
-static int xen_9pfs_init(struct XenDevice *xendev)
+static int xen_9pfs_init(struct XenLegacyDevice *xendev)
 {
     return 0;
 }
@@ -305,7 +305,7 @@ static void xen_9pfs_evtchn_event(void *opaque)
     qemu_bh_schedule(ring->bh);
 }
 
-static void xen_9pfs_disconnect(struct XenDevice *xendev)
+static void xen_9pfs_disconnect(struct XenLegacyDevice *xendev)
 {
     Xen9pfsDev *xen_9pdev = container_of(xendev, Xen9pfsDev, xendev);
     int i;
@@ -321,7 +321,7 @@ static void xen_9pfs_disconnect(struct XenDevice *xendev)
     }
 }
 
-static int xen_9pfs_free(struct XenDevice *xendev)
+static int xen_9pfs_free(struct XenLegacyDevice *xendev)
 {
     Xen9pfsDev *xen_9pdev = container_of(xendev, Xen9pfsDev, xendev);
     int i;
@@ -354,7 +354,7 @@ static int xen_9pfs_free(struct XenDevice *xendev)
     return 0;
 }
 
-static int xen_9pfs_connect(struct XenDevice *xendev)
+static int xen_9pfs_connect(struct XenLegacyDevice *xendev)
 {
     Error *err = NULL;
     int i;
@@ -467,7 +467,7 @@ out:
     return -1;
 }
 
-static void xen_9pfs_alloc(struct XenDevice *xendev)
+static void xen_9pfs_alloc(struct XenLegacyDevice *xendev)
 {
     xenstore_write_be_str(xendev, "versions", VERSIONS);
     xenstore_write_be_int(xendev, "max-rings", MAX_RINGS);
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 36eff94f84..75fe55f2ae 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -25,7 +25,7 @@
 #include <sys/uio.h>
 
 #include "hw/hw.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "xen_blkif.h"
 #include "sysemu/blockdev.h"
 #include "sysemu/iothread.h"
@@ -63,7 +63,7 @@ struct ioreq {
 #define MAX_RING_PAGE_ORDER 4
 
 struct XenBlkDev {
-    struct XenDevice    xendev;  /* must be first */
+    struct XenLegacyDevice    xendev;  /* must be first */
     char                *params;
     char                *mode;
     char                *type;
@@ -179,7 +179,7 @@ static void ioreq_release(struct ioreq *ioreq, bool finish)
 static int ioreq_parse(struct ioreq *ioreq)
 {
     struct XenBlkDev *blkdev = ioreq->blkdev;
-    struct XenDevice *xendev = &blkdev->xendev;
+    struct XenLegacyDevice *xendev = &blkdev->xendev;
     size_t len;
     int i;
 
@@ -243,7 +243,7 @@ err:
 static int ioreq_grant_copy(struct ioreq *ioreq)
 {
     struct XenBlkDev *blkdev = ioreq->blkdev;
-    struct XenDevice *xendev = &blkdev->xendev;
+    struct XenLegacyDevice *xendev = &blkdev->xendev;
     XenGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
     int i, count, rc;
     int64_t file_blk = blkdev->file_blk;
@@ -289,7 +289,7 @@ static void qemu_aio_complete(void *opaque, int ret)
 {
     struct ioreq *ioreq = opaque;
     struct XenBlkDev *blkdev = ioreq->blkdev;
-    struct XenDevice *xendev = &blkdev->xendev;
+    struct XenLegacyDevice *xendev = &blkdev->xendev;
 
     aio_context_acquire(blkdev->ctx);
 
@@ -608,7 +608,7 @@ static void blk_bh(void *opaque)
     aio_context_release(blkdev->ctx);
 }
 
-static void blk_alloc(struct XenDevice *xendev)
+static void blk_alloc(struct XenLegacyDevice *xendev)
 {
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
     Error *err = NULL;
@@ -628,7 +628,7 @@ static void blk_alloc(struct XenDevice *xendev)
 
 static void blk_parse_discard(struct XenBlkDev *blkdev)
 {
-    struct XenDevice *xendev = &blkdev->xendev;
+    struct XenLegacyDevice *xendev = &blkdev->xendev;
     int enable;
 
     blkdev->feature_discard = true;
@@ -642,7 +642,7 @@ static void blk_parse_discard(struct XenBlkDev *blkdev)
     }
 }
 
-static int blk_init(struct XenDevice *xendev)
+static int blk_init(struct XenLegacyDevice *xendev)
 {
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
     int info = 0;
@@ -737,7 +737,7 @@ out_error:
     return -1;
 }
 
-static int blk_connect(struct XenDevice *xendev)
+static int blk_connect(struct XenLegacyDevice *xendev)
 {
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
     int index, qflags;
@@ -941,7 +941,7 @@ static int blk_connect(struct XenDevice *xendev)
     return 0;
 }
 
-static void blk_disconnect(struct XenDevice *xendev)
+static void blk_disconnect(struct XenLegacyDevice *xendev)
 {
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
 
@@ -966,7 +966,7 @@ static void blk_disconnect(struct XenDevice *xendev)
     }
 }
 
-static int blk_free(struct XenDevice *xendev)
+static int blk_free(struct XenLegacyDevice *xendev)
 {
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
     struct ioreq *ioreq;
@@ -992,7 +992,7 @@ static int blk_free(struct XenDevice *xendev)
     return 0;
 }
 
-static void blk_event(struct XenDevice *xendev)
+static void blk_event(struct XenLegacyDevice *xendev)
 {
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
 
diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c
index 44f7236382..460adc1ba1 100644
--- a/hw/char/xen_console.c
+++ b/hw/char/xen_console.c
@@ -26,7 +26,7 @@
 #include "qapi/error.h"
 #include "hw/hw.h"
 #include "chardev/char-fe.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 
 #include <xen/io/console.h>
 
@@ -39,7 +39,7 @@ struct buffer {
 };
 
 struct XenConsole {
-    struct XenDevice  xendev;  /* must be first */
+    struct XenLegacyDevice  xendev;  /* must be first */
     struct buffer     buffer;
     char              console[XEN_BUFSIZE];
     int               ring_ref;
@@ -173,7 +173,7 @@ static void xencons_send(struct XenConsole *con)
 
 /* -------------------------------------------------------------------- */
 
-static int con_init(struct XenDevice *xendev)
+static int con_init(struct XenLegacyDevice *xendev)
 {
     struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
     char *type, *dom, label[32];
@@ -222,7 +222,7 @@ out:
     return ret;
 }
 
-static int con_initialise(struct XenDevice *xendev)
+static int con_initialise(struct XenLegacyDevice *xendev)
 {
     struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
     int limit;
@@ -259,7 +259,7 @@ static int con_initialise(struct XenDevice *xendev)
     return 0;
 }
 
-static void con_disconnect(struct XenDevice *xendev)
+static void con_disconnect(struct XenLegacyDevice *xendev)
 {
     struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
 
@@ -276,7 +276,7 @@ static void con_disconnect(struct XenDevice *xendev)
     }
 }
 
-static void con_event(struct XenDevice *xendev)
+static void con_event(struct XenLegacyDevice *xendev)
 {
     struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
 
diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c
index 0330dc6f61..6202f1150e 100644
--- a/hw/display/xenfb.c
+++ b/hw/display/xenfb.c
@@ -30,7 +30,7 @@
 #include "hw/hw.h"
 #include "ui/input.h"
 #include "ui/console.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 
 #include <xen/event_channel.h>
 #include <xen/io/fbif.h>
@@ -46,7 +46,7 @@
 /* -------------------------------------------------------------------- */
 
 struct common {
-    struct XenDevice  xendev;  /* must be first */
+    struct XenLegacyDevice  xendev;  /* must be first */
     void              *page;
 };
 
@@ -342,14 +342,14 @@ static QemuInputHandler xenfb_rel_mouse = {
     .sync  = xenfb_mouse_sync,
 };
 
-static int input_init(struct XenDevice *xendev)
+static int input_init(struct XenLegacyDevice *xendev)
 {
     xenstore_write_be_int(xendev, "feature-abs-pointer", 1);
     xenstore_write_be_int(xendev, "feature-raw-pointer", 1);
     return 0;
 }
 
-static int input_initialise(struct XenDevice *xendev)
+static int input_initialise(struct XenLegacyDevice *xendev)
 {
     struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);
     int rc;
@@ -361,7 +361,7 @@ static int input_initialise(struct XenDevice *xendev)
     return 0;
 }
 
-static void input_connected(struct XenDevice *xendev)
+static void input_connected(struct XenLegacyDevice *xendev)
 {
     struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);
 
@@ -395,7 +395,7 @@ static void input_connected(struct XenDevice *xendev)
     }
 }
 
-static void input_disconnect(struct XenDevice *xendev)
+static void input_disconnect(struct XenLegacyDevice *xendev)
 {
     struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);
 
@@ -410,7 +410,7 @@ static void input_disconnect(struct XenDevice *xendev)
     common_unbind(&in->c);
 }
 
-static void input_event(struct XenDevice *xendev)
+static void input_event(struct XenLegacyDevice *xendev)
 {
     struct XenInput *xenfb = container_of(xendev, struct XenInput, c.xendev);
     struct xenkbd_page *page = xenfb->c.page;
@@ -867,7 +867,7 @@ static void xenfb_handle_events(struct XenFB *xenfb)
     page->out_cons = cons;
 }
 
-static int fb_init(struct XenDevice *xendev)
+static int fb_init(struct XenLegacyDevice *xendev)
 {
 #ifdef XENFB_TYPE_RESIZE
     xenstore_write_be_int(xendev, "feature-resize", 1);
@@ -875,7 +875,7 @@ static int fb_init(struct XenDevice *xendev)
     return 0;
 }
 
-static int fb_initialise(struct XenDevice *xendev)
+static int fb_initialise(struct XenLegacyDevice *xendev)
 {
     struct XenFB *fb = container_of(xendev, struct XenFB, c.xendev);
     struct xenfb_page *fb_page;
@@ -912,7 +912,7 @@ static int fb_initialise(struct XenDevice *xendev)
     return 0;
 }
 
-static void fb_disconnect(struct XenDevice *xendev)
+static void fb_disconnect(struct XenLegacyDevice *xendev)
 {
     struct XenFB *fb = container_of(xendev, struct XenFB, c.xendev);
 
@@ -935,7 +935,8 @@ static void fb_disconnect(struct XenDevice *xendev)
     fb->bug_trigger    = 0;
 }
 
-static void fb_frontend_changed(struct XenDevice *xendev, const char *node)
+static void fb_frontend_changed(struct XenLegacyDevice *xendev,
+                                const char *node)
 {
     struct XenFB *fb = container_of(xendev, struct XenFB, c.xendev);
 
@@ -953,7 +954,7 @@ static void fb_frontend_changed(struct XenDevice *xendev, const char *node)
     }
 }
 
-static void fb_event(struct XenDevice *xendev)
+static void fb_event(struct XenLegacyDevice *xendev)
 {
     struct XenFB *xenfb = container_of(xendev, struct XenFB, c.xendev);
 
diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
index 935a3676c8..1d637639c7 100644
--- a/hw/i386/xen/xen-hvm.c
+++ b/hw/i386/xen/xen-hvm.c
@@ -16,7 +16,7 @@
 #include "hw/i386/pc.h"
 #include "hw/i386/apic-msidef.h"
 #include "hw/xen/xen_common.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "qapi/error.h"
 #include "qapi/qapi-commands-misc.h"
 #include "qemu/error-report.h"
diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
index 4e4f069a24..9134a7bfef 100644
--- a/hw/i386/xen/xen-mapcache.c
+++ b/hw/i386/xen/xen-mapcache.c
@@ -14,7 +14,7 @@
 
 #include <sys/resource.h>
 
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "qemu/bitmap.h"
 
 #include <xen/hvm/params.h>
diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c
index deb7a0c374..16afb54fee 100644
--- a/hw/i386/xen/xen_platform.c
+++ b/hw/i386/xen/xen_platform.c
@@ -30,7 +30,7 @@
 #include "hw/pci/pci.h"
 #include "hw/irq.h"
 #include "hw/xen/xen_common.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "trace.h"
 #include "exec/address-spaces.h"
 #include "sysemu/block-backend.h"
diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c
index 46a8dbfc90..37cda8e4be 100644
--- a/hw/net/xen_nic.c
+++ b/hw/net/xen_nic.c
@@ -28,14 +28,14 @@
 #include "net/net.h"
 #include "net/checksum.h"
 #include "net/util.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 
 #include <xen/io/netif.h>
 
 /* ------------------------------------------------------------- */
 
 struct XenNetDev {
-    struct XenDevice      xendev;  /* must be first */
+    struct XenLegacyDevice      xendev;  /* must be first */
     char                  *mac;
     int                   tx_work;
     int                   tx_ring_ref;
@@ -276,7 +276,7 @@ static NetClientInfo net_xen_info = {
     .receive = net_rx_packet,
 };
 
-static int net_init(struct XenDevice *xendev)
+static int net_init(struct XenLegacyDevice *xendev)
 {
     struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);
 
@@ -308,7 +308,7 @@ static int net_init(struct XenDevice *xendev)
     return 0;
 }
 
-static int net_connect(struct XenDevice *xendev)
+static int net_connect(struct XenLegacyDevice *xendev)
 {
     struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);
     int rx_copy;
@@ -363,7 +363,7 @@ static int net_connect(struct XenDevice *xendev)
     return 0;
 }
 
-static void net_disconnect(struct XenDevice *xendev)
+static void net_disconnect(struct XenLegacyDevice *xendev)
 {
     struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);
 
@@ -379,14 +379,14 @@ static void net_disconnect(struct XenDevice *xendev)
     }
 }
 
-static void net_event(struct XenDevice *xendev)
+static void net_event(struct XenLegacyDevice *xendev)
 {
     struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);
     net_tx_packets(netdev);
     qemu_flush_queued_packets(qemu_get_queue(netdev->nic));
 }
 
-static int net_free(struct XenDevice *xendev)
+static int net_free(struct XenLegacyDevice *xendev)
 {
     struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);
 
diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c
index 5b2e21ed18..9b2da6e75d 100644
--- a/hw/usb/xen-usb.c
+++ b/hw/usb/xen-usb.c
@@ -27,7 +27,7 @@
 #include "qemu/option.h"
 #include "hw/sysbus.h"
 #include "hw/usb.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "monitor/qdev.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qstring.h"
@@ -99,7 +99,7 @@ struct usbback_hotplug {
 };
 
 struct usbback_info {
-    struct XenDevice         xendev;  /* must be first */
+    struct XenLegacyDevice         xendev;  /* must be first */
     USBBus                   bus;
     void                     *urb_sring;
     void                     *conn_sring;
@@ -142,7 +142,7 @@ static int usbback_gnttab_map(struct usbback_req *usbback_req)
     unsigned int nr_segs, i, prot;
     uint32_t ref[USBIF_MAX_SEGMENTS_PER_REQUEST];
     struct usbback_info *usbif = usbback_req->usbif;
-    struct XenDevice *xendev = &usbif->xendev;
+    struct XenLegacyDevice *xendev = &usbif->xendev;
     struct usbif_request_segment *seg;
     void *addr;
 
@@ -220,7 +220,7 @@ static int usbback_gnttab_map(struct usbback_req *usbback_req)
 
 static int usbback_init_packet(struct usbback_req *usbback_req)
 {
-    struct XenDevice *xendev = &usbback_req->usbif->xendev;
+    struct XenLegacyDevice *xendev = &usbback_req->usbif->xendev;
     USBPacket *packet = &usbback_req->packet;
     USBDevice *dev = usbback_req->stub->dev;
     USBEndpoint *ep;
@@ -279,7 +279,7 @@ static void usbback_do_response(struct usbback_req *usbback_req, int32_t status,
 {
     struct usbback_info *usbif;
     struct usbif_urb_response *res;
-    struct XenDevice *xendev;
+    struct XenLegacyDevice *xendev;
     unsigned int notify;
 
     usbif = usbback_req->usbif;
@@ -824,7 +824,7 @@ static void usbback_process_port(struct usbback_info *usbif, unsigned port)
     g_free(busid);
 }
 
-static void usbback_disconnect(struct XenDevice *xendev)
+static void usbback_disconnect(struct XenLegacyDevice *xendev)
 {
     struct usbback_info *usbif;
     unsigned int i;
@@ -853,7 +853,7 @@ static void usbback_disconnect(struct XenDevice *xendev)
     TR_BUS(xendev, "finished\n");
 }
 
-static int usbback_connect(struct XenDevice *xendev)
+static int usbback_connect(struct XenLegacyDevice *xendev)
 {
     struct usbback_info *usbif;
     struct usbif_urb_sring *urb_sring;
@@ -909,7 +909,8 @@ static int usbback_connect(struct XenDevice *xendev)
     return 0;
 }
 
-static void usbback_backend_changed(struct XenDevice *xendev, const char *node)
+static void usbback_backend_changed(struct XenLegacyDevice *xendev,
+                                    const char *node)
 {
     struct usbback_info *usbif;
     unsigned int i;
@@ -922,7 +923,7 @@ static void usbback_backend_changed(struct XenDevice *xendev, const char *node)
     }
 }
 
-static int usbback_init(struct XenDevice *xendev)
+static int usbback_init(struct XenLegacyDevice *xendev)
 {
     struct usbback_info *usbif;
 
@@ -1001,7 +1002,7 @@ static USBPortOps xen_usb_port_ops = {
 static USBBusOps xen_usb_bus_ops = {
 };
 
-static void usbback_alloc(struct XenDevice *xendev)
+static void usbback_alloc(struct XenLegacyDevice *xendev)
 {
     struct usbback_info *usbif;
     USBPort *p;
@@ -1027,7 +1028,7 @@ static void usbback_alloc(struct XenDevice *xendev)
     xen_be_set_max_grant_refs(xendev, max_grants);
 }
 
-static int usbback_free(struct XenDevice *xendev)
+static int usbback_free(struct XenLegacyDevice *xendev)
 {
     struct usbback_info *usbif;
     struct usbback_req *usbback_req;
@@ -1066,7 +1067,7 @@ static int usbback_free(struct XenDevice *xendev)
     return 0;
 }
 
-static void usbback_event(struct XenDevice *xendev)
+static void usbback_event(struct XenLegacyDevice *xendev)
 {
     struct usbback_info *usbif;
 
diff --git a/hw/xen/Makefile.objs b/hw/xen/Makefile.objs
index 9ea5c73423..3f64a44051 100644
--- a/hw/xen/Makefile.objs
+++ b/hw/xen/Makefile.objs
@@ -1,5 +1,5 @@
 # xen backend driver support
-common-obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o xen_pvdev.o xen-common.o
+common-obj-$(CONFIG_XEN) += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o xen-common.o
 
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_graphics.o xen_pt_msi.o
diff --git a/hw/xen/xen-common.c b/hw/xen/xen-common.c
index 6ec14c73ca..ef130b2850 100644
--- a/hw/xen/xen-common.c
+++ b/hw/xen/xen-common.c
@@ -10,7 +10,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu/error-report.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "chardev/char.h"
 #include "sysemu/accel.h"
 #include "migration/misc.h"
diff --git a/hw/xen/xen_backend.c b/hw/xen/xen-legacy-backend.c
similarity index 89%
rename from hw/xen/xen_backend.c
rename to hw/xen/xen-legacy-backend.c
index 9a8e8771ec..2d748665a6 100644
--- a/hw/xen/xen_backend.c
+++ b/hw/xen/xen-legacy-backend.c
@@ -30,7 +30,7 @@
 #include "hw/boards.h"
 #include "qemu/log.h"
 #include "qapi/error.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "hw/xen/xen_pvdev.h"
 #include "monitor/qdev.h"
 
@@ -49,42 +49,47 @@ const char *xen_protocol;
 static bool xen_feature_grant_copy;
 static int debug;
 
-int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const char *val)
+int xenstore_write_be_str(struct XenLegacyDevice *xendev, const char *node,
+                          const char *val)
 {
     return xenstore_write_str(xendev->be, node, val);
 }
 
-int xenstore_write_be_int(struct XenDevice *xendev, const char *node, int ival)
+int xenstore_write_be_int(struct XenLegacyDevice *xendev, const char *node,
+                          int ival)
 {
     return xenstore_write_int(xendev->be, node, ival);
 }
 
-int xenstore_write_be_int64(struct XenDevice *xendev, const char *node, int64_t ival)
+int xenstore_write_be_int64(struct XenLegacyDevice *xendev, const char *node,
+                            int64_t ival)
 {
     return xenstore_write_int64(xendev->be, node, ival);
 }
 
-char *xenstore_read_be_str(struct XenDevice *xendev, const char *node)
+char *xenstore_read_be_str(struct XenLegacyDevice *xendev, const char *node)
 {
     return xenstore_read_str(xendev->be, node);
 }
 
-int xenstore_read_be_int(struct XenDevice *xendev, const char *node, int *ival)
+int xenstore_read_be_int(struct XenLegacyDevice *xendev, const char *node,
+                         int *ival)
 {
     return xenstore_read_int(xendev->be, node, ival);
 }
 
-char *xenstore_read_fe_str(struct XenDevice *xendev, const char *node)
+char *xenstore_read_fe_str(struct XenLegacyDevice *xendev, const char *node)
 {
     return xenstore_read_str(xendev->fe, node);
 }
 
-int xenstore_read_fe_int(struct XenDevice *xendev, const char *node, int *ival)
+int xenstore_read_fe_int(struct XenLegacyDevice *xendev, const char *node,
+                         int *ival)
 {
     return xenstore_read_int(xendev->fe, node, ival);
 }
 
-int xenstore_read_fe_uint64(struct XenDevice *xendev, const char *node,
+int xenstore_read_fe_uint64(struct XenLegacyDevice *xendev, const char *node,
                             uint64_t *uval)
 {
     return xenstore_read_uint64(xendev->fe, node, uval);
@@ -92,7 +97,7 @@ int xenstore_read_fe_uint64(struct XenDevice *xendev, const char *node,
 
 /* ------------------------------------------------------------- */
 
-int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state)
+int xen_be_set_state(struct XenLegacyDevice *xendev, enum xenbus_state state)
 {
     int rc;
 
@@ -106,7 +111,7 @@ int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state)
     return 0;
 }
 
-void xen_be_set_max_grant_refs(struct XenDevice *xendev,
+void xen_be_set_max_grant_refs(struct XenLegacyDevice *xendev,
                                unsigned int nr_refs)
 {
     assert(xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV);
@@ -117,7 +122,7 @@ void xen_be_set_max_grant_refs(struct XenDevice *xendev,
     }
 }
 
-void *xen_be_map_grant_refs(struct XenDevice *xendev, uint32_t *refs,
+void *xen_be_map_grant_refs(struct XenLegacyDevice *xendev, uint32_t *refs,
                             unsigned int nr_refs, int prot)
 {
     void *ptr;
@@ -135,7 +140,7 @@ void *xen_be_map_grant_refs(struct XenDevice *xendev, uint32_t *refs,
     return ptr;
 }
 
-void xen_be_unmap_grant_refs(struct XenDevice *xendev, void *ptr,
+void xen_be_unmap_grant_refs(struct XenLegacyDevice *xendev, void *ptr,
                              unsigned int nr_refs)
 {
     assert(xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV);
@@ -146,7 +151,7 @@ void xen_be_unmap_grant_refs(struct XenDevice *xendev, void *ptr,
     }
 }
 
-static int compat_copy_grant_refs(struct XenDevice *xendev,
+static int compat_copy_grant_refs(struct XenLegacyDevice *xendev,
                                   bool to_domain,
                                   XenGrantCopySegment segs[],
                                   unsigned int nr_segs)
@@ -195,7 +200,7 @@ static int compat_copy_grant_refs(struct XenDevice *xendev,
     return 0;
 }
 
-int xen_be_copy_grant_refs(struct XenDevice *xendev,
+int xen_be_copy_grant_refs(struct XenLegacyDevice *xendev,
                            bool to_domain,
                            XenGrantCopySegment segs[],
                            unsigned int nr_segs)
@@ -259,10 +264,11 @@ int xen_be_copy_grant_refs(struct XenDevice *xendev,
 /*
  * get xen backend device, allocate a new one if it doesn't exist.
  */
-static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
-                                           struct XenDevOps *ops)
+static struct XenLegacyDevice *xen_be_get_xendev(const char *type, int dom,
+                                                 int dev,
+                                                 struct XenDevOps *ops)
 {
-    struct XenDevice *xendev;
+    struct XenLegacyDevice *xendev;
 
     xendev = xen_pv_find_xendev(type, dom, dev);
     if (xendev) {
@@ -314,7 +320,8 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
  * Node specifies the changed field.  node = NULL means
  * update all fields (used for initialization).
  */
-static void xen_be_backend_changed(struct XenDevice *xendev, const char *node)
+static void xen_be_backend_changed(struct XenLegacyDevice *xendev,
+                                   const char *node)
 {
     if (node == NULL  ||  strcmp(node, "online") == 0) {
         if (xenstore_read_be_int(xendev, "online", &xendev->online) == -1) {
@@ -330,7 +337,8 @@ static void xen_be_backend_changed(struct XenDevice *xendev, const char *node)
     }
 }
 
-static void xen_be_frontend_changed(struct XenDevice *xendev, const char *node)
+static void xen_be_frontend_changed(struct XenLegacyDevice *xendev,
+                                    const char *node)
 {
     int fe_state;
 
@@ -373,7 +381,7 @@ static void xen_be_frontend_changed(struct XenDevice *xendev, const char *node)
  * only affects the xendev->be_state variable as xenbus should
  * already be put into that state by xend.
  */
-static int xen_be_try_setup(struct XenDevice *xendev)
+static int xen_be_try_setup(struct XenLegacyDevice *xendev)
 {
     char token[XEN_BUFSIZE];
     int be_state;
@@ -417,7 +425,7 @@ static int xen_be_try_setup(struct XenDevice *xendev)
  *
  * Goes to InitWait on success.
  */
-static int xen_be_try_init(struct XenDevice *xendev)
+static int xen_be_try_init(struct XenLegacyDevice *xendev)
 {
     int rc = 0;
 
@@ -446,7 +454,7 @@ static int xen_be_try_init(struct XenDevice *xendev)
  *
  * Goes to Connected on success.
  */
-static int xen_be_try_initialise(struct XenDevice *xendev)
+static int xen_be_try_initialise(struct XenLegacyDevice *xendev)
 {
     int rc = 0;
 
@@ -487,7 +495,7 @@ static int xen_be_try_initialise(struct XenDevice *xendev)
  * frontend being Connected.  Note that this may be called more
  * than once since the backend state is not modified.
  */
-static void xen_be_try_connected(struct XenDevice *xendev)
+static void xen_be_try_connected(struct XenLegacyDevice *xendev)
 {
     if (!xendev->ops->connected) {
         return;
@@ -510,7 +518,8 @@ static void xen_be_try_connected(struct XenDevice *xendev)
  *
  * Goes to Closed when done.
  */
-static void xen_be_disconnect(struct XenDevice *xendev, enum xenbus_state state)
+static void xen_be_disconnect(struct XenLegacyDevice *xendev,
+                              enum xenbus_state state)
 {
     if (xendev->be_state != XenbusStateClosing &&
         xendev->be_state != XenbusStateClosed  &&
@@ -529,7 +538,7 @@ static void xen_be_disconnect(struct XenDevice *xendev, enum xenbus_state state)
 /*
  * Try to reset xendev, for reconnection by another frontend instance.
  */
-static int xen_be_try_reset(struct XenDevice *xendev)
+static int xen_be_try_reset(struct XenLegacyDevice *xendev)
 {
     if (xendev->fe_state != XenbusStateInitialising) {
         return -1;
@@ -543,7 +552,7 @@ static int xen_be_try_reset(struct XenDevice *xendev)
 /*
  * state change dispatcher function
  */
-void xen_be_check_state(struct XenDevice *xendev)
+void xen_be_check_state(struct XenLegacyDevice *xendev)
 {
     int rc = 0;
 
@@ -587,7 +596,7 @@ void xen_be_check_state(struct XenDevice *xendev)
 
 static int xenstore_scan(const char *type, int dom, struct XenDevOps *ops)
 {
-    struct XenDevice *xendev;
+    struct XenLegacyDevice *xendev;
     char path[XEN_BUFSIZE], token[XEN_BUFSIZE];
     char **dev = NULL;
     unsigned int cdev, j;
@@ -620,7 +629,7 @@ static int xenstore_scan(const char *type, int dom, struct XenDevOps *ops)
 void xenstore_update_be(char *watch, char *type, int dom,
                         struct XenDevOps *ops)
 {
-    struct XenDevice *xendev;
+    struct XenLegacyDevice *xendev;
     char path[XEN_BUFSIZE], *bepath;
     unsigned int len, dev;
 
@@ -651,7 +660,7 @@ void xenstore_update_be(char *watch, char *type, int dom,
     }
 }
 
-void xenstore_update_fe(char *watch, struct XenDevice *xendev)
+void xenstore_update_fe(char *watch, struct XenLegacyDevice *xendev)
 {
     char *node;
     unsigned int len;
@@ -753,7 +762,7 @@ void xen_be_register_common(void)
 #endif
 }
 
-int xen_be_bind_evtchn(struct XenDevice *xendev)
+int xen_be_bind_evtchn(struct XenLegacyDevice *xendev)
 {
     if (xendev->local_port != -1) {
         return 0;
@@ -789,7 +798,7 @@ static const TypeInfo xendev_type_info = {
     .name          = TYPE_XENBACKEND,
     .parent        = TYPE_XENSYSDEV,
     .class_init    = xendev_class_init,
-    .instance_size = sizeof(struct XenDevice),
+    .instance_size = sizeof(struct XenLegacyDevice),
 };
 
 static void xen_sysbus_class_init(ObjectClass *klass, void *data)
diff --git a/hw/xen/xen_devconfig.c b/hw/xen/xen_devconfig.c
index aebc19bd71..1b30bd7691 100644
--- a/hw/xen/xen_devconfig.c
+++ b/hw/xen/xen_devconfig.c
@@ -1,5 +1,5 @@
 #include "qemu/osdep.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "qemu/option.h"
 #include "sysemu/blockdev.h"
 
diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
index f1f3a3727c..b20bf3a453 100644
--- a/hw/xen/xen_pt.c
+++ b/hw/xen/xen_pt.c
@@ -59,7 +59,7 @@
 #include "hw/pci/pci.h"
 #include "hw/xen/xen.h"
 #include "hw/i386/pc.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "xen_pt.h"
 #include "qemu/range.h"
 #include "exec/address-spaces.h"
diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
index 47f9010c75..81112049b6 100644
--- a/hw/xen/xen_pt_config_init.c
+++ b/hw/xen/xen_pt_config_init.c
@@ -15,7 +15,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qemu/timer.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "xen_pt.h"
 
 #define XEN_PT_MERGE_VALUE(value, data, val_mask) \
diff --git a/hw/xen/xen_pt_graphics.c b/hw/xen/xen_pt_graphics.c
index 135c8df1e7..130cc6cbf0 100644
--- a/hw/xen/xen_pt_graphics.c
+++ b/hw/xen/xen_pt_graphics.c
@@ -5,7 +5,7 @@
 #include "qapi/error.h"
 #include "xen_pt.h"
 #include "xen-host-pci-device.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 
 static unsigned long igd_guest_opregion;
 static unsigned long igd_host_opregion;
diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c
index cc514f9157..fb4b887b92 100644
--- a/hw/xen/xen_pt_msi.c
+++ b/hw/xen/xen_pt_msi.c
@@ -11,7 +11,7 @@
 
 #include "qemu/osdep.h"
 
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "xen_pt.h"
 #include "hw/i386/apic-msidef.h"
 
diff --git a/hw/xen/xen_pvdev.c b/hw/xen/xen_pvdev.c
index aed783e844..61de091002 100644
--- a/hw/xen/xen_pvdev.c
+++ b/hw/xen/xen_pvdev.c
@@ -20,7 +20,7 @@
 #include "qemu/osdep.h"
 #include "qemu/log.h"
 #include "hw/qdev-core.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "hw/xen/xen_pvdev.h"
 
 /* private */
@@ -34,7 +34,7 @@ struct xs_dirs {
 static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup =
     QTAILQ_HEAD_INITIALIZER(xs_cleanup);
 
-static QTAILQ_HEAD(XenDeviceHead, XenDevice) xendevs =
+static QTAILQ_HEAD(XenLegacyDeviceHead, XenLegacyDevice) xendevs =
     QTAILQ_HEAD_INITIALIZER(xendevs);
 
 /* ------------------------------------------------------------- */
@@ -195,7 +195,7 @@ const char *xenbus_strstate(enum xenbus_state state)
  *  2 == noisy debug messages (logfile only).
  *  3 == will flood your log (logfile only).
  */
-void xen_pv_printf(struct XenDevice *xendev, int msg_level,
+void xen_pv_printf(struct XenLegacyDevice *xendev, int msg_level,
                    const char *fmt, ...)
 {
     va_list args;
@@ -230,7 +230,7 @@ void xen_pv_printf(struct XenDevice *xendev, int msg_level,
 
 void xen_pv_evtchn_event(void *opaque)
 {
-    struct XenDevice *xendev = opaque;
+    struct XenLegacyDevice *xendev = opaque;
     evtchn_port_t port;
 
     port = xenevtchn_pending(xendev->evtchndev);
@@ -247,7 +247,7 @@ void xen_pv_evtchn_event(void *opaque)
     }
 }
 
-void xen_pv_unbind_evtchn(struct XenDevice *xendev)
+void xen_pv_unbind_evtchn(struct XenLegacyDevice *xendev)
 {
     if (xendev->local_port == -1) {
         return;
@@ -258,16 +258,16 @@ void xen_pv_unbind_evtchn(struct XenDevice *xendev)
     xendev->local_port = -1;
 }
 
-int xen_pv_send_notify(struct XenDevice *xendev)
+int xen_pv_send_notify(struct XenLegacyDevice *xendev)
 {
     return xenevtchn_notify(xendev->evtchndev, xendev->local_port);
 }
 
 /* ------------------------------------------------------------- */
 
-struct XenDevice *xen_pv_find_xendev(const char *type, int dom, int dev)
+struct XenLegacyDevice *xen_pv_find_xendev(const char *type, int dom, int dev)
 {
-    struct XenDevice *xendev;
+    struct XenLegacyDevice *xendev;
 
     QTAILQ_FOREACH(xendev, &xendevs, next) {
         if (xendev->dom != dom) {
@@ -287,7 +287,7 @@ struct XenDevice *xen_pv_find_xendev(const char *type, int dom, int dev)
 /*
  * release xen backend device.
  */
-void xen_pv_del_xendev(struct XenDevice *xendev)
+void xen_pv_del_xendev(struct XenLegacyDevice *xendev)
 {
     if (xendev->ops->free) {
         xendev->ops->free(xendev);
@@ -312,7 +312,7 @@ void xen_pv_del_xendev(struct XenDevice *xendev)
     qdev_unplug(&xendev->qdev, NULL);
 }
 
-void xen_pv_insert_xendev(struct XenDevice *xendev)
+void xen_pv_insert_xendev(struct XenLegacyDevice *xendev)
 {
     QTAILQ_INSERT_TAIL(&xendevs, xendev, next);
 }
diff --git a/hw/xenpv/xen_domainbuild.c b/hw/xenpv/xen_domainbuild.c
index 188acaca16..deb28cf596 100644
--- a/hw/xenpv/xen_domainbuild.c
+++ b/hw/xenpv/xen_domainbuild.c
@@ -1,6 +1,6 @@
 #include "qemu/osdep.h"
 #include "qemu/units.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "xen_domainbuild.h"
 #include "qemu/timer.h"
 #include "qemu/log.h"
diff --git a/hw/xenpv/xen_machine_pv.c b/hw/xenpv/xen_machine_pv.c
index 44d67b87c4..8c86fb7031 100644
--- a/hw/xenpv/xen_machine_pv.c
+++ b/hw/xenpv/xen_machine_pv.c
@@ -26,7 +26,7 @@
 #include "qemu/error-report.h"
 #include "hw/hw.h"
 #include "hw/boards.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "xen_domainbuild.h"
 #include "sysemu/block-backend.h"
 
diff --git a/include/hw/xen/xen_backend.h b/include/hw/xen/xen-legacy-backend.h
similarity index 61%
rename from include/hw/xen/xen_backend.h
rename to include/hw/xen/xen-legacy-backend.h
index 9c17fdd85d..20cb47b5bf 100644
--- a/include/hw/xen/xen_backend.h
+++ b/include/hw/xen/xen-legacy-backend.h
@@ -11,7 +11,7 @@
 #define TYPE_XENBACKEND "xen-backend"
 
 #define XENBACKEND_DEVICE(obj) \
-    OBJECT_CHECK(XenDevice, (obj), TYPE_XENBACKEND)
+    OBJECT_CHECK(XenLegacyDevice, (obj), TYPE_XENBACKEND)
 
 /* variables */
 extern struct xs_handle *xenstore;
@@ -20,32 +20,37 @@ extern DeviceState *xen_sysdev;
 extern BusState *xen_sysbus;
 
 int xenstore_mkdir(char *path, int p);
-int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const char *val);
-int xenstore_write_be_int(struct XenDevice *xendev, const char *node, int ival);
-int xenstore_write_be_int64(struct XenDevice *xendev, const char *node, int64_t ival);
-char *xenstore_read_be_str(struct XenDevice *xendev, const char *node);
-int xenstore_read_be_int(struct XenDevice *xendev, const char *node, int *ival);
-void xenstore_update_fe(char *watch, struct XenDevice *xendev);
+int xenstore_write_be_str(struct XenLegacyDevice *xendev, const char *node,
+                          const char *val);
+int xenstore_write_be_int(struct XenLegacyDevice *xendev, const char *node,
+                          int ival);
+int xenstore_write_be_int64(struct XenLegacyDevice *xendev, const char *node,
+                            int64_t ival);
+char *xenstore_read_be_str(struct XenLegacyDevice *xendev, const char *node);
+int xenstore_read_be_int(struct XenLegacyDevice *xendev, const char *node,
+                         int *ival);
+void xenstore_update_fe(char *watch, struct XenLegacyDevice *xendev);
 void xenstore_update_be(char *watch, char *type, int dom,
                         struct XenDevOps *ops);
-char *xenstore_read_fe_str(struct XenDevice *xendev, const char *node);
-int xenstore_read_fe_int(struct XenDevice *xendev, const char *node, int *ival);
-int xenstore_read_fe_uint64(struct XenDevice *xendev, const char *node,
+char *xenstore_read_fe_str(struct XenLegacyDevice *xendev, const char *node);
+int xenstore_read_fe_int(struct XenLegacyDevice *xendev, const char *node,
+                         int *ival);
+int xenstore_read_fe_uint64(struct XenLegacyDevice *xendev, const char *node,
                             uint64_t *uval);
 
-void xen_be_check_state(struct XenDevice *xendev);
+void xen_be_check_state(struct XenLegacyDevice *xendev);
 
 /* xen backend driver bits */
 int xen_be_init(void);
 void xen_be_register_common(void);
 int xen_be_register(const char *type, struct XenDevOps *ops);
-int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state);
-int xen_be_bind_evtchn(struct XenDevice *xendev);
-void xen_be_set_max_grant_refs(struct XenDevice *xendev,
+int xen_be_set_state(struct XenLegacyDevice *xendev, enum xenbus_state state);
+int xen_be_bind_evtchn(struct XenLegacyDevice *xendev);
+void xen_be_set_max_grant_refs(struct XenLegacyDevice *xendev,
                                unsigned int nr_refs);
-void *xen_be_map_grant_refs(struct XenDevice *xendev, uint32_t *refs,
+void *xen_be_map_grant_refs(struct XenLegacyDevice *xendev, uint32_t *refs,
                             unsigned int nr_refs, int prot);
-void xen_be_unmap_grant_refs(struct XenDevice *xendev, void *ptr,
+void xen_be_unmap_grant_refs(struct XenLegacyDevice *xendev, void *ptr,
                              unsigned int nr_refs);
 
 typedef struct XenGrantCopySegment {
@@ -59,17 +64,17 @@ typedef struct XenGrantCopySegment {
     size_t len;
 } XenGrantCopySegment;
 
-int xen_be_copy_grant_refs(struct XenDevice *xendev,
+int xen_be_copy_grant_refs(struct XenLegacyDevice *xendev,
                            bool to_domain, XenGrantCopySegment segs[],
                            unsigned int nr_segs);
 
-static inline void *xen_be_map_grant_ref(struct XenDevice *xendev,
+static inline void *xen_be_map_grant_ref(struct XenLegacyDevice *xendev,
                                          uint32_t ref, int prot)
 {
     return xen_be_map_grant_refs(xendev, &ref, 1, prot);
 }
 
-static inline void xen_be_unmap_grant_ref(struct XenDevice *xendev,
+static inline void xen_be_unmap_grant_ref(struct XenLegacyDevice *xendev,
                                           void *ptr)
 {
     return xen_be_unmap_grant_refs(xendev, ptr, 1);
diff --git a/include/hw/xen/xen_pvdev.h b/include/hw/xen/xen_pvdev.h
index d473e9b34d..83e5174d90 100644
--- a/include/hw/xen/xen_pvdev.h
+++ b/include/hw/xen/xen_pvdev.h
@@ -6,7 +6,7 @@
 
 #define XEN_BUFSIZE 1024
 
-struct XenDevice;
+struct XenLegacyDevice;
 
 /* driver uses grant tables  ->  open gntdev device (xendev->gnttabdev) */
 #define DEVOPS_FLAG_NEED_GNTDEV   1
@@ -16,19 +16,21 @@ struct XenDevice;
 struct XenDevOps {
     size_t    size;
     uint32_t  flags;
-    void      (*alloc)(struct XenDevice *xendev);
-    int       (*init)(struct XenDevice *xendev);
-    int       (*initialise)(struct XenDevice *xendev);
-    void      (*connected)(struct XenDevice *xendev);
-    void      (*event)(struct XenDevice *xendev);
-    void      (*disconnect)(struct XenDevice *xendev);
-    int       (*free)(struct XenDevice *xendev);
-    void      (*backend_changed)(struct XenDevice *xendev, const char *node);
-    void      (*frontend_changed)(struct XenDevice *xendev, const char *node);
+    void      (*alloc)(struct XenLegacyDevice *xendev);
+    int       (*init)(struct XenLegacyDevice *xendev);
+    int       (*initialise)(struct XenLegacyDevice *xendev);
+    void      (*connected)(struct XenLegacyDevice *xendev);
+    void      (*event)(struct XenLegacyDevice *xendev);
+    void      (*disconnect)(struct XenLegacyDevice *xendev);
+    int       (*free)(struct XenLegacyDevice *xendev);
+    void      (*backend_changed)(struct XenLegacyDevice *xendev,
+                                 const char *node);
+    void      (*frontend_changed)(struct XenLegacyDevice *xendev,
+                                  const char *node);
     int       (*backend_register)(void);
 };
 
-struct XenDevice {
+struct XenLegacyDevice {
     DeviceState        qdev;
     const char         *type;
     int                dom;
@@ -49,7 +51,7 @@ struct XenDevice {
     xengnttab_handle   *gnttabdev;
 
     struct XenDevOps   *ops;
-    QTAILQ_ENTRY(XenDevice) next;
+    QTAILQ_ENTRY(XenLegacyDevice) next;
 };
 
 /* ------------------------------------------------------------- */
@@ -66,14 +68,14 @@ void xenstore_update(void *unused);
 const char *xenbus_strstate(enum xenbus_state state);
 
 void xen_pv_evtchn_event(void *opaque);
-void xen_pv_insert_xendev(struct XenDevice *xendev);
-void xen_pv_del_xendev(struct XenDevice *xendev);
-struct XenDevice *xen_pv_find_xendev(const char *type, int dom, int dev);
+void xen_pv_insert_xendev(struct XenLegacyDevice *xendev);
+void xen_pv_del_xendev(struct XenLegacyDevice *xendev);
+struct XenLegacyDevice *xen_pv_find_xendev(const char *type, int dom, int dev);
 
-void xen_pv_unbind_evtchn(struct XenDevice *xendev);
-int xen_pv_send_notify(struct XenDevice *xendev);
+void xen_pv_unbind_evtchn(struct XenLegacyDevice *xendev);
+int xen_pv_send_notify(struct XenLegacyDevice *xendev);
 
-void xen_pv_printf(struct XenDevice *xendev, int msg_level,
+void xen_pv_printf(struct XenLegacyDevice *xendev, int msg_level,
                    const char *fmt, ...)  GCC_FMT_ATTR(3, 4);
 
 #endif /* QEMU_HW_XEN_PVDEV_H */
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [Qemu-devel] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
  2018-11-21 15:11   ` Paul Durrant
@ 2018-11-21 15:11 ` Paul Durrant
  2018-11-28 16:19   ` [Qemu-block] " Kevin Wolf
                     ` (2 more replies)
  2018-11-21 15:11 ` Paul Durrant
                   ` (23 subsequent siblings)
  25 siblings, 3 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:11 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Paul Durrant, Stefano Stabellini, Anthony Perard,
	Michael S. Tsirkin, Marcel Apfelbaum, Paolo Bonzini,
	Richard Henderson, Eduardo Habkost

This patch adds the basic boilerplate for a 'XenBus' object that will act
as a parent to 'XenDevice' PV backends.
A new 'XenBridge' object is also added to connect XenBus to the system bus.

The XenBus object is instantiated by a new xen_bus_init() function called
from the same sites as the legacy xen_be_init() function.

Subsequent patches will flesh-out the functionality of these objects.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Eduardo Habkost <ehabkost@redhat.com>
---
 hw/i386/xen/xen-hvm.c     |   3 ++
 hw/xen/Makefile.objs      |   2 +-
 hw/xen/trace-events       |   6 +++
 hw/xen/xen-bus.c          | 125 ++++++++++++++++++++++++++++++++++++++++++++++
 hw/xenpv/xen_machine_pv.c |   3 ++
 include/hw/xen/xen-bus.h  |  53 ++++++++++++++++++++
 6 files changed, 191 insertions(+), 1 deletion(-)
 create mode 100644 hw/xen/xen-bus.c
 create mode 100644 include/hw/xen/xen-bus.h

diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
index 1d637639c7..4497f751d2 100644
--- a/hw/i386/xen/xen-hvm.c
+++ b/hw/i386/xen/xen-hvm.c
@@ -17,6 +17,7 @@
 #include "hw/i386/apic-msidef.h"
 #include "hw/xen/xen_common.h"
 #include "hw/xen/xen-legacy-backend.h"
+#include "hw/xen/xen-bus.h"
 #include "qapi/error.h"
 #include "qapi/qapi-commands-misc.h"
 #include "qemu/error-report.h"
@@ -1479,6 +1480,8 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
     QLIST_INIT(&state->dev_list);
     device_listener_register(&state->device_listener);
 
+    xen_bus_init();
+
     /* Initialize backend core & drivers */
     if (xen_be_init() != 0) {
         error_report("xen backend core setup failed");
diff --git a/hw/xen/Makefile.objs b/hw/xen/Makefile.objs
index 3f64a44051..d9d6d7b4f9 100644
--- a/hw/xen/Makefile.objs
+++ b/hw/xen/Makefile.objs
@@ -1,5 +1,5 @@
 # xen backend driver support
-common-obj-$(CONFIG_XEN) += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o xen-common.o
+common-obj-$(CONFIG_XEN) += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o xen-common.o xen-bus.o
 
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_graphics.o xen_pt_msi.o
diff --git a/hw/xen/trace-events b/hw/xen/trace-events
index c7e7a3b523..0172cd4e26 100644
--- a/hw/xen/trace-events
+++ b/hw/xen/trace-events
@@ -12,3 +12,9 @@ xen_unmap_portio_range(uint32_t id, uint64_t start_addr, uint64_t end_addr) "id:
 xen_map_pcidev(uint32_t id, uint8_t bus, uint8_t dev, uint8_t func) "id: %u bdf: %02x.%02x.%02x"
 xen_unmap_pcidev(uint32_t id, uint8_t bus, uint8_t dev, uint8_t func) "id: %u bdf: %02x.%02x.%02x"
 xen_domid_restrict(int err) "err: %u"
+
+# include/hw/xen/xen-bus.c
+xen_bus_realize(void) ""
+xen_bus_unrealize(void) ""
+xen_device_realize(const char *type) "type: %s"
+xen_device_unrealize(const char *type) "type: %s"
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
new file mode 100644
index 0000000000..dede2d914a
--- /dev/null
+++ b/hw/xen/xen-bus.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "hw/sysbus.h"
+#include "hw/xen/xen-bus.h"
+#include "qapi/error.h"
+#include "trace.h"
+
+static void xen_bus_unrealize(BusState *bus, Error **errp)
+{
+    trace_xen_bus_unrealize();
+}
+
+static void xen_bus_realize(BusState *bus, Error **errp)
+{
+    trace_xen_bus_realize();
+}
+
+static void xen_bus_class_init(ObjectClass *class, void *data)
+{
+    BusClass *bus_class = BUS_CLASS(class);
+
+    bus_class->realize = xen_bus_realize;
+    bus_class->unrealize = xen_bus_unrealize;
+}
+
+static const TypeInfo xen_bus_type_info = {
+    .name = TYPE_XEN_BUS,
+    .parent = TYPE_BUS,
+    .instance_size = sizeof(XenBus),
+    .class_size = sizeof(XenBusClass),
+    .class_init = xen_bus_class_init,
+};
+
+static void xen_device_unrealize(DeviceState *dev, Error **errp)
+{
+    XenDevice *xendev = XEN_DEVICE(dev);
+    XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
+    const char *type = object_get_typename(OBJECT(xendev));
+    Error *local_err = NULL;
+
+    trace_xen_device_unrealize(type);
+
+    if (xendev_class->unrealize) {
+        xendev_class->unrealize(xendev, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            return;
+        }
+    }
+}
+
+static void xen_device_realize(DeviceState *dev, Error **errp)
+{
+    XenDevice *xendev = XEN_DEVICE(dev);
+    XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
+    const char *type = object_get_typename(OBJECT(xendev));
+    Error *local_err = NULL;
+
+    trace_xen_device_realize(type);
+
+    if (xendev_class->realize) {
+        xendev_class->realize(xendev, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            goto unrealize;
+        }
+    }
+
+    return;
+
+unrealize:
+    xen_device_unrealize(dev, &error_abort);
+}
+
+static void xen_device_class_init(ObjectClass *class, void *data)
+{
+    DeviceClass *dev_class = DEVICE_CLASS(class);
+
+    dev_class->realize = xen_device_realize;
+    dev_class->unrealize = xen_device_unrealize;
+    dev_class->bus_type = TYPE_XEN_BUS;
+}
+
+static const TypeInfo xen_device_type_info = {
+    .name = TYPE_XEN_DEVICE,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(XenDevice),
+    .abstract = true,
+    .class_size = sizeof(XenDeviceClass),
+    .class_init = xen_device_class_init,
+};
+
+typedef struct XenBridge {
+    SysBusDevice busdev;
+} XenBridge;
+
+#define TYPE_XEN_BRIDGE "xen-bridge"
+
+static const TypeInfo xen_bridge_type_info = {
+    .name = TYPE_XEN_BRIDGE,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(XenBridge),
+};
+
+static void xen_register_types(void)
+{
+    type_register_static(&xen_bridge_type_info);
+    type_register_static(&xen_bus_type_info);
+    type_register_static(&xen_device_type_info);
+}
+
+type_init(xen_register_types)
+
+void xen_bus_init(void)
+{
+    DeviceState *dev = qdev_create(NULL, TYPE_XEN_BRIDGE);
+
+    qbus_create(TYPE_XEN_BUS, dev, NULL);
+    qdev_init_nofail(dev);
+}
diff --git a/hw/xenpv/xen_machine_pv.c b/hw/xenpv/xen_machine_pv.c
index 8c86fb7031..608e591bcc 100644
--- a/hw/xenpv/xen_machine_pv.c
+++ b/hw/xenpv/xen_machine_pv.c
@@ -27,6 +27,7 @@
 #include "hw/hw.h"
 #include "hw/boards.h"
 #include "hw/xen/xen-legacy-backend.h"
+#include "hw/xen/xen-bus.h"
 #include "xen_domainbuild.h"
 #include "sysemu/block-backend.h"
 
@@ -93,6 +94,8 @@ static void xen_init_pv(MachineState *machine)
         xen_config_dev_nic(nd_table + i);
     }
 
+    xen_bus_init();
+
     /* config cleanup hook */
     atexit(xen_config_cleanup);
 }
diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h
new file mode 100644
index 0000000000..41772dc73a
--- /dev/null
+++ b/include/hw/xen/xen-bus.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ */
+
+#ifndef HW_XEN_BUS_H
+#define HW_XEN_BUS_H
+
+#include "hw/sysbus.h"
+
+typedef struct XenDevice {
+    DeviceState qdev;
+} XenDevice;
+
+typedef void (*XenDeviceRealize)(XenDevice *xendev, Error **errp);
+typedef void (*XenDeviceUnrealize)(XenDevice *xendev, Error **errp);
+
+typedef struct XenDeviceClass {
+    /*< private >*/
+    DeviceClass parent_class;
+    /*< public >*/
+    XenDeviceRealize realize;
+    XenDeviceUnrealize unrealize;
+} XenDeviceClass;
+
+#define TYPE_XEN_DEVICE "xen-device"
+#define XEN_DEVICE(obj) \
+     OBJECT_CHECK(XenDevice, (obj), TYPE_XEN_DEVICE)
+#define XEN_DEVICE_CLASS(class) \
+     OBJECT_CLASS_CHECK(XenDeviceClass, (class), TYPE_XEN_DEVICE)
+#define XEN_DEVICE_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(XenDeviceClass, (obj), TYPE_XEN_DEVICE)
+
+typedef struct XenBus {
+    BusState qbus;
+} XenBus;
+
+typedef struct XenBusClass {
+    /*< private >*/
+    BusClass parent_class;
+} XenBusClass;
+
+#define TYPE_XEN_BUS "xen-bus"
+#define XEN_BUS(obj) \
+    OBJECT_CHECK(XenBus, (obj), TYPE_XEN_BUS)
+#define XEN_BUS_CLASS(class) \
+    OBJECT_CLASS_CHECK(XenBusClass, (class), TYPE_XEN_BUS)
+#define XEN_BUS_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(XenBusClass, (obj), TYPE_XEN_BUS)
+
+void xen_bus_init(void);
+
+#endif /* HW_XEN_BUS_H */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
  2018-11-21 15:11   ` Paul Durrant
  2018-11-21 15:11 ` [Qemu-devel] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy Paul Durrant
@ 2018-11-21 15:11 ` Paul Durrant
  2018-11-21 15:11 ` [PATCH 03/18] xen: introduce 'xen-qdisk' Paul Durrant
                   ` (22 subsequent siblings)
  25 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:11 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Stefano Stabellini, Eduardo Habkost, Michael S. Tsirkin,
	Paul Durrant, Marcel Apfelbaum, Anthony Perard, Paolo Bonzini,
	Richard Henderson

This patch adds the basic boilerplate for a 'XenBus' object that will act
as a parent to 'XenDevice' PV backends.
A new 'XenBridge' object is also added to connect XenBus to the system bus.

The XenBus object is instantiated by a new xen_bus_init() function called
from the same sites as the legacy xen_be_init() function.

Subsequent patches will flesh-out the functionality of these objects.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Eduardo Habkost <ehabkost@redhat.com>
---
 hw/i386/xen/xen-hvm.c     |   3 ++
 hw/xen/Makefile.objs      |   2 +-
 hw/xen/trace-events       |   6 +++
 hw/xen/xen-bus.c          | 125 ++++++++++++++++++++++++++++++++++++++++++++++
 hw/xenpv/xen_machine_pv.c |   3 ++
 include/hw/xen/xen-bus.h  |  53 ++++++++++++++++++++
 6 files changed, 191 insertions(+), 1 deletion(-)
 create mode 100644 hw/xen/xen-bus.c
 create mode 100644 include/hw/xen/xen-bus.h

diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
index 1d637639c7..4497f751d2 100644
--- a/hw/i386/xen/xen-hvm.c
+++ b/hw/i386/xen/xen-hvm.c
@@ -17,6 +17,7 @@
 #include "hw/i386/apic-msidef.h"
 #include "hw/xen/xen_common.h"
 #include "hw/xen/xen-legacy-backend.h"
+#include "hw/xen/xen-bus.h"
 #include "qapi/error.h"
 #include "qapi/qapi-commands-misc.h"
 #include "qemu/error-report.h"
@@ -1479,6 +1480,8 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
     QLIST_INIT(&state->dev_list);
     device_listener_register(&state->device_listener);
 
+    xen_bus_init();
+
     /* Initialize backend core & drivers */
     if (xen_be_init() != 0) {
         error_report("xen backend core setup failed");
diff --git a/hw/xen/Makefile.objs b/hw/xen/Makefile.objs
index 3f64a44051..d9d6d7b4f9 100644
--- a/hw/xen/Makefile.objs
+++ b/hw/xen/Makefile.objs
@@ -1,5 +1,5 @@
 # xen backend driver support
-common-obj-$(CONFIG_XEN) += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o xen-common.o
+common-obj-$(CONFIG_XEN) += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o xen-common.o xen-bus.o
 
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_graphics.o xen_pt_msi.o
diff --git a/hw/xen/trace-events b/hw/xen/trace-events
index c7e7a3b523..0172cd4e26 100644
--- a/hw/xen/trace-events
+++ b/hw/xen/trace-events
@@ -12,3 +12,9 @@ xen_unmap_portio_range(uint32_t id, uint64_t start_addr, uint64_t end_addr) "id:
 xen_map_pcidev(uint32_t id, uint8_t bus, uint8_t dev, uint8_t func) "id: %u bdf: %02x.%02x.%02x"
 xen_unmap_pcidev(uint32_t id, uint8_t bus, uint8_t dev, uint8_t func) "id: %u bdf: %02x.%02x.%02x"
 xen_domid_restrict(int err) "err: %u"
+
+# include/hw/xen/xen-bus.c
+xen_bus_realize(void) ""
+xen_bus_unrealize(void) ""
+xen_device_realize(const char *type) "type: %s"
+xen_device_unrealize(const char *type) "type: %s"
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
new file mode 100644
index 0000000000..dede2d914a
--- /dev/null
+++ b/hw/xen/xen-bus.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "hw/sysbus.h"
+#include "hw/xen/xen-bus.h"
+#include "qapi/error.h"
+#include "trace.h"
+
+static void xen_bus_unrealize(BusState *bus, Error **errp)
+{
+    trace_xen_bus_unrealize();
+}
+
+static void xen_bus_realize(BusState *bus, Error **errp)
+{
+    trace_xen_bus_realize();
+}
+
+static void xen_bus_class_init(ObjectClass *class, void *data)
+{
+    BusClass *bus_class = BUS_CLASS(class);
+
+    bus_class->realize = xen_bus_realize;
+    bus_class->unrealize = xen_bus_unrealize;
+}
+
+static const TypeInfo xen_bus_type_info = {
+    .name = TYPE_XEN_BUS,
+    .parent = TYPE_BUS,
+    .instance_size = sizeof(XenBus),
+    .class_size = sizeof(XenBusClass),
+    .class_init = xen_bus_class_init,
+};
+
+static void xen_device_unrealize(DeviceState *dev, Error **errp)
+{
+    XenDevice *xendev = XEN_DEVICE(dev);
+    XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
+    const char *type = object_get_typename(OBJECT(xendev));
+    Error *local_err = NULL;
+
+    trace_xen_device_unrealize(type);
+
+    if (xendev_class->unrealize) {
+        xendev_class->unrealize(xendev, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            return;
+        }
+    }
+}
+
+static void xen_device_realize(DeviceState *dev, Error **errp)
+{
+    XenDevice *xendev = XEN_DEVICE(dev);
+    XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
+    const char *type = object_get_typename(OBJECT(xendev));
+    Error *local_err = NULL;
+
+    trace_xen_device_realize(type);
+
+    if (xendev_class->realize) {
+        xendev_class->realize(xendev, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            goto unrealize;
+        }
+    }
+
+    return;
+
+unrealize:
+    xen_device_unrealize(dev, &error_abort);
+}
+
+static void xen_device_class_init(ObjectClass *class, void *data)
+{
+    DeviceClass *dev_class = DEVICE_CLASS(class);
+
+    dev_class->realize = xen_device_realize;
+    dev_class->unrealize = xen_device_unrealize;
+    dev_class->bus_type = TYPE_XEN_BUS;
+}
+
+static const TypeInfo xen_device_type_info = {
+    .name = TYPE_XEN_DEVICE,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(XenDevice),
+    .abstract = true,
+    .class_size = sizeof(XenDeviceClass),
+    .class_init = xen_device_class_init,
+};
+
+typedef struct XenBridge {
+    SysBusDevice busdev;
+} XenBridge;
+
+#define TYPE_XEN_BRIDGE "xen-bridge"
+
+static const TypeInfo xen_bridge_type_info = {
+    .name = TYPE_XEN_BRIDGE,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(XenBridge),
+};
+
+static void xen_register_types(void)
+{
+    type_register_static(&xen_bridge_type_info);
+    type_register_static(&xen_bus_type_info);
+    type_register_static(&xen_device_type_info);
+}
+
+type_init(xen_register_types)
+
+void xen_bus_init(void)
+{
+    DeviceState *dev = qdev_create(NULL, TYPE_XEN_BRIDGE);
+
+    qbus_create(TYPE_XEN_BUS, dev, NULL);
+    qdev_init_nofail(dev);
+}
diff --git a/hw/xenpv/xen_machine_pv.c b/hw/xenpv/xen_machine_pv.c
index 8c86fb7031..608e591bcc 100644
--- a/hw/xenpv/xen_machine_pv.c
+++ b/hw/xenpv/xen_machine_pv.c
@@ -27,6 +27,7 @@
 #include "hw/hw.h"
 #include "hw/boards.h"
 #include "hw/xen/xen-legacy-backend.h"
+#include "hw/xen/xen-bus.h"
 #include "xen_domainbuild.h"
 #include "sysemu/block-backend.h"
 
@@ -93,6 +94,8 @@ static void xen_init_pv(MachineState *machine)
         xen_config_dev_nic(nd_table + i);
     }
 
+    xen_bus_init();
+
     /* config cleanup hook */
     atexit(xen_config_cleanup);
 }
diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h
new file mode 100644
index 0000000000..41772dc73a
--- /dev/null
+++ b/include/hw/xen/xen-bus.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ */
+
+#ifndef HW_XEN_BUS_H
+#define HW_XEN_BUS_H
+
+#include "hw/sysbus.h"
+
+typedef struct XenDevice {
+    DeviceState qdev;
+} XenDevice;
+
+typedef void (*XenDeviceRealize)(XenDevice *xendev, Error **errp);
+typedef void (*XenDeviceUnrealize)(XenDevice *xendev, Error **errp);
+
+typedef struct XenDeviceClass {
+    /*< private >*/
+    DeviceClass parent_class;
+    /*< public >*/
+    XenDeviceRealize realize;
+    XenDeviceUnrealize unrealize;
+} XenDeviceClass;
+
+#define TYPE_XEN_DEVICE "xen-device"
+#define XEN_DEVICE(obj) \
+     OBJECT_CHECK(XenDevice, (obj), TYPE_XEN_DEVICE)
+#define XEN_DEVICE_CLASS(class) \
+     OBJECT_CLASS_CHECK(XenDeviceClass, (class), TYPE_XEN_DEVICE)
+#define XEN_DEVICE_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(XenDeviceClass, (obj), TYPE_XEN_DEVICE)
+
+typedef struct XenBus {
+    BusState qbus;
+} XenBus;
+
+typedef struct XenBusClass {
+    /*< private >*/
+    BusClass parent_class;
+} XenBusClass;
+
+#define TYPE_XEN_BUS "xen-bus"
+#define XEN_BUS(obj) \
+    OBJECT_CHECK(XenBus, (obj), TYPE_XEN_BUS)
+#define XEN_BUS_CLASS(class) \
+    OBJECT_CLASS_CHECK(XenBusClass, (class), TYPE_XEN_BUS)
+#define XEN_BUS_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(XenBusClass, (obj), TYPE_XEN_BUS)
+
+void xen_bus_init(void);
+
+#endif /* HW_XEN_BUS_H */
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [Qemu-devel] [PATCH 03/18] xen: introduce 'xen-qdisk'
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
                   ` (3 preceding siblings ...)
  2018-11-21 15:11 ` [PATCH 03/18] xen: introduce 'xen-qdisk' Paul Durrant
@ 2018-11-21 15:11 ` Paul Durrant
  2018-11-29 16:05   ` Anthony PERARD
  2018-11-29 16:05   ` [Qemu-devel] " Anthony PERARD
  2018-11-21 15:11 ` [Qemu-devel] [PATCH 04/18] xen: create xenstore areas for XenDevice-s Paul Durrant
                   ` (20 subsequent siblings)
  25 siblings, 2 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:11 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Paul Durrant, Kevin Wolf, Max Reitz, Stefano Stabellini, Anthony Perard

This patch adds a new XenDevice: 'xen-qdisk' [1]. This will eventually
replace the 'xen_disk' legacy PV backend but it is illustrative to build
up the implementation incrementally, along with the XenBus/XenDevice
framework. Subsequent patches will therefore add to this device's
implementation as new features are added to the framework.

After this patch has been applied it is possible to instantiate a new
'xen-qdisk' device with a single 'vdev' parameter, which accepts values
adhering to the Xen VBD naming scheme [2]. For example, a command-line
instantiation of a xen-qdisk can be done with an argument similar to the
following:

-device xen-qdisk,vdev=hda

The implementation of the vdev parameter formulates the appropriate VBD
number for use in the PV protocol.

[1] The name 'qdisk' as always been the name given to the QEMU
    implementation of the Xen PV block protocol backend implementation
[2] http://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=docs/man/xen-vbd-interface.markdown.7

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
---
 MAINTAINERS                |   2 +-
 hw/block/Makefile.objs     |   1 +
 hw/block/trace-events      |   4 +
 hw/block/xen-qdisk.c       | 256 +++++++++++++++++++++++++++++++++++++++++++++
 include/hw/xen/xen-qdisk.h |  38 +++++++
 5 files changed, 300 insertions(+), 1 deletion(-)
 create mode 100644 hw/block/xen-qdisk.c
 create mode 100644 include/hw/xen/xen-qdisk.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 1032406c56..10f048a503 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -389,7 +389,7 @@ F: hw/9pfs/xen-9p-backend.c
 F: hw/char/xen_console.c
 F: hw/display/xenfb.c
 F: hw/net/xen_nic.c
-F: hw/block/xen_*
+F: hw/block/xen*
 F: hw/xen/
 F: hw/xenpv/
 F: hw/i386/xen/
diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs
index 53ce5751ae..bcdd36d318 100644
--- a/hw/block/Makefile.objs
+++ b/hw/block/Makefile.objs
@@ -5,6 +5,7 @@ common-obj-$(CONFIG_NAND) += nand.o
 common-obj-$(CONFIG_PFLASH_CFI01) += pflash_cfi01.o
 common-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
 common-obj-$(CONFIG_XEN) += xen_disk.o
+common-obj-$(CONFIG_XEN) += xen-qdisk.o
 common-obj-$(CONFIG_ECC) += ecc.o
 common-obj-$(CONFIG_ONENAND) += onenand.o
 common-obj-$(CONFIG_NVME_PCI) += nvme.o
diff --git a/hw/block/trace-events b/hw/block/trace-events
index 335c092450..fd3c126ac1 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -127,3 +127,7 @@ xen_disk_init(char *name) "%s"
 xen_disk_connect(char *name) "%s"
 xen_disk_disconnect(char *name) "%s"
 xen_disk_free(char *name) "%s"
+
+# hw/block/xen-qdisk.c
+xen_qdisk_realize(uint32_t disk, uint32_t partition) "d%up%u"
+xen_qdisk_unrealize(uint32_t disk, uint32_t partition) "d%up%u"
diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
new file mode 100644
index 0000000000..72122073f7
--- /dev/null
+++ b/hw/block/xen-qdisk.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/cutils.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+#include "hw/hw.h"
+#include "hw/xen/xen-qdisk.h"
+#include "trace.h"
+
+static void xen_qdisk_realize(XenDevice *xendev, Error **errp)
+{
+    XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
+    XenQdiskVdev *vdev = &qdiskdev->vdev;
+
+    if (!vdev->valid) {
+        error_setg(errp, "vdev property not set");
+        return;
+    }
+
+    trace_xen_qdisk_realize(vdev->disk, vdev->partition);
+}
+
+static void xen_qdisk_unrealize(XenDevice *xendev, Error **errp)
+{
+    XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
+    XenQdiskVdev *vdev = &qdiskdev->vdev;
+
+    trace_xen_qdisk_unrealize(vdev->disk, vdev->partition);
+}
+
+static char *disk_to_vbd_name(unsigned int disk)
+{
+    unsigned int len = DIV_ROUND_UP(disk, 26);
+    char *name = g_malloc0(len + 1);
+
+    do {
+        name[len--] = 'a' + (disk % 26);
+        disk /= 26;
+    } while (disk != 0);
+    assert(len == 0);
+
+    return name;
+}
+
+static void xen_qdisk_get_vdev(Object *obj, Visitor *v, const char *name,
+                               void *opaque, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    XenQdiskVdev *vdev = qdev_get_prop_ptr(dev, prop);
+    char *str;
+
+    switch (vdev->type) {
+    case XEN_QDISK_VDEV_TYPE_DP:
+        str = g_strdup_printf("d%lup%lu", vdev->disk, vdev->partition);
+        break;
+
+    case XEN_QDISK_VDEV_TYPE_XVD:
+    case XEN_QDISK_VDEV_TYPE_HD:
+    case XEN_QDISK_VDEV_TYPE_SD: {
+        char *name = disk_to_vbd_name(vdev->disk);
+
+        str = g_strdup_printf("%s%s%lu",
+                              (vdev->type == XEN_QDISK_VDEV_TYPE_XVD) ?
+                              "xvd" :
+                              (vdev->type == XEN_QDISK_VDEV_TYPE_HD) ?
+                              "hd" :
+                              "sd",
+                              name, vdev->partition);
+        g_free(name);
+        break;
+    }
+    default:
+        error_setg(errp, "invalid vdev type");
+        return;
+    }
+
+    visit_type_str(v, name, &str, errp);
+    g_free(str);
+}
+
+static unsigned int vbd_name_to_disk(const char *name, const char **endp)
+{
+    unsigned int disk = 0;
+
+    while (*name != '\0') {
+        if (!g_ascii_isalpha(*name) || !g_ascii_islower(*name)) {
+            break;
+        }
+
+        disk *= 26;
+        disk += *name++ - 'a';
+    }
+    *endp = name;
+
+    return disk;
+}
+
+static void xen_qdisk_set_vdev(Object *obj, Visitor *v, const char *name,
+                               void *opaque, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    XenQdiskVdev *vdev = qdev_get_prop_ptr(dev, prop);
+    Error *local_err = NULL;
+    char *str, *p;
+    const char *end;
+
+    if (dev->realized) {
+        qdev_prop_set_after_realize(dev, name, errp);
+        return;
+    }
+
+    visit_type_str(v, name, &str, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    p = strchr(str, 'd');
+    if (!p) {
+        goto invalid;
+    }
+
+    *p++ = '\0';
+    if (*str == '\0') {
+        vdev->type = XEN_QDISK_VDEV_TYPE_DP;
+    } else if (strcmp(str, "xv") == 0) {
+        vdev->type = XEN_QDISK_VDEV_TYPE_XVD;
+    } else if (strcmp(str, "h") == 0) {
+        vdev->type = XEN_QDISK_VDEV_TYPE_HD;
+    } else if (strcmp(str, "s") == 0) {
+        vdev->type = XEN_QDISK_VDEV_TYPE_SD;
+    } else {
+        goto invalid;
+    }
+
+    if (vdev->type == XEN_QDISK_VDEV_TYPE_DP) {
+        if (qemu_strtoul(p, &end, 10, &vdev->disk)) {
+            goto invalid;
+        }
+
+        if (*end == 'p') {
+            p = (char *) ++end;
+            if (*end == '\0') {
+                goto invalid;
+            }
+        }
+    } else {
+        vdev->disk = vbd_name_to_disk(p, &end);
+    }
+
+    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_QDISK_VDEV_TYPE_DP:
+    case XEN_QDISK_VDEV_TYPE_XVD:
+        if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) {
+            vdev->number = (202 << 8) | (vdev->disk << 4) |
+                vdev->partition;
+        } else if (vdev->disk < (1 << 20) && vdev->partition < (1 << 8)) {
+            vdev->number = (1 << 28) | (vdev->disk << 8) |
+                vdev->partition;
+        } else {
+            goto invalid;
+        }
+        break;
+
+    case XEN_QDISK_VDEV_TYPE_HD:
+        if ((vdev->disk == 0 || vdev->disk == 1) &&
+            vdev->partition < (1 << 4)) {
+            vdev->number = (3 << 8) | (vdev->disk << 6) | vdev->partition;
+        } else if ((vdev->disk == 2 || vdev->disk == 3) &&
+                   vdev->partition < (1 << 4)) {
+            vdev->number = (22 << 8) | ((vdev->disk - 2) << 6) |
+                vdev->partition;
+        } else {
+            goto invalid;
+        }
+        break;
+
+    case XEN_QDISK_VDEV_TYPE_SD:
+        if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) {
+            vdev->number = (8 << 8) | (vdev->disk << 4) | vdev->partition;
+        } else {
+            goto invalid;
+        }
+        break;
+
+    default:
+        goto invalid;
+    }
+
+    g_free(str);
+    vdev->valid = true;
+    return;
+
+invalid:
+    error_setg(errp, "invalid virtual disk specifier");
+    g_free(str);
+}
+
+const PropertyInfo xen_qdisk_prop_vdev = {
+    .name  = "str",
+    .description = "Virtual Disk specifier: d*p*/xvd*/hd*/sd*",
+    .get = xen_qdisk_get_vdev,
+    .set = xen_qdisk_set_vdev,
+};
+
+static Property xen_qdisk_props[] = {
+    DEFINE_PROP("vdev", XenQdiskDevice, vdev,
+                xen_qdisk_prop_vdev, XenQdiskVdev),
+    DEFINE_PROP_END_OF_LIST()
+};
+
+static void xen_qdisk_class_init(ObjectClass *class, void *data)
+{
+    DeviceClass *dev_class = DEVICE_CLASS(class);
+    XenDeviceClass *xendev_class = XEN_DEVICE_CLASS(class);
+
+    xendev_class->realize = xen_qdisk_realize;
+    xendev_class->unrealize = xen_qdisk_unrealize;
+
+    dev_class->desc = "Xen Qdisk Device";
+    dev_class->props = xen_qdisk_props;
+}
+
+static const TypeInfo xen_qdisk_type_info = {
+    .name = TYPE_XEN_QDISK_DEVICE,
+    .parent = TYPE_XEN_DEVICE,
+    .instance_size = sizeof(XenQdiskDevice),
+    .class_init = xen_qdisk_class_init,
+};
+
+static void xen_qdisk_register_types(void)
+{
+    type_register_static(&xen_qdisk_type_info);
+}
+
+type_init(xen_qdisk_register_types)
diff --git a/include/hw/xen/xen-qdisk.h b/include/hw/xen/xen-qdisk.h
new file mode 100644
index 0000000000..ade0866037
--- /dev/null
+++ b/include/hw/xen/xen-qdisk.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ */
+
+#ifndef HW_XEN_QDISK_H
+#define HW_XEN_QDISK_H
+
+#include "hw/xen/xen-bus.h"
+
+typedef enum XenQdiskVdevType {
+    XEN_QDISK_VDEV_TYPE_DP,
+    XEN_QDISK_VDEV_TYPE_XVD,
+    XEN_QDISK_VDEV_TYPE_HD,
+    XEN_QDISK_VDEV_TYPE_SD,
+    XEN_QDISK_VDEV_TYPE__MAX
+} XenQdiskVdevType;
+
+typedef struct XenQdiskVdev {
+    XenQdiskVdevType type;
+    unsigned long disk;
+    unsigned long partition;
+    unsigned long number;
+    bool valid;
+} XenQdiskVdev;
+
+#define TYPE_XEN_QDISK_DEVICE  "xen-qdisk"
+#define XEN_QDISK_DEVICE(obj) \
+     OBJECT_CHECK(XenQdiskDevice, (obj), TYPE_XEN_QDISK_DEVICE)
+
+typedef struct XenQdiskDevice XenQdiskDevice;
+
+struct XenQdiskDevice {
+    XenDevice xendev;
+    XenQdiskVdev vdev;
+};
+
+#endif /* HW_XEN_QDISK_H */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [PATCH 03/18] xen: introduce 'xen-qdisk'
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
                   ` (2 preceding siblings ...)
  2018-11-21 15:11 ` Paul Durrant
@ 2018-11-21 15:11 ` Paul Durrant
  2018-11-21 15:11 ` [Qemu-devel] " Paul Durrant
                   ` (21 subsequent siblings)
  25 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:11 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Kevin Wolf, Anthony Perard, Paul Durrant, Stefano Stabellini, Max Reitz

This patch adds a new XenDevice: 'xen-qdisk' [1]. This will eventually
replace the 'xen_disk' legacy PV backend but it is illustrative to build
up the implementation incrementally, along with the XenBus/XenDevice
framework. Subsequent patches will therefore add to this device's
implementation as new features are added to the framework.

After this patch has been applied it is possible to instantiate a new
'xen-qdisk' device with a single 'vdev' parameter, which accepts values
adhering to the Xen VBD naming scheme [2]. For example, a command-line
instantiation of a xen-qdisk can be done with an argument similar to the
following:

-device xen-qdisk,vdev=hda

The implementation of the vdev parameter formulates the appropriate VBD
number for use in the PV protocol.

[1] The name 'qdisk' as always been the name given to the QEMU
    implementation of the Xen PV block protocol backend implementation
[2] http://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=docs/man/xen-vbd-interface.markdown.7

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
---
 MAINTAINERS                |   2 +-
 hw/block/Makefile.objs     |   1 +
 hw/block/trace-events      |   4 +
 hw/block/xen-qdisk.c       | 256 +++++++++++++++++++++++++++++++++++++++++++++
 include/hw/xen/xen-qdisk.h |  38 +++++++
 5 files changed, 300 insertions(+), 1 deletion(-)
 create mode 100644 hw/block/xen-qdisk.c
 create mode 100644 include/hw/xen/xen-qdisk.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 1032406c56..10f048a503 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -389,7 +389,7 @@ F: hw/9pfs/xen-9p-backend.c
 F: hw/char/xen_console.c
 F: hw/display/xenfb.c
 F: hw/net/xen_nic.c
-F: hw/block/xen_*
+F: hw/block/xen*
 F: hw/xen/
 F: hw/xenpv/
 F: hw/i386/xen/
diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs
index 53ce5751ae..bcdd36d318 100644
--- a/hw/block/Makefile.objs
+++ b/hw/block/Makefile.objs
@@ -5,6 +5,7 @@ common-obj-$(CONFIG_NAND) += nand.o
 common-obj-$(CONFIG_PFLASH_CFI01) += pflash_cfi01.o
 common-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
 common-obj-$(CONFIG_XEN) += xen_disk.o
+common-obj-$(CONFIG_XEN) += xen-qdisk.o
 common-obj-$(CONFIG_ECC) += ecc.o
 common-obj-$(CONFIG_ONENAND) += onenand.o
 common-obj-$(CONFIG_NVME_PCI) += nvme.o
diff --git a/hw/block/trace-events b/hw/block/trace-events
index 335c092450..fd3c126ac1 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -127,3 +127,7 @@ xen_disk_init(char *name) "%s"
 xen_disk_connect(char *name) "%s"
 xen_disk_disconnect(char *name) "%s"
 xen_disk_free(char *name) "%s"
+
+# hw/block/xen-qdisk.c
+xen_qdisk_realize(uint32_t disk, uint32_t partition) "d%up%u"
+xen_qdisk_unrealize(uint32_t disk, uint32_t partition) "d%up%u"
diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
new file mode 100644
index 0000000000..72122073f7
--- /dev/null
+++ b/hw/block/xen-qdisk.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/cutils.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+#include "hw/hw.h"
+#include "hw/xen/xen-qdisk.h"
+#include "trace.h"
+
+static void xen_qdisk_realize(XenDevice *xendev, Error **errp)
+{
+    XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
+    XenQdiskVdev *vdev = &qdiskdev->vdev;
+
+    if (!vdev->valid) {
+        error_setg(errp, "vdev property not set");
+        return;
+    }
+
+    trace_xen_qdisk_realize(vdev->disk, vdev->partition);
+}
+
+static void xen_qdisk_unrealize(XenDevice *xendev, Error **errp)
+{
+    XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
+    XenQdiskVdev *vdev = &qdiskdev->vdev;
+
+    trace_xen_qdisk_unrealize(vdev->disk, vdev->partition);
+}
+
+static char *disk_to_vbd_name(unsigned int disk)
+{
+    unsigned int len = DIV_ROUND_UP(disk, 26);
+    char *name = g_malloc0(len + 1);
+
+    do {
+        name[len--] = 'a' + (disk % 26);
+        disk /= 26;
+    } while (disk != 0);
+    assert(len == 0);
+
+    return name;
+}
+
+static void xen_qdisk_get_vdev(Object *obj, Visitor *v, const char *name,
+                               void *opaque, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    XenQdiskVdev *vdev = qdev_get_prop_ptr(dev, prop);
+    char *str;
+
+    switch (vdev->type) {
+    case XEN_QDISK_VDEV_TYPE_DP:
+        str = g_strdup_printf("d%lup%lu", vdev->disk, vdev->partition);
+        break;
+
+    case XEN_QDISK_VDEV_TYPE_XVD:
+    case XEN_QDISK_VDEV_TYPE_HD:
+    case XEN_QDISK_VDEV_TYPE_SD: {
+        char *name = disk_to_vbd_name(vdev->disk);
+
+        str = g_strdup_printf("%s%s%lu",
+                              (vdev->type == XEN_QDISK_VDEV_TYPE_XVD) ?
+                              "xvd" :
+                              (vdev->type == XEN_QDISK_VDEV_TYPE_HD) ?
+                              "hd" :
+                              "sd",
+                              name, vdev->partition);
+        g_free(name);
+        break;
+    }
+    default:
+        error_setg(errp, "invalid vdev type");
+        return;
+    }
+
+    visit_type_str(v, name, &str, errp);
+    g_free(str);
+}
+
+static unsigned int vbd_name_to_disk(const char *name, const char **endp)
+{
+    unsigned int disk = 0;
+
+    while (*name != '\0') {
+        if (!g_ascii_isalpha(*name) || !g_ascii_islower(*name)) {
+            break;
+        }
+
+        disk *= 26;
+        disk += *name++ - 'a';
+    }
+    *endp = name;
+
+    return disk;
+}
+
+static void xen_qdisk_set_vdev(Object *obj, Visitor *v, const char *name,
+                               void *opaque, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    XenQdiskVdev *vdev = qdev_get_prop_ptr(dev, prop);
+    Error *local_err = NULL;
+    char *str, *p;
+    const char *end;
+
+    if (dev->realized) {
+        qdev_prop_set_after_realize(dev, name, errp);
+        return;
+    }
+
+    visit_type_str(v, name, &str, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    p = strchr(str, 'd');
+    if (!p) {
+        goto invalid;
+    }
+
+    *p++ = '\0';
+    if (*str == '\0') {
+        vdev->type = XEN_QDISK_VDEV_TYPE_DP;
+    } else if (strcmp(str, "xv") == 0) {
+        vdev->type = XEN_QDISK_VDEV_TYPE_XVD;
+    } else if (strcmp(str, "h") == 0) {
+        vdev->type = XEN_QDISK_VDEV_TYPE_HD;
+    } else if (strcmp(str, "s") == 0) {
+        vdev->type = XEN_QDISK_VDEV_TYPE_SD;
+    } else {
+        goto invalid;
+    }
+
+    if (vdev->type == XEN_QDISK_VDEV_TYPE_DP) {
+        if (qemu_strtoul(p, &end, 10, &vdev->disk)) {
+            goto invalid;
+        }
+
+        if (*end == 'p') {
+            p = (char *) ++end;
+            if (*end == '\0') {
+                goto invalid;
+            }
+        }
+    } else {
+        vdev->disk = vbd_name_to_disk(p, &end);
+    }
+
+    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_QDISK_VDEV_TYPE_DP:
+    case XEN_QDISK_VDEV_TYPE_XVD:
+        if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) {
+            vdev->number = (202 << 8) | (vdev->disk << 4) |
+                vdev->partition;
+        } else if (vdev->disk < (1 << 20) && vdev->partition < (1 << 8)) {
+            vdev->number = (1 << 28) | (vdev->disk << 8) |
+                vdev->partition;
+        } else {
+            goto invalid;
+        }
+        break;
+
+    case XEN_QDISK_VDEV_TYPE_HD:
+        if ((vdev->disk == 0 || vdev->disk == 1) &&
+            vdev->partition < (1 << 4)) {
+            vdev->number = (3 << 8) | (vdev->disk << 6) | vdev->partition;
+        } else if ((vdev->disk == 2 || vdev->disk == 3) &&
+                   vdev->partition < (1 << 4)) {
+            vdev->number = (22 << 8) | ((vdev->disk - 2) << 6) |
+                vdev->partition;
+        } else {
+            goto invalid;
+        }
+        break;
+
+    case XEN_QDISK_VDEV_TYPE_SD:
+        if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) {
+            vdev->number = (8 << 8) | (vdev->disk << 4) | vdev->partition;
+        } else {
+            goto invalid;
+        }
+        break;
+
+    default:
+        goto invalid;
+    }
+
+    g_free(str);
+    vdev->valid = true;
+    return;
+
+invalid:
+    error_setg(errp, "invalid virtual disk specifier");
+    g_free(str);
+}
+
+const PropertyInfo xen_qdisk_prop_vdev = {
+    .name  = "str",
+    .description = "Virtual Disk specifier: d*p*/xvd*/hd*/sd*",
+    .get = xen_qdisk_get_vdev,
+    .set = xen_qdisk_set_vdev,
+};
+
+static Property xen_qdisk_props[] = {
+    DEFINE_PROP("vdev", XenQdiskDevice, vdev,
+                xen_qdisk_prop_vdev, XenQdiskVdev),
+    DEFINE_PROP_END_OF_LIST()
+};
+
+static void xen_qdisk_class_init(ObjectClass *class, void *data)
+{
+    DeviceClass *dev_class = DEVICE_CLASS(class);
+    XenDeviceClass *xendev_class = XEN_DEVICE_CLASS(class);
+
+    xendev_class->realize = xen_qdisk_realize;
+    xendev_class->unrealize = xen_qdisk_unrealize;
+
+    dev_class->desc = "Xen Qdisk Device";
+    dev_class->props = xen_qdisk_props;
+}
+
+static const TypeInfo xen_qdisk_type_info = {
+    .name = TYPE_XEN_QDISK_DEVICE,
+    .parent = TYPE_XEN_DEVICE,
+    .instance_size = sizeof(XenQdiskDevice),
+    .class_init = xen_qdisk_class_init,
+};
+
+static void xen_qdisk_register_types(void)
+{
+    type_register_static(&xen_qdisk_type_info);
+}
+
+type_init(xen_qdisk_register_types)
diff --git a/include/hw/xen/xen-qdisk.h b/include/hw/xen/xen-qdisk.h
new file mode 100644
index 0000000000..ade0866037
--- /dev/null
+++ b/include/hw/xen/xen-qdisk.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ */
+
+#ifndef HW_XEN_QDISK_H
+#define HW_XEN_QDISK_H
+
+#include "hw/xen/xen-bus.h"
+
+typedef enum XenQdiskVdevType {
+    XEN_QDISK_VDEV_TYPE_DP,
+    XEN_QDISK_VDEV_TYPE_XVD,
+    XEN_QDISK_VDEV_TYPE_HD,
+    XEN_QDISK_VDEV_TYPE_SD,
+    XEN_QDISK_VDEV_TYPE__MAX
+} XenQdiskVdevType;
+
+typedef struct XenQdiskVdev {
+    XenQdiskVdevType type;
+    unsigned long disk;
+    unsigned long partition;
+    unsigned long number;
+    bool valid;
+} XenQdiskVdev;
+
+#define TYPE_XEN_QDISK_DEVICE  "xen-qdisk"
+#define XEN_QDISK_DEVICE(obj) \
+     OBJECT_CHECK(XenQdiskDevice, (obj), TYPE_XEN_QDISK_DEVICE)
+
+typedef struct XenQdiskDevice XenQdiskDevice;
+
+struct XenQdiskDevice {
+    XenDevice xendev;
+    XenQdiskVdev vdev;
+};
+
+#endif /* HW_XEN_QDISK_H */
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [Qemu-devel] [PATCH 04/18] xen: create xenstore areas for XenDevice-s
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
                   ` (4 preceding siblings ...)
  2018-11-21 15:11 ` [Qemu-devel] " Paul Durrant
@ 2018-11-21 15:11 ` Paul Durrant
  2018-11-29 18:48   ` Anthony PERARD
  2018-11-29 18:48   ` [Qemu-devel] " Anthony PERARD
  2018-11-21 15:11 ` Paul Durrant
                   ` (19 subsequent siblings)
  25 siblings, 2 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:11 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Paul Durrant, Stefano Stabellini, Anthony Perard, Kevin Wolf, Max Reitz

This patch adds a new source module, xen-bus-helper.c, which builds on
basic libxenstore primitives to provide functions to create (setting
permissions appropriately) and destroy xenstore areas, and functions to
'printf' and 'scanf' nodes therein. The main xen-bus code then uses
these primitives [1] to initialize and destroy the frontend and backend
areas for a XenDevice during realize and unrealize respectively.

The 'xen-qdisk' implementation is extended with a 'get_name' method that
returns the VBD number. This number is reqired to 'name' the xenstore
areas.

NOTE: An exit handler is also added to make sure the xenstore areas are
      cleaned up if QEMU terminates without devices being unrealized.

[1] The 'scanf' functions are actually not yet needed, but they will be
    needed by code delivered in subsequent patches.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
---
 hw/block/xen-qdisk.c            |  11 ++
 hw/xen/Makefile.objs            |   2 +-
 hw/xen/trace-events             |   6 +-
 hw/xen/xen-bus-helper.c         | 124 +++++++++++++++++
 hw/xen/xen-bus.c                | 288 +++++++++++++++++++++++++++++++++++++++-
 include/hw/xen/xen-bus-helper.h |  26 ++++
 include/hw/xen/xen-bus.h        |  12 ++
 7 files changed, 464 insertions(+), 5 deletions(-)
 create mode 100644 hw/xen/xen-bus-helper.c
 create mode 100644 include/hw/xen/xen-bus-helper.h

diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
index 72122073f7..0859643f7d 100644
--- a/hw/block/xen-qdisk.c
+++ b/hw/block/xen-qdisk.c
@@ -11,6 +11,14 @@
 #include "hw/xen/xen-qdisk.h"
 #include "trace.h"
 
+static char *xen_qdisk_get_name(XenDevice *xendev, Error **errp)
+{
+    XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
+    XenQdiskVdev *vdev = &qdiskdev->vdev;
+
+    return g_strdup_printf("%lu", vdev->number);
+}
+
 static void xen_qdisk_realize(XenDevice *xendev, Error **errp)
 {
     XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
@@ -234,6 +242,9 @@ static void xen_qdisk_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_qdisk_get_name;
     xendev_class->realize = xen_qdisk_realize;
     xendev_class->unrealize = xen_qdisk_unrealize;
 
diff --git a/hw/xen/Makefile.objs b/hw/xen/Makefile.objs
index d9d6d7b4f9..77c0868190 100644
--- a/hw/xen/Makefile.objs
+++ b/hw/xen/Makefile.objs
@@ -1,5 +1,5 @@
 # xen backend driver support
-common-obj-$(CONFIG_XEN) += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o xen-common.o xen-bus.o
+common-obj-$(CONFIG_XEN) += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o xen-common.o xen-bus.o xen-bus-helper.o
 
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_graphics.o xen_pt_msi.o
diff --git a/hw/xen/trace-events b/hw/xen/trace-events
index 0172cd4e26..fa8aea1da1 100644
--- a/hw/xen/trace-events
+++ b/hw/xen/trace-events
@@ -16,5 +16,7 @@ xen_domid_restrict(int err) "err: %u"
 # include/hw/xen/xen-bus.c
 xen_bus_realize(void) ""
 xen_bus_unrealize(void) ""
-xen_device_realize(const char *type) "type: %s"
-xen_device_unrealize(const char *type) "type: %s"
+xen_device_realize(const char *type, char *name) "type: %s name: %s"
+xen_device_unrealize(const char *type, char *name) "type: %s name: %s"
+xen_device_backend_state(const char *type, char *name, const char *state) "type: %s name: %s -> %s"
+xen_device_frontend_state(const char *type, char *name, const char *state) "type: %s name: %s -> %s"
diff --git a/hw/xen/xen-bus-helper.c b/hw/xen/xen-bus-helper.c
new file mode 100644
index 0000000000..d9ee2ed6a0
--- /dev/null
+++ b/hw/xen/xen-bus-helper.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "hw/sysbus.h"
+#include "hw/xen/xen.h"
+#include "hw/xen/xen-bus.h"
+#include "hw/xen/xen-bus-helper.h"
+#include "qapi/error.h"
+
+struct xs_state {
+    enum xenbus_state statenum;
+    const char *statestr;
+};
+#define XS_STATE(state) { state, #state }
+
+static struct xs_state xs_state[] = {
+    XS_STATE(XenbusStateUnknown),
+    XS_STATE(XenbusStateInitialising),
+    XS_STATE(XenbusStateInitWait),
+    XS_STATE(XenbusStateInitialised),
+    XS_STATE(XenbusStateConnected),
+    XS_STATE(XenbusStateClosing),
+    XS_STATE(XenbusStateClosed),
+    XS_STATE(XenbusStateReconfiguring),
+    XS_STATE(XenbusStateReconfigured),
+};
+
+#undef XS_STATE
+
+const char *xs_strstate(enum xenbus_state state)
+{
+    unsigned int i;
+
+   for (i = 0; i < ARRAY_SIZE(xs_state); i++) {
+        if (xs_state[i].statenum == state) {
+            return xs_state[i].statestr;
+        }
+    }
+
+    return "INVALID";
+}
+
+void xs_node_create(struct xs_handle *xsh, const char *node,
+                    struct xs_permissions perms[],
+                    unsigned int nr_perms, Error **errp)
+{
+    if (!xs_write(xsh, XBT_NULL, node, "", 0)) {
+        error_setg_errno(errp, errno, "failed to create node '%s'", node);
+        return;
+    }
+
+    if (!xs_set_permissions(xsh, XBT_NULL, node,
+                            perms, nr_perms)) {
+        error_setg_errno(errp, errno, "failed to set node '%s' permissions",
+                         node);
+    }
+}
+
+void xs_node_destroy(struct xs_handle *xsh, const char *node)
+{
+    xs_rm(xsh, XBT_NULL, node);
+}
+
+void xs_node_vprintf(struct xs_handle *xsh, const char *node,
+                     const char *key, const char *fmt, va_list ap)
+{
+    char *path, *value;
+
+    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
+        g_strdup(key);
+
+    value = g_strdup_vprintf(fmt, ap);
+
+    xs_write(xsh, XBT_NULL, path, value, strlen(value));
+
+    g_free(value);
+    g_free(path);
+}
+
+void xs_node_printf(struct xs_handle *xsh, const char *node,
+                    const char *key, const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    xs_node_vprintf(xsh, node, key, fmt, ap);
+    va_end(ap);
+}
+
+int xs_node_vscanf(struct xs_handle *xsh, const char *node, const char *key,
+                   const char *fmt, va_list ap)
+{
+    char *path, *value;
+    int rc;
+
+    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
+        g_strdup(key);
+
+    value = xs_read(xsh, XBT_NULL, path, NULL);
+
+    rc = value ? vsscanf(value, fmt, ap) : EOF;
+
+    free(value);
+    g_free(path);
+
+    return rc;
+}
+
+int xs_node_scanf(struct xs_handle *xsh, const char *node, const char *key,
+                  const char *fmt, ...)
+{
+    va_list ap;
+    int rc;
+
+    va_start(ap, fmt);
+    rc = xs_node_vscanf(xsh, node, key, fmt, ap);
+    va_end(ap);
+
+    return rc;
+}
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index dede2d914a..663aa8e117 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -6,24 +6,102 @@
 #include "qemu/osdep.h"
 #include "hw/hw.h"
 #include "hw/sysbus.h"
+#include "hw/xen/xen.h"
 #include "hw/xen/xen-bus.h"
+#include "hw/xen/xen-bus-helper.h"
+#include "monitor/monitor.h"
 #include "qapi/error.h"
+#include "sysemu/sysemu.h"
 #include "trace.h"
 
+static char *xen_device_get_backend_path(XenDevice *xendev)
+{
+    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
+    XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
+    const char *type = object_get_typename(OBJECT(xendev));
+    const char *backend = xendev_class->backend;
+
+    if (!backend) {
+        backend = type;
+    }
+
+    return g_strdup_printf("/local/domain/%u/backend/%s/%u/%s",
+                           xenbus->backend_id, backend, xendev->frontend_id,
+                           xendev->name);
+}
+
+static char *xen_device_get_frontend_path(XenDevice *xendev)
+{
+    XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
+    const char *type = object_get_typename(OBJECT(xendev));
+    const char *device = xendev_class->device;
+
+    if (!device) {
+        device = type;
+    }
+
+    return g_strdup_printf("/local/domain/%u/device/%s/%s",
+                           xendev->frontend_id, device, xendev->name);
+}
+
+static void xen_bus_print_dev(Monitor *mon, DeviceState *dev, int indent)
+{
+    XenDevice *xendev = XEN_DEVICE(dev);
+
+    monitor_printf(mon, "%*sname = '%s' frontend_id = %u\n",
+                   indent, "", xendev->name, xendev->frontend_id);
+}
+
+static char *xen_bus_get_dev_path(DeviceState *dev)
+{
+    return xen_device_get_backend_path(XEN_DEVICE(dev));
+}
+
 static void xen_bus_unrealize(BusState *bus, Error **errp)
 {
+    XenBus *xenbus = XEN_BUS(bus);
+
     trace_xen_bus_unrealize();
+
+    if (!xenbus->xsh) {
+        return;
+    }
+
+    xs_close(xenbus->xsh);
 }
 
 static void xen_bus_realize(BusState *bus, Error **errp)
 {
+    XenBus *xenbus = XEN_BUS(bus);
+    unsigned int domid;
+
     trace_xen_bus_realize();
+
+    xenbus->xsh = xs_open(0);
+    if (!xenbus->xsh) {
+        error_setg_errno(errp, errno, "failed xs_open");
+        goto fail;
+    }
+
+    if (xs_node_scanf(xenbus->xsh, "", /* domain root node */
+                            "domid", "%u", &domid) == 1) {
+        xenbus->backend_id = domid;
+    } else {
+        xenbus->backend_id = 0; /* Assume lack of node means dom0 */
+    }
+
+    return;
+
+fail:
+    xen_bus_unrealize(bus, &error_abort);
 }
 
 static void xen_bus_class_init(ObjectClass *class, void *data)
 {
     BusClass *bus_class = BUS_CLASS(class);
 
+    bus_class->print_dev = xen_bus_print_dev;
+    bus_class->get_dev_path = xen_bus_get_dev_path;
     bus_class->realize = xen_bus_realize;
     bus_class->unrealize = xen_bus_unrealize;
 }
@@ -36,6 +114,138 @@ static const TypeInfo xen_bus_type_info = {
     .class_init = xen_bus_class_init,
 };
 
+static void xen_device_backend_printf(XenDevice *xendev, const char *key,
+                                      const char *fmt, ...)
+{
+    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
+    va_list ap;
+
+    g_assert(xenbus->xsh);
+
+    va_start(ap, fmt);
+    xs_node_vprintf(xenbus->xsh, xendev->backend_path, key, fmt, ap);
+    va_end(ap);
+}
+
+static void xen_device_backend_set_state(XenDevice *xendev,
+                                         enum xenbus_state state)
+{
+    const char *type = object_get_typename(OBJECT(xendev));
+
+    if (xendev->backend_state == state) {
+        return;
+    }
+
+    trace_xen_device_backend_state(type, xendev->name,
+                                   xs_strstate(state));
+
+    xendev->backend_state = state;
+    xen_device_backend_printf(xendev, "state", "%u", state);
+}
+
+static void xen_device_backend_create(XenDevice *xendev, Error **errp)
+{
+    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
+    struct xs_permissions perms[2];
+    Error *local_err = NULL;
+
+    xendev->backend_path = xen_device_get_backend_path(xendev);
+
+    perms[0].id = xenbus->backend_id;
+    perms[0].perms = XS_PERM_NONE;
+    perms[1].id = xendev->frontend_id;
+    perms[1].perms = XS_PERM_READ;
+
+    g_assert(xenbus->xsh);
+
+    xs_node_create(xenbus->xsh, xendev->backend_path, perms,
+                   ARRAY_SIZE(perms), &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to create backend: ");
+    }
+}
+
+static void xen_device_backend_destroy(XenDevice *xendev)
+{
+    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
+
+    if (!xendev->backend_path) {
+        return;
+    }
+
+    g_assert(xenbus->xsh);
+
+    xs_node_destroy(xenbus->xsh, xendev->backend_path);
+    g_free(xendev->backend_path);
+}
+
+static void xen_device_frontend_printf(XenDevice *xendev, const char *key,
+                                       const char *fmt, ...)
+{
+    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
+    va_list ap;
+
+    g_assert(xenbus->xsh);
+
+    va_start(ap, fmt);
+    xs_node_vprintf(xenbus->xsh, xendev->frontend_path, key, fmt, ap);
+    va_end(ap);
+}
+
+static void xen_device_frontend_set_state(XenDevice *xendev,
+                                          enum xenbus_state state)
+{
+    const char *type = object_get_typename(OBJECT(xendev));
+
+    if (xendev->frontend_state == state) {
+        return;
+    }
+
+    trace_xen_device_frontend_state(type, xendev->name,
+                                    xs_strstate(state));
+
+    xendev->frontend_state = state;
+    xen_device_frontend_printf(xendev, "state", "%u", state);
+}
+
+static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
+{
+    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
+    struct xs_permissions perms[2];
+    Error *local_err = NULL;
+
+    xendev->frontend_path = xen_device_get_frontend_path(xendev);
+
+    perms[0].id = xendev->frontend_id;
+    perms[0].perms = XS_PERM_NONE;
+    perms[1].id = xenbus->backend_id;
+    perms[1].perms = XS_PERM_READ | XS_PERM_WRITE;
+
+    g_assert(xenbus->xsh);
+
+    xs_node_create(xenbus->xsh, xendev->frontend_path, perms,
+                   ARRAY_SIZE(perms), &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to create frontend: ");
+    }
+}
+
+static void xen_device_frontend_destroy(XenDevice *xendev)
+{
+    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
+
+    if (!xendev->frontend_path) {
+        return;
+    }
+
+    g_assert(xenbus->xsh);
+
+    xs_node_destroy(xenbus->xsh, xendev->frontend_path);
+    g_free(xendev->frontend_path);
+}
+
 static void xen_device_unrealize(DeviceState *dev, Error **errp)
 {
     XenDevice *xendev = XEN_DEVICE(dev);
@@ -43,7 +253,10 @@ static void xen_device_unrealize(DeviceState *dev, Error **errp)
     const char *type = object_get_typename(OBJECT(xendev));
     Error *local_err = NULL;
 
-    trace_xen_device_unrealize(type);
+    trace_xen_device_unrealize(type, xendev->name);
+
+    if (xendev->exit.notify)
+        qemu_remove_exit_notifier(&xendev->exit);
 
     if (xendev_class->unrealize) {
         xendev_class->unrealize(xendev, &local_err);
@@ -52,16 +265,62 @@ static void xen_device_unrealize(DeviceState *dev, Error **errp)
             return;
         }
     }
+
+    xen_device_frontend_destroy(xendev);
+    xen_device_backend_destroy(xendev);
+
+    g_free(xendev->name);
+}
+
+static void xen_device_exit(Notifier *n, void *data)
+{
+    XenDevice *xendev = container_of(n, XenDevice, exit);
+
+    xen_device_unrealize(DEVICE(xendev), &error_abort);
 }
 
 static void xen_device_realize(DeviceState *dev, Error **errp)
 {
     XenDevice *xendev = XEN_DEVICE(dev);
     XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
+    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
     const char *type = object_get_typename(OBJECT(xendev));
     Error *local_err = NULL;
 
-    trace_xen_device_realize(type);
+    if (xendev->frontend_id == DOMID_INVALID) {
+        xendev->frontend_id = xen_domid;
+    }
+
+    if (xendev->frontend_id >= DOMID_FIRST_RESERVED) {
+        error_setg(errp, "invalid frontend-id");
+        return;
+    }
+
+    if (!xendev_class->get_name) {
+        error_setg(errp, "get_name method not implemented");
+        return;
+    }
+
+    xendev->name = xendev_class->get_name(xendev, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to get device name: ");
+        return;
+    }
+
+    trace_xen_device_realize(type, xendev->name);
+
+    xen_device_backend_create(xendev, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        goto unrealize;
+    }
+
+    xen_device_frontend_create(xendev, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        goto unrealize;
+    }
 
     if (xendev_class->realize) {
         xendev_class->realize(xendev, &local_err);
@@ -71,18 +330,43 @@ static void xen_device_realize(DeviceState *dev, Error **errp)
         }
     }
 
+    xen_device_backend_printf(xendev, "frontend", "%s",
+                              xendev->frontend_path);
+    xen_device_backend_printf(xendev, "frontend-id", "%u",
+                              xendev->frontend_id);
+    xen_device_backend_printf(xendev, "online", "%u", 1);
+    xen_device_backend_printf(xendev, "hotplug-status", "connected");
+
+    xen_device_backend_set_state(xendev, XenbusStateInitWait);
+
+    xen_device_frontend_printf(xendev, "backend", "%s",
+                               xendev->backend_path);
+    xen_device_frontend_printf(xendev, "backend-id", "%u",
+                               xenbus->backend_id);
+
+    xen_device_frontend_set_state(xendev, XenbusStateInitialising);
+
+    xendev->exit.notify = xen_device_exit;
+    qemu_add_exit_notifier(&xendev->exit);
     return;
 
 unrealize:
     xen_device_unrealize(dev, &error_abort);
 }
 
+static Property xen_device_props[] = {
+    DEFINE_PROP_UINT16("frontend-id", XenDevice, frontend_id,
+                       DOMID_INVALID),
+    DEFINE_PROP_END_OF_LIST()
+};
+
 static void xen_device_class_init(ObjectClass *class, void *data)
 {
     DeviceClass *dev_class = DEVICE_CLASS(class);
 
     dev_class->realize = xen_device_realize;
     dev_class->unrealize = xen_device_unrealize;
+    dev_class->props = xen_device_props;
     dev_class->bus_type = TYPE_XEN_BUS;
 }
 
diff --git a/include/hw/xen/xen-bus-helper.h b/include/hw/xen/xen-bus-helper.h
new file mode 100644
index 0000000000..53570650db
--- /dev/null
+++ b/include/hw/xen/xen-bus-helper.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ */
+
+#ifndef HW_XEN_BUS_HELPER_H
+#define HW_XEN_BUS_HELPER_H
+
+const char *xs_strstate(enum xenbus_state state);
+
+void xs_node_create(struct xs_handle *xsh, const char *node,
+                    struct xs_permissions perms[],
+                    unsigned int nr_perms, Error **errp);
+void xs_node_destroy(struct xs_handle *xsh, const char *node);
+
+void xs_node_vprintf(struct xs_handle *xsh, const char *node,
+                     const char *key, const char *fmt, va_list ap);
+void xs_node_printf(struct xs_handle *xsh, const char *node, const char *key,
+                    const char *fmt, ...);
+
+int xs_node_vscanf(struct xs_handle *xsh, const char *node, const char *key,
+                   const char *fmt, va_list ap);
+int xs_node_scanf(struct xs_handle *xsh, const char *node, const char *key,
+                  const char *fmt, ...);
+
+#endif /* HW_XEN_BUS_HELPER_H */
diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h
index 41772dc73a..434d1dbf58 100644
--- a/include/hw/xen/xen-bus.h
+++ b/include/hw/xen/xen-bus.h
@@ -6,12 +6,19 @@
 #ifndef HW_XEN_BUS_H
 #define HW_XEN_BUS_H
 
+#include "hw/xen/xen_common.h"
 #include "hw/sysbus.h"
 
 typedef struct XenDevice {
     DeviceState qdev;
+    domid_t frontend_id;
+    char *name;
+    char *backend_path, *frontend_path;
+    enum xenbus_state backend_state, frontend_state;
+    Notifier exit;
 } XenDevice;
 
+typedef char *(*XenDeviceGetName)(XenDevice *xendev, Error **errp);
 typedef void (*XenDeviceRealize)(XenDevice *xendev, Error **errp);
 typedef void (*XenDeviceUnrealize)(XenDevice *xendev, Error **errp);
 
@@ -19,6 +26,9 @@ typedef struct XenDeviceClass {
     /*< private >*/
     DeviceClass parent_class;
     /*< public >*/
+    const char *backend;
+    const char *device;
+    XenDeviceGetName get_name;
     XenDeviceRealize realize;
     XenDeviceUnrealize unrealize;
 } XenDeviceClass;
@@ -33,6 +43,8 @@ typedef struct XenDeviceClass {
 
 typedef struct XenBus {
     BusState qbus;
+    domid_t backend_id;
+    struct xs_handle *xsh;
 } XenBus;
 
 typedef struct XenBusClass {
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [PATCH 04/18] xen: create xenstore areas for XenDevice-s
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
                   ` (5 preceding siblings ...)
  2018-11-21 15:11 ` [Qemu-devel] [PATCH 04/18] xen: create xenstore areas for XenDevice-s Paul Durrant
@ 2018-11-21 15:11 ` Paul Durrant
  2018-11-21 15:11 ` [Qemu-devel] [PATCH 05/18] xen: add xenstore watcher infratructure Paul Durrant
                   ` (18 subsequent siblings)
  25 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:11 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Anthony Perard, Kevin Wolf, Paul Durrant, Stefano Stabellini, Max Reitz

This patch adds a new source module, xen-bus-helper.c, which builds on
basic libxenstore primitives to provide functions to create (setting
permissions appropriately) and destroy xenstore areas, and functions to
'printf' and 'scanf' nodes therein. The main xen-bus code then uses
these primitives [1] to initialize and destroy the frontend and backend
areas for a XenDevice during realize and unrealize respectively.

The 'xen-qdisk' implementation is extended with a 'get_name' method that
returns the VBD number. This number is reqired to 'name' the xenstore
areas.

NOTE: An exit handler is also added to make sure the xenstore areas are
      cleaned up if QEMU terminates without devices being unrealized.

[1] The 'scanf' functions are actually not yet needed, but they will be
    needed by code delivered in subsequent patches.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
---
 hw/block/xen-qdisk.c            |  11 ++
 hw/xen/Makefile.objs            |   2 +-
 hw/xen/trace-events             |   6 +-
 hw/xen/xen-bus-helper.c         | 124 +++++++++++++++++
 hw/xen/xen-bus.c                | 288 +++++++++++++++++++++++++++++++++++++++-
 include/hw/xen/xen-bus-helper.h |  26 ++++
 include/hw/xen/xen-bus.h        |  12 ++
 7 files changed, 464 insertions(+), 5 deletions(-)
 create mode 100644 hw/xen/xen-bus-helper.c
 create mode 100644 include/hw/xen/xen-bus-helper.h

diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
index 72122073f7..0859643f7d 100644
--- a/hw/block/xen-qdisk.c
+++ b/hw/block/xen-qdisk.c
@@ -11,6 +11,14 @@
 #include "hw/xen/xen-qdisk.h"
 #include "trace.h"
 
+static char *xen_qdisk_get_name(XenDevice *xendev, Error **errp)
+{
+    XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
+    XenQdiskVdev *vdev = &qdiskdev->vdev;
+
+    return g_strdup_printf("%lu", vdev->number);
+}
+
 static void xen_qdisk_realize(XenDevice *xendev, Error **errp)
 {
     XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
@@ -234,6 +242,9 @@ static void xen_qdisk_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_qdisk_get_name;
     xendev_class->realize = xen_qdisk_realize;
     xendev_class->unrealize = xen_qdisk_unrealize;
 
diff --git a/hw/xen/Makefile.objs b/hw/xen/Makefile.objs
index d9d6d7b4f9..77c0868190 100644
--- a/hw/xen/Makefile.objs
+++ b/hw/xen/Makefile.objs
@@ -1,5 +1,5 @@
 # xen backend driver support
-common-obj-$(CONFIG_XEN) += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o xen-common.o xen-bus.o
+common-obj-$(CONFIG_XEN) += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o xen-common.o xen-bus.o xen-bus-helper.o
 
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_graphics.o xen_pt_msi.o
diff --git a/hw/xen/trace-events b/hw/xen/trace-events
index 0172cd4e26..fa8aea1da1 100644
--- a/hw/xen/trace-events
+++ b/hw/xen/trace-events
@@ -16,5 +16,7 @@ xen_domid_restrict(int err) "err: %u"
 # include/hw/xen/xen-bus.c
 xen_bus_realize(void) ""
 xen_bus_unrealize(void) ""
-xen_device_realize(const char *type) "type: %s"
-xen_device_unrealize(const char *type) "type: %s"
+xen_device_realize(const char *type, char *name) "type: %s name: %s"
+xen_device_unrealize(const char *type, char *name) "type: %s name: %s"
+xen_device_backend_state(const char *type, char *name, const char *state) "type: %s name: %s -> %s"
+xen_device_frontend_state(const char *type, char *name, const char *state) "type: %s name: %s -> %s"
diff --git a/hw/xen/xen-bus-helper.c b/hw/xen/xen-bus-helper.c
new file mode 100644
index 0000000000..d9ee2ed6a0
--- /dev/null
+++ b/hw/xen/xen-bus-helper.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "hw/sysbus.h"
+#include "hw/xen/xen.h"
+#include "hw/xen/xen-bus.h"
+#include "hw/xen/xen-bus-helper.h"
+#include "qapi/error.h"
+
+struct xs_state {
+    enum xenbus_state statenum;
+    const char *statestr;
+};
+#define XS_STATE(state) { state, #state }
+
+static struct xs_state xs_state[] = {
+    XS_STATE(XenbusStateUnknown),
+    XS_STATE(XenbusStateInitialising),
+    XS_STATE(XenbusStateInitWait),
+    XS_STATE(XenbusStateInitialised),
+    XS_STATE(XenbusStateConnected),
+    XS_STATE(XenbusStateClosing),
+    XS_STATE(XenbusStateClosed),
+    XS_STATE(XenbusStateReconfiguring),
+    XS_STATE(XenbusStateReconfigured),
+};
+
+#undef XS_STATE
+
+const char *xs_strstate(enum xenbus_state state)
+{
+    unsigned int i;
+
+   for (i = 0; i < ARRAY_SIZE(xs_state); i++) {
+        if (xs_state[i].statenum == state) {
+            return xs_state[i].statestr;
+        }
+    }
+
+    return "INVALID";
+}
+
+void xs_node_create(struct xs_handle *xsh, const char *node,
+                    struct xs_permissions perms[],
+                    unsigned int nr_perms, Error **errp)
+{
+    if (!xs_write(xsh, XBT_NULL, node, "", 0)) {
+        error_setg_errno(errp, errno, "failed to create node '%s'", node);
+        return;
+    }
+
+    if (!xs_set_permissions(xsh, XBT_NULL, node,
+                            perms, nr_perms)) {
+        error_setg_errno(errp, errno, "failed to set node '%s' permissions",
+                         node);
+    }
+}
+
+void xs_node_destroy(struct xs_handle *xsh, const char *node)
+{
+    xs_rm(xsh, XBT_NULL, node);
+}
+
+void xs_node_vprintf(struct xs_handle *xsh, const char *node,
+                     const char *key, const char *fmt, va_list ap)
+{
+    char *path, *value;
+
+    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
+        g_strdup(key);
+
+    value = g_strdup_vprintf(fmt, ap);
+
+    xs_write(xsh, XBT_NULL, path, value, strlen(value));
+
+    g_free(value);
+    g_free(path);
+}
+
+void xs_node_printf(struct xs_handle *xsh, const char *node,
+                    const char *key, const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    xs_node_vprintf(xsh, node, key, fmt, ap);
+    va_end(ap);
+}
+
+int xs_node_vscanf(struct xs_handle *xsh, const char *node, const char *key,
+                   const char *fmt, va_list ap)
+{
+    char *path, *value;
+    int rc;
+
+    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
+        g_strdup(key);
+
+    value = xs_read(xsh, XBT_NULL, path, NULL);
+
+    rc = value ? vsscanf(value, fmt, ap) : EOF;
+
+    free(value);
+    g_free(path);
+
+    return rc;
+}
+
+int xs_node_scanf(struct xs_handle *xsh, const char *node, const char *key,
+                  const char *fmt, ...)
+{
+    va_list ap;
+    int rc;
+
+    va_start(ap, fmt);
+    rc = xs_node_vscanf(xsh, node, key, fmt, ap);
+    va_end(ap);
+
+    return rc;
+}
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index dede2d914a..663aa8e117 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -6,24 +6,102 @@
 #include "qemu/osdep.h"
 #include "hw/hw.h"
 #include "hw/sysbus.h"
+#include "hw/xen/xen.h"
 #include "hw/xen/xen-bus.h"
+#include "hw/xen/xen-bus-helper.h"
+#include "monitor/monitor.h"
 #include "qapi/error.h"
+#include "sysemu/sysemu.h"
 #include "trace.h"
 
+static char *xen_device_get_backend_path(XenDevice *xendev)
+{
+    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
+    XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
+    const char *type = object_get_typename(OBJECT(xendev));
+    const char *backend = xendev_class->backend;
+
+    if (!backend) {
+        backend = type;
+    }
+
+    return g_strdup_printf("/local/domain/%u/backend/%s/%u/%s",
+                           xenbus->backend_id, backend, xendev->frontend_id,
+                           xendev->name);
+}
+
+static char *xen_device_get_frontend_path(XenDevice *xendev)
+{
+    XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
+    const char *type = object_get_typename(OBJECT(xendev));
+    const char *device = xendev_class->device;
+
+    if (!device) {
+        device = type;
+    }
+
+    return g_strdup_printf("/local/domain/%u/device/%s/%s",
+                           xendev->frontend_id, device, xendev->name);
+}
+
+static void xen_bus_print_dev(Monitor *mon, DeviceState *dev, int indent)
+{
+    XenDevice *xendev = XEN_DEVICE(dev);
+
+    monitor_printf(mon, "%*sname = '%s' frontend_id = %u\n",
+                   indent, "", xendev->name, xendev->frontend_id);
+}
+
+static char *xen_bus_get_dev_path(DeviceState *dev)
+{
+    return xen_device_get_backend_path(XEN_DEVICE(dev));
+}
+
 static void xen_bus_unrealize(BusState *bus, Error **errp)
 {
+    XenBus *xenbus = XEN_BUS(bus);
+
     trace_xen_bus_unrealize();
+
+    if (!xenbus->xsh) {
+        return;
+    }
+
+    xs_close(xenbus->xsh);
 }
 
 static void xen_bus_realize(BusState *bus, Error **errp)
 {
+    XenBus *xenbus = XEN_BUS(bus);
+    unsigned int domid;
+
     trace_xen_bus_realize();
+
+    xenbus->xsh = xs_open(0);
+    if (!xenbus->xsh) {
+        error_setg_errno(errp, errno, "failed xs_open");
+        goto fail;
+    }
+
+    if (xs_node_scanf(xenbus->xsh, "", /* domain root node */
+                            "domid", "%u", &domid) == 1) {
+        xenbus->backend_id = domid;
+    } else {
+        xenbus->backend_id = 0; /* Assume lack of node means dom0 */
+    }
+
+    return;
+
+fail:
+    xen_bus_unrealize(bus, &error_abort);
 }
 
 static void xen_bus_class_init(ObjectClass *class, void *data)
 {
     BusClass *bus_class = BUS_CLASS(class);
 
+    bus_class->print_dev = xen_bus_print_dev;
+    bus_class->get_dev_path = xen_bus_get_dev_path;
     bus_class->realize = xen_bus_realize;
     bus_class->unrealize = xen_bus_unrealize;
 }
@@ -36,6 +114,138 @@ static const TypeInfo xen_bus_type_info = {
     .class_init = xen_bus_class_init,
 };
 
+static void xen_device_backend_printf(XenDevice *xendev, const char *key,
+                                      const char *fmt, ...)
+{
+    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
+    va_list ap;
+
+    g_assert(xenbus->xsh);
+
+    va_start(ap, fmt);
+    xs_node_vprintf(xenbus->xsh, xendev->backend_path, key, fmt, ap);
+    va_end(ap);
+}
+
+static void xen_device_backend_set_state(XenDevice *xendev,
+                                         enum xenbus_state state)
+{
+    const char *type = object_get_typename(OBJECT(xendev));
+
+    if (xendev->backend_state == state) {
+        return;
+    }
+
+    trace_xen_device_backend_state(type, xendev->name,
+                                   xs_strstate(state));
+
+    xendev->backend_state = state;
+    xen_device_backend_printf(xendev, "state", "%u", state);
+}
+
+static void xen_device_backend_create(XenDevice *xendev, Error **errp)
+{
+    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
+    struct xs_permissions perms[2];
+    Error *local_err = NULL;
+
+    xendev->backend_path = xen_device_get_backend_path(xendev);
+
+    perms[0].id = xenbus->backend_id;
+    perms[0].perms = XS_PERM_NONE;
+    perms[1].id = xendev->frontend_id;
+    perms[1].perms = XS_PERM_READ;
+
+    g_assert(xenbus->xsh);
+
+    xs_node_create(xenbus->xsh, xendev->backend_path, perms,
+                   ARRAY_SIZE(perms), &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to create backend: ");
+    }
+}
+
+static void xen_device_backend_destroy(XenDevice *xendev)
+{
+    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
+
+    if (!xendev->backend_path) {
+        return;
+    }
+
+    g_assert(xenbus->xsh);
+
+    xs_node_destroy(xenbus->xsh, xendev->backend_path);
+    g_free(xendev->backend_path);
+}
+
+static void xen_device_frontend_printf(XenDevice *xendev, const char *key,
+                                       const char *fmt, ...)
+{
+    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
+    va_list ap;
+
+    g_assert(xenbus->xsh);
+
+    va_start(ap, fmt);
+    xs_node_vprintf(xenbus->xsh, xendev->frontend_path, key, fmt, ap);
+    va_end(ap);
+}
+
+static void xen_device_frontend_set_state(XenDevice *xendev,
+                                          enum xenbus_state state)
+{
+    const char *type = object_get_typename(OBJECT(xendev));
+
+    if (xendev->frontend_state == state) {
+        return;
+    }
+
+    trace_xen_device_frontend_state(type, xendev->name,
+                                    xs_strstate(state));
+
+    xendev->frontend_state = state;
+    xen_device_frontend_printf(xendev, "state", "%u", state);
+}
+
+static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
+{
+    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
+    struct xs_permissions perms[2];
+    Error *local_err = NULL;
+
+    xendev->frontend_path = xen_device_get_frontend_path(xendev);
+
+    perms[0].id = xendev->frontend_id;
+    perms[0].perms = XS_PERM_NONE;
+    perms[1].id = xenbus->backend_id;
+    perms[1].perms = XS_PERM_READ | XS_PERM_WRITE;
+
+    g_assert(xenbus->xsh);
+
+    xs_node_create(xenbus->xsh, xendev->frontend_path, perms,
+                   ARRAY_SIZE(perms), &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to create frontend: ");
+    }
+}
+
+static void xen_device_frontend_destroy(XenDevice *xendev)
+{
+    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
+
+    if (!xendev->frontend_path) {
+        return;
+    }
+
+    g_assert(xenbus->xsh);
+
+    xs_node_destroy(xenbus->xsh, xendev->frontend_path);
+    g_free(xendev->frontend_path);
+}
+
 static void xen_device_unrealize(DeviceState *dev, Error **errp)
 {
     XenDevice *xendev = XEN_DEVICE(dev);
@@ -43,7 +253,10 @@ static void xen_device_unrealize(DeviceState *dev, Error **errp)
     const char *type = object_get_typename(OBJECT(xendev));
     Error *local_err = NULL;
 
-    trace_xen_device_unrealize(type);
+    trace_xen_device_unrealize(type, xendev->name);
+
+    if (xendev->exit.notify)
+        qemu_remove_exit_notifier(&xendev->exit);
 
     if (xendev_class->unrealize) {
         xendev_class->unrealize(xendev, &local_err);
@@ -52,16 +265,62 @@ static void xen_device_unrealize(DeviceState *dev, Error **errp)
             return;
         }
     }
+
+    xen_device_frontend_destroy(xendev);
+    xen_device_backend_destroy(xendev);
+
+    g_free(xendev->name);
+}
+
+static void xen_device_exit(Notifier *n, void *data)
+{
+    XenDevice *xendev = container_of(n, XenDevice, exit);
+
+    xen_device_unrealize(DEVICE(xendev), &error_abort);
 }
 
 static void xen_device_realize(DeviceState *dev, Error **errp)
 {
     XenDevice *xendev = XEN_DEVICE(dev);
     XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
+    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
     const char *type = object_get_typename(OBJECT(xendev));
     Error *local_err = NULL;
 
-    trace_xen_device_realize(type);
+    if (xendev->frontend_id == DOMID_INVALID) {
+        xendev->frontend_id = xen_domid;
+    }
+
+    if (xendev->frontend_id >= DOMID_FIRST_RESERVED) {
+        error_setg(errp, "invalid frontend-id");
+        return;
+    }
+
+    if (!xendev_class->get_name) {
+        error_setg(errp, "get_name method not implemented");
+        return;
+    }
+
+    xendev->name = xendev_class->get_name(xendev, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to get device name: ");
+        return;
+    }
+
+    trace_xen_device_realize(type, xendev->name);
+
+    xen_device_backend_create(xendev, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        goto unrealize;
+    }
+
+    xen_device_frontend_create(xendev, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        goto unrealize;
+    }
 
     if (xendev_class->realize) {
         xendev_class->realize(xendev, &local_err);
@@ -71,18 +330,43 @@ static void xen_device_realize(DeviceState *dev, Error **errp)
         }
     }
 
+    xen_device_backend_printf(xendev, "frontend", "%s",
+                              xendev->frontend_path);
+    xen_device_backend_printf(xendev, "frontend-id", "%u",
+                              xendev->frontend_id);
+    xen_device_backend_printf(xendev, "online", "%u", 1);
+    xen_device_backend_printf(xendev, "hotplug-status", "connected");
+
+    xen_device_backend_set_state(xendev, XenbusStateInitWait);
+
+    xen_device_frontend_printf(xendev, "backend", "%s",
+                               xendev->backend_path);
+    xen_device_frontend_printf(xendev, "backend-id", "%u",
+                               xenbus->backend_id);
+
+    xen_device_frontend_set_state(xendev, XenbusStateInitialising);
+
+    xendev->exit.notify = xen_device_exit;
+    qemu_add_exit_notifier(&xendev->exit);
     return;
 
 unrealize:
     xen_device_unrealize(dev, &error_abort);
 }
 
+static Property xen_device_props[] = {
+    DEFINE_PROP_UINT16("frontend-id", XenDevice, frontend_id,
+                       DOMID_INVALID),
+    DEFINE_PROP_END_OF_LIST()
+};
+
 static void xen_device_class_init(ObjectClass *class, void *data)
 {
     DeviceClass *dev_class = DEVICE_CLASS(class);
 
     dev_class->realize = xen_device_realize;
     dev_class->unrealize = xen_device_unrealize;
+    dev_class->props = xen_device_props;
     dev_class->bus_type = TYPE_XEN_BUS;
 }
 
diff --git a/include/hw/xen/xen-bus-helper.h b/include/hw/xen/xen-bus-helper.h
new file mode 100644
index 0000000000..53570650db
--- /dev/null
+++ b/include/hw/xen/xen-bus-helper.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ */
+
+#ifndef HW_XEN_BUS_HELPER_H
+#define HW_XEN_BUS_HELPER_H
+
+const char *xs_strstate(enum xenbus_state state);
+
+void xs_node_create(struct xs_handle *xsh, const char *node,
+                    struct xs_permissions perms[],
+                    unsigned int nr_perms, Error **errp);
+void xs_node_destroy(struct xs_handle *xsh, const char *node);
+
+void xs_node_vprintf(struct xs_handle *xsh, const char *node,
+                     const char *key, const char *fmt, va_list ap);
+void xs_node_printf(struct xs_handle *xsh, const char *node, const char *key,
+                    const char *fmt, ...);
+
+int xs_node_vscanf(struct xs_handle *xsh, const char *node, const char *key,
+                   const char *fmt, va_list ap);
+int xs_node_scanf(struct xs_handle *xsh, const char *node, const char *key,
+                  const char *fmt, ...);
+
+#endif /* HW_XEN_BUS_HELPER_H */
diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h
index 41772dc73a..434d1dbf58 100644
--- a/include/hw/xen/xen-bus.h
+++ b/include/hw/xen/xen-bus.h
@@ -6,12 +6,19 @@
 #ifndef HW_XEN_BUS_H
 #define HW_XEN_BUS_H
 
+#include "hw/xen/xen_common.h"
 #include "hw/sysbus.h"
 
 typedef struct XenDevice {
     DeviceState qdev;
+    domid_t frontend_id;
+    char *name;
+    char *backend_path, *frontend_path;
+    enum xenbus_state backend_state, frontend_state;
+    Notifier exit;
 } XenDevice;
 
+typedef char *(*XenDeviceGetName)(XenDevice *xendev, Error **errp);
 typedef void (*XenDeviceRealize)(XenDevice *xendev, Error **errp);
 typedef void (*XenDeviceUnrealize)(XenDevice *xendev, Error **errp);
 
@@ -19,6 +26,9 @@ typedef struct XenDeviceClass {
     /*< private >*/
     DeviceClass parent_class;
     /*< public >*/
+    const char *backend;
+    const char *device;
+    XenDeviceGetName get_name;
     XenDeviceRealize realize;
     XenDeviceUnrealize unrealize;
 } XenDeviceClass;
@@ -33,6 +43,8 @@ typedef struct XenDeviceClass {
 
 typedef struct XenBus {
     BusState qbus;
+    domid_t backend_id;
+    struct xs_handle *xsh;
 } XenBus;
 
 typedef struct XenBusClass {
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [Qemu-devel] [PATCH 05/18] xen: add xenstore watcher infratructure
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
                   ` (6 preceding siblings ...)
  2018-11-21 15:11 ` Paul Durrant
@ 2018-11-21 15:11 ` Paul Durrant
  2018-12-03 14:42   ` Anthony PERARD
  2018-12-03 14:42   ` Anthony PERARD
  2018-11-21 15:11 ` Paul Durrant
                   ` (17 subsequent siblings)
  25 siblings, 2 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:11 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Paul Durrant, Kevin Wolf, Max Reitz, Stefano Stabellini, Anthony Perard

A Xen PV frontend communicates its state to the PV backend by writing to
the 'state' key in the frontend area in xenstore. It is therefore
necessary for a XenDevice implementation to be notified whenever the
value of this key changes.

This patch adds code to do this as follows:

- an 'fd handler' is registered on the libxenstore handle which will be
  triggered whenever a 'watch' event occurs
- primitives are added to xen-bus-helper to add or remove watch events
- a list of Notifier objects is added to XenBus to provide a mechanism
  to call the appropriate 'watch handler' when its associated event
  occurs

The xen-qisk implementation is extended with a 'frontend_changed' method,
which calls as-yet stub 'connect' and 'disconnect' functions when the
relevant frontend state transitions occur. A subsequent patch will supply
a full implementation for these functions.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
---
 hw/block/trace-events           |   2 +
 hw/block/xen-qdisk.c            |  56 +++++++++++
 hw/xen/trace-events             |   4 +
 hw/xen/xen-bus-helper.c         |  28 ++++++
 hw/xen/xen-bus.c                | 205 +++++++++++++++++++++++++++++++++++++++-
 include/hw/xen/xen-bus-helper.h |   5 +
 include/hw/xen/xen-bus.h        |  15 +++
 7 files changed, 313 insertions(+), 2 deletions(-)

diff --git a/hw/block/trace-events b/hw/block/trace-events
index fd3c126ac1..8b95567560 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -130,4 +130,6 @@ xen_disk_free(char *name) "%s"
 
 # hw/block/xen-qdisk.c
 xen_qdisk_realize(uint32_t disk, uint32_t partition) "d%up%u"
+xen_qdisk_connect(uint32_t disk, uint32_t partition) "d%up%u"
+xen_qdisk_disconnect(uint32_t disk, uint32_t partition) "d%up%u"
 xen_qdisk_unrealize(uint32_t disk, uint32_t partition) "d%up%u"
diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
index 0859643f7d..35f7b70480 100644
--- a/hw/block/xen-qdisk.c
+++ b/hw/block/xen-qdisk.c
@@ -32,12 +32,67 @@ static void xen_qdisk_realize(XenDevice *xendev, Error **errp)
     trace_xen_qdisk_realize(vdev->disk, vdev->partition);
 }
 
+static void xen_qdisk_connect(XenQdiskDevice *qdiskdev, Error **errp)
+{
+    XenQdiskVdev *vdev = &qdiskdev->vdev;
+
+    trace_xen_qdisk_connect(vdev->disk, vdev->partition);
+}
+
+static void xen_qdisk_disconnect(XenQdiskDevice *qdiskdev, Error **errp)
+{
+    XenQdiskVdev *vdev = &qdiskdev->vdev;
+
+    trace_xen_qdisk_disconnect(vdev->disk, vdev->partition);
+}
+
+static void xen_qdisk_frontend_changed(XenDevice *xendev,
+                                       enum xenbus_state frontend_state,
+                                       Error **errp)
+{
+    XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
+    enum xenbus_state backend_state = xen_device_backend_get_state(xendev);
+    Error *local_err = NULL;
+
+    switch (frontend_state) {
+    case XenbusStateInitialised:
+    case XenbusStateConnected:
+        if (backend_state == XenbusStateConnected) {
+            break;
+        }
+
+        xen_qdisk_disconnect(qdiskdev, &error_fatal);
+        xen_qdisk_connect(qdiskdev, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            break;
+        }
+
+        xen_device_backend_set_state(xendev, XenbusStateConnected);
+        break;
+
+    case XenbusStateClosing:
+        xen_device_backend_set_state(xendev, XenbusStateClosing);
+        break;
+
+    case XenbusStateClosed:
+        xen_qdisk_disconnect(qdiskdev, &error_fatal);
+        xen_device_backend_set_state(xendev, XenbusStateClosed);
+        break;
+
+    default:
+        break;
+    }
+}
+
 static void xen_qdisk_unrealize(XenDevice *xendev, Error **errp)
 {
     XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
     XenQdiskVdev *vdev = &qdiskdev->vdev;
 
     trace_xen_qdisk_unrealize(vdev->disk, vdev->partition);
+
+    xen_qdisk_disconnect(qdiskdev, &error_fatal);
 }
 
 static char *disk_to_vbd_name(unsigned int disk)
@@ -246,6 +301,7 @@ static void xen_qdisk_class_init(ObjectClass *class, void *data)
     xendev_class->device = "vbd";
     xendev_class->get_name = xen_qdisk_get_name;
     xendev_class->realize = xen_qdisk_realize;
+    xendev_class->frontend_changed = xen_qdisk_frontend_changed;
     xendev_class->unrealize = xen_qdisk_unrealize;
 
     dev_class->desc = "Xen Qdisk Device";
diff --git a/hw/xen/trace-events b/hw/xen/trace-events
index fa8aea1da1..94c46c2e34 100644
--- a/hw/xen/trace-events
+++ b/hw/xen/trace-events
@@ -16,7 +16,11 @@ xen_domid_restrict(int err) "err: %u"
 # include/hw/xen/xen-bus.c
 xen_bus_realize(void) ""
 xen_bus_unrealize(void) ""
+xen_bus_add_watch(const char *node, const char *key, char *token) "node: %s key: %s token: %s"
+xen_bus_remove_watch(const char *node, const char *key, char *token) "node: %s key: %s token: %s"
+xen_bus_watch(const char *token) "token: %s"
 xen_device_realize(const char *type, char *name) "type: %s name: %s"
 xen_device_unrealize(const char *type, char *name) "type: %s name: %s"
 xen_device_backend_state(const char *type, char *name, const char *state) "type: %s name: %s -> %s"
 xen_device_frontend_state(const char *type, char *name, const char *state) "type: %s name: %s -> %s"
+xen_device_frontend_changed(const char *type, char *name) "type: %s name: %s"
diff --git a/hw/xen/xen-bus-helper.c b/hw/xen/xen-bus-helper.c
index d9ee2ed6a0..b44acc8047 100644
--- a/hw/xen/xen-bus-helper.c
+++ b/hw/xen/xen-bus-helper.c
@@ -122,3 +122,31 @@ int xs_node_scanf(struct xs_handle *xsh, const char *node, const char *key,
 
     return rc;
 }
+
+void xs_node_watch(struct xs_handle *xsh, const char *node, const char *key,
+                   char *token, Error **errp)
+{
+    char *path;
+
+    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
+        g_strdup(key);
+
+    if (!xs_watch(xsh, path, token)) {
+        error_setg_errno(errp, errno, "failed to watch path '%s'", path);
+    }
+
+    g_free(path);
+}
+
+void xs_node_unwatch(struct xs_handle *xsh, const char *node,
+                     const char *key, const char *token)
+{
+    char *path;
+
+    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
+        g_strdup(key);
+
+    xs_unwatch(xsh, path, token);
+
+    g_free(path);
+}
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index 663aa8e117..99988f8568 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -4,6 +4,9 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "qemu/main-loop.h"
+#include "qemu/uuid.h"
 #include "hw/hw.h"
 #include "hw/sysbus.h"
 #include "hw/xen/xen.h"
@@ -57,6 +60,78 @@ static char *xen_bus_get_dev_path(DeviceState *dev)
     return xen_device_get_backend_path(XEN_DEVICE(dev));
 }
 
+struct XenWatch {
+    char *node, *key;
+    char *token;
+    XenWatchHandler handler;
+    void *opaque;
+    Notifier notifier;
+};
+
+static void watch_notify(Notifier *n, void *data)
+{
+    XenWatch *watch = container_of(n, XenWatch, notifier);
+    const char *token = data;
+
+    if (!strcmp(watch->token, token)) {
+        watch->handler(watch->opaque);
+    }
+}
+
+static XenWatch *xen_bus_add_watch(XenBus *xenbus, const char *node,
+                                   const char *key, XenWatchHandler handler,
+                                   void *opaque, Error **errp)
+{
+    XenWatch *watch = g_new0(XenWatch, 1);
+    QemuUUID uuid;
+    Error *local_err = NULL;
+
+    qemu_uuid_generate(&uuid);
+    watch->token = qemu_uuid_unparse_strdup(&uuid);
+
+    trace_xen_bus_add_watch(node, key, watch->token);
+
+    watch->node = g_strdup(node);
+    watch->key = g_strdup(key);
+    watch->handler = handler;
+    watch->opaque = opaque;
+    watch->notifier.notify = watch_notify;
+
+    notifier_list_add(&xenbus->watch_notifiers, &watch->notifier);
+
+    xs_node_watch(xenbus->xsh, node, key, watch->token, &local_err);
+
+    if (local_err) {
+        error_propagate(errp, local_err);
+
+        notifier_remove(&watch->notifier);
+
+        g_free(watch->token);
+        g_free(watch->key);
+        g_free(watch->node);
+
+        g_free(watch);
+        watch = NULL;
+    }
+
+    return watch;
+}
+
+static void xen_bus_remove_watch(XenBus *xenbus, XenWatch *watch)
+{
+    trace_xen_bus_remove_watch(watch->node, watch->key, watch->token);
+
+    xs_node_unwatch(xenbus->xsh, watch->node, watch->key, watch->token);
+
+    notifier_remove(&watch->notifier);
+
+    g_free(watch->token);
+    g_free(watch->key);
+    g_free(watch->node);
+
+    g_free(watch);
+}
+
 static void xen_bus_unrealize(BusState *bus, Error **errp)
 {
     XenBus *xenbus = XEN_BUS(bus);
@@ -67,9 +142,34 @@ static void xen_bus_unrealize(BusState *bus, Error **errp)
         return;
     }
 
+    qemu_set_fd_handler(xs_fileno(xenbus->xsh), NULL, NULL, NULL);
+
     xs_close(xenbus->xsh);
 }
 
+static void xen_bus_watch(void *opaque)
+{
+    XenBus *xenbus = opaque;
+    char **v;
+    const char *token;
+    unsigned int n;
+
+    g_assert(xenbus->xsh);
+
+    v = xs_read_watch(xenbus->xsh, &n);
+    if (!v) {
+        return;
+    }
+
+    token = v[XS_WATCH_TOKEN];
+
+    trace_xen_bus_watch(token);
+
+    notifier_list_notify(&xenbus->watch_notifiers, (void *)token);
+
+    free(v);
+}
+
 static void xen_bus_realize(BusState *bus, Error **errp)
 {
     XenBus *xenbus = XEN_BUS(bus);
@@ -90,6 +190,9 @@ static void xen_bus_realize(BusState *bus, Error **errp)
         xenbus->backend_id = 0; /* Assume lack of node means dom0 */
     }
 
+    notifier_list_init(&xenbus->watch_notifiers);
+    qemu_set_fd_handler(xs_fileno(xenbus->xsh), xen_bus_watch, NULL,
+                        xenbus);
     return;
 
 fail:
@@ -127,8 +230,25 @@ static void xen_device_backend_printf(XenDevice *xendev, const char *key,
     va_end(ap);
 }
 
-static void xen_device_backend_set_state(XenDevice *xendev,
-                                         enum xenbus_state state)
+static int xen_device_backend_scanf(XenDevice *xendev, const char *key,
+                                    const char *fmt, ...)
+{
+    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
+    va_list ap;
+    int rc;
+
+    g_assert(xenbus->xsh);
+
+    va_start(ap, fmt);
+    rc = xs_node_vscanf(xenbus->xsh, xendev->backend_path, key, fmt,
+                        ap);
+    va_end(ap);
+
+    return rc;
+}
+
+void xen_device_backend_set_state(XenDevice *xendev,
+                                  enum xenbus_state state)
 {
     const char *type = object_get_typename(OBJECT(xendev));
 
@@ -143,6 +263,11 @@ static void xen_device_backend_set_state(XenDevice *xendev,
     xen_device_backend_printf(xendev, "state", "%u", state);
 }
 
+enum xenbus_state xen_device_backend_get_state(XenDevice *xendev)
+{
+    return xendev->backend_state;
+}
+
 static void xen_device_backend_create(XenDevice *xendev, Error **errp)
 {
     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
@@ -193,6 +318,23 @@ static void xen_device_frontend_printf(XenDevice *xendev, const char *key,
     va_end(ap);
 }
 
+static int xen_device_frontend_scanf(XenDevice *xendev, const char *key,
+                                      const char *fmt, ...)
+{
+    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
+    va_list ap;
+    int rc;
+
+    g_assert(xenbus->xsh);
+
+    va_start(ap, fmt);
+    rc = xs_node_vscanf(xenbus->xsh, xendev->frontend_path, key, fmt,
+                        ap);
+    va_end(ap);
+
+    return rc;
+}
+
 static void xen_device_frontend_set_state(XenDevice *xendev,
                                           enum xenbus_state state)
 {
@@ -209,6 +351,53 @@ static void xen_device_frontend_set_state(XenDevice *xendev,
     xen_device_frontend_printf(xendev, "state", "%u", state);
 }
 
+static void xen_device_frontend_changed(void *opaque)
+{
+    XenDevice *xendev = opaque;
+    XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
+    const char *type = object_get_typename(OBJECT(xendev));
+    enum xenbus_state state;
+
+    trace_xen_device_frontend_changed(type, xendev->name);
+
+    if (xen_device_frontend_scanf(xendev, "state", "%u", &state) != 1) {
+        state = XenbusStateUnknown;
+    }
+
+    xen_device_frontend_set_state(xendev, state);
+
+    if (xendev_class->frontend_changed) {
+        Error *local_err = NULL;
+
+        xendev_class->frontend_changed(xendev, state, &local_err);
+
+        if (local_err) {
+            const char *msg = error_get_pretty(local_err);
+
+            error_report("frontend change error: %s", msg);
+            error_free(local_err);
+        }
+    }
+
+    /*
+     * If a backend is still 'online' then its state should be cycled
+     * back round to InitWait in order for a new frontend instance to
+     * connect. This may happen when, for example, a frontend driver is
+     * re-installed or updated.
+     */
+    if (xendev->backend_state == XenbusStateClosed) {
+        unsigned int online;
+
+        if (xen_device_backend_scanf(xendev, "online", "%u", &online) != 1) {
+            online = 0;
+        }
+
+        if (online) {
+            xen_device_backend_set_state(xendev, XenbusStateInitWait);
+        }
+    }
+}
+
 static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
 {
     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
@@ -230,12 +419,24 @@ static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
         error_propagate(errp, local_err);
         error_prepend(errp, "failed to create frontend: ");
     }
+
+    xendev->frontend_state_watch =
+        xen_bus_add_watch(xenbus, xendev->frontend_path, "state",
+                          xen_device_frontend_changed, xendev, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to watch frontend state: ");
+    }
 }
 
 static void xen_device_frontend_destroy(XenDevice *xendev)
 {
     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
 
+    if (xendev->frontend_state_watch) {
+        xen_bus_remove_watch(xenbus, xendev->frontend_state_watch);
+    }
+
     if (!xendev->frontend_path) {
         return;
     }
diff --git a/include/hw/xen/xen-bus-helper.h b/include/hw/xen/xen-bus-helper.h
index 53570650db..3b88efaa0c 100644
--- a/include/hw/xen/xen-bus-helper.h
+++ b/include/hw/xen/xen-bus-helper.h
@@ -23,4 +23,9 @@ int xs_node_vscanf(struct xs_handle *xsh, const char *node, const char *key,
 int xs_node_scanf(struct xs_handle *xsh, const char *node, const char *key,
                   const char *fmt, ...);
 
+void xs_node_watch(struct xs_handle *xsh, const char *node, const char *key,
+                   char *token, Error **errp);
+void xs_node_unwatch(struct xs_handle *xsh, const char *node, const char *key,
+                     const char *token);
+
 #endif /* HW_XEN_BUS_HELPER_H */
diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h
index 434d1dbf58..954149e51b 100644
--- a/include/hw/xen/xen-bus.h
+++ b/include/hw/xen/xen-bus.h
@@ -8,6 +8,11 @@
 
 #include "hw/xen/xen_common.h"
 #include "hw/sysbus.h"
+#include "qemu/notify.h"
+
+typedef void (*XenWatchHandler)(void *opaque);
+
+typedef struct XenWatch XenWatch;
 
 typedef struct XenDevice {
     DeviceState qdev;
@@ -16,10 +21,14 @@ typedef struct XenDevice {
     char *backend_path, *frontend_path;
     enum xenbus_state backend_state, frontend_state;
     Notifier exit;
+    XenWatch *frontend_state_watch;
 } XenDevice;
 
 typedef char *(*XenDeviceGetName)(XenDevice *xendev, Error **errp);
 typedef void (*XenDeviceRealize)(XenDevice *xendev, Error **errp);
+typedef void (*XenDeviceFrontendChanged)(XenDevice *xendev,
+                                         enum xenbus_state frontend_state,
+                                         Error **errp);
 typedef void (*XenDeviceUnrealize)(XenDevice *xendev, Error **errp);
 
 typedef struct XenDeviceClass {
@@ -30,6 +39,7 @@ typedef struct XenDeviceClass {
     const char *device;
     XenDeviceGetName get_name;
     XenDeviceRealize realize;
+    XenDeviceFrontendChanged frontend_changed;
     XenDeviceUnrealize unrealize;
 } XenDeviceClass;
 
@@ -45,6 +55,7 @@ typedef struct XenBus {
     BusState qbus;
     domid_t backend_id;
     struct xs_handle *xsh;
+    NotifierList watch_notifiers;
 } XenBus;
 
 typedef struct XenBusClass {
@@ -62,4 +73,8 @@ typedef struct XenBusClass {
 
 void xen_bus_init(void);
 
+void xen_device_backend_set_state(XenDevice *xendev,
+                                  enum xenbus_state state);
+enum xenbus_state xen_device_backend_get_state(XenDevice *xendev);
+
 #endif /* HW_XEN_BUS_H */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [PATCH 05/18] xen: add xenstore watcher infratructure
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
                   ` (7 preceding siblings ...)
  2018-11-21 15:11 ` [Qemu-devel] [PATCH 05/18] xen: add xenstore watcher infratructure Paul Durrant
@ 2018-11-21 15:11 ` Paul Durrant
  2018-11-21 15:11   ` Paul Durrant
                   ` (16 subsequent siblings)
  25 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:11 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Kevin Wolf, Anthony Perard, Paul Durrant, Stefano Stabellini, Max Reitz

A Xen PV frontend communicates its state to the PV backend by writing to
the 'state' key in the frontend area in xenstore. It is therefore
necessary for a XenDevice implementation to be notified whenever the
value of this key changes.

This patch adds code to do this as follows:

- an 'fd handler' is registered on the libxenstore handle which will be
  triggered whenever a 'watch' event occurs
- primitives are added to xen-bus-helper to add or remove watch events
- a list of Notifier objects is added to XenBus to provide a mechanism
  to call the appropriate 'watch handler' when its associated event
  occurs

The xen-qisk implementation is extended with a 'frontend_changed' method,
which calls as-yet stub 'connect' and 'disconnect' functions when the
relevant frontend state transitions occur. A subsequent patch will supply
a full implementation for these functions.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
---
 hw/block/trace-events           |   2 +
 hw/block/xen-qdisk.c            |  56 +++++++++++
 hw/xen/trace-events             |   4 +
 hw/xen/xen-bus-helper.c         |  28 ++++++
 hw/xen/xen-bus.c                | 205 +++++++++++++++++++++++++++++++++++++++-
 include/hw/xen/xen-bus-helper.h |   5 +
 include/hw/xen/xen-bus.h        |  15 +++
 7 files changed, 313 insertions(+), 2 deletions(-)

diff --git a/hw/block/trace-events b/hw/block/trace-events
index fd3c126ac1..8b95567560 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -130,4 +130,6 @@ xen_disk_free(char *name) "%s"
 
 # hw/block/xen-qdisk.c
 xen_qdisk_realize(uint32_t disk, uint32_t partition) "d%up%u"
+xen_qdisk_connect(uint32_t disk, uint32_t partition) "d%up%u"
+xen_qdisk_disconnect(uint32_t disk, uint32_t partition) "d%up%u"
 xen_qdisk_unrealize(uint32_t disk, uint32_t partition) "d%up%u"
diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
index 0859643f7d..35f7b70480 100644
--- a/hw/block/xen-qdisk.c
+++ b/hw/block/xen-qdisk.c
@@ -32,12 +32,67 @@ static void xen_qdisk_realize(XenDevice *xendev, Error **errp)
     trace_xen_qdisk_realize(vdev->disk, vdev->partition);
 }
 
+static void xen_qdisk_connect(XenQdiskDevice *qdiskdev, Error **errp)
+{
+    XenQdiskVdev *vdev = &qdiskdev->vdev;
+
+    trace_xen_qdisk_connect(vdev->disk, vdev->partition);
+}
+
+static void xen_qdisk_disconnect(XenQdiskDevice *qdiskdev, Error **errp)
+{
+    XenQdiskVdev *vdev = &qdiskdev->vdev;
+
+    trace_xen_qdisk_disconnect(vdev->disk, vdev->partition);
+}
+
+static void xen_qdisk_frontend_changed(XenDevice *xendev,
+                                       enum xenbus_state frontend_state,
+                                       Error **errp)
+{
+    XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
+    enum xenbus_state backend_state = xen_device_backend_get_state(xendev);
+    Error *local_err = NULL;
+
+    switch (frontend_state) {
+    case XenbusStateInitialised:
+    case XenbusStateConnected:
+        if (backend_state == XenbusStateConnected) {
+            break;
+        }
+
+        xen_qdisk_disconnect(qdiskdev, &error_fatal);
+        xen_qdisk_connect(qdiskdev, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            break;
+        }
+
+        xen_device_backend_set_state(xendev, XenbusStateConnected);
+        break;
+
+    case XenbusStateClosing:
+        xen_device_backend_set_state(xendev, XenbusStateClosing);
+        break;
+
+    case XenbusStateClosed:
+        xen_qdisk_disconnect(qdiskdev, &error_fatal);
+        xen_device_backend_set_state(xendev, XenbusStateClosed);
+        break;
+
+    default:
+        break;
+    }
+}
+
 static void xen_qdisk_unrealize(XenDevice *xendev, Error **errp)
 {
     XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
     XenQdiskVdev *vdev = &qdiskdev->vdev;
 
     trace_xen_qdisk_unrealize(vdev->disk, vdev->partition);
+
+    xen_qdisk_disconnect(qdiskdev, &error_fatal);
 }
 
 static char *disk_to_vbd_name(unsigned int disk)
@@ -246,6 +301,7 @@ static void xen_qdisk_class_init(ObjectClass *class, void *data)
     xendev_class->device = "vbd";
     xendev_class->get_name = xen_qdisk_get_name;
     xendev_class->realize = xen_qdisk_realize;
+    xendev_class->frontend_changed = xen_qdisk_frontend_changed;
     xendev_class->unrealize = xen_qdisk_unrealize;
 
     dev_class->desc = "Xen Qdisk Device";
diff --git a/hw/xen/trace-events b/hw/xen/trace-events
index fa8aea1da1..94c46c2e34 100644
--- a/hw/xen/trace-events
+++ b/hw/xen/trace-events
@@ -16,7 +16,11 @@ xen_domid_restrict(int err) "err: %u"
 # include/hw/xen/xen-bus.c
 xen_bus_realize(void) ""
 xen_bus_unrealize(void) ""
+xen_bus_add_watch(const char *node, const char *key, char *token) "node: %s key: %s token: %s"
+xen_bus_remove_watch(const char *node, const char *key, char *token) "node: %s key: %s token: %s"
+xen_bus_watch(const char *token) "token: %s"
 xen_device_realize(const char *type, char *name) "type: %s name: %s"
 xen_device_unrealize(const char *type, char *name) "type: %s name: %s"
 xen_device_backend_state(const char *type, char *name, const char *state) "type: %s name: %s -> %s"
 xen_device_frontend_state(const char *type, char *name, const char *state) "type: %s name: %s -> %s"
+xen_device_frontend_changed(const char *type, char *name) "type: %s name: %s"
diff --git a/hw/xen/xen-bus-helper.c b/hw/xen/xen-bus-helper.c
index d9ee2ed6a0..b44acc8047 100644
--- a/hw/xen/xen-bus-helper.c
+++ b/hw/xen/xen-bus-helper.c
@@ -122,3 +122,31 @@ int xs_node_scanf(struct xs_handle *xsh, const char *node, const char *key,
 
     return rc;
 }
+
+void xs_node_watch(struct xs_handle *xsh, const char *node, const char *key,
+                   char *token, Error **errp)
+{
+    char *path;
+
+    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
+        g_strdup(key);
+
+    if (!xs_watch(xsh, path, token)) {
+        error_setg_errno(errp, errno, "failed to watch path '%s'", path);
+    }
+
+    g_free(path);
+}
+
+void xs_node_unwatch(struct xs_handle *xsh, const char *node,
+                     const char *key, const char *token)
+{
+    char *path;
+
+    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
+        g_strdup(key);
+
+    xs_unwatch(xsh, path, token);
+
+    g_free(path);
+}
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index 663aa8e117..99988f8568 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -4,6 +4,9 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "qemu/main-loop.h"
+#include "qemu/uuid.h"
 #include "hw/hw.h"
 #include "hw/sysbus.h"
 #include "hw/xen/xen.h"
@@ -57,6 +60,78 @@ static char *xen_bus_get_dev_path(DeviceState *dev)
     return xen_device_get_backend_path(XEN_DEVICE(dev));
 }
 
+struct XenWatch {
+    char *node, *key;
+    char *token;
+    XenWatchHandler handler;
+    void *opaque;
+    Notifier notifier;
+};
+
+static void watch_notify(Notifier *n, void *data)
+{
+    XenWatch *watch = container_of(n, XenWatch, notifier);
+    const char *token = data;
+
+    if (!strcmp(watch->token, token)) {
+        watch->handler(watch->opaque);
+    }
+}
+
+static XenWatch *xen_bus_add_watch(XenBus *xenbus, const char *node,
+                                   const char *key, XenWatchHandler handler,
+                                   void *opaque, Error **errp)
+{
+    XenWatch *watch = g_new0(XenWatch, 1);
+    QemuUUID uuid;
+    Error *local_err = NULL;
+
+    qemu_uuid_generate(&uuid);
+    watch->token = qemu_uuid_unparse_strdup(&uuid);
+
+    trace_xen_bus_add_watch(node, key, watch->token);
+
+    watch->node = g_strdup(node);
+    watch->key = g_strdup(key);
+    watch->handler = handler;
+    watch->opaque = opaque;
+    watch->notifier.notify = watch_notify;
+
+    notifier_list_add(&xenbus->watch_notifiers, &watch->notifier);
+
+    xs_node_watch(xenbus->xsh, node, key, watch->token, &local_err);
+
+    if (local_err) {
+        error_propagate(errp, local_err);
+
+        notifier_remove(&watch->notifier);
+
+        g_free(watch->token);
+        g_free(watch->key);
+        g_free(watch->node);
+
+        g_free(watch);
+        watch = NULL;
+    }
+
+    return watch;
+}
+
+static void xen_bus_remove_watch(XenBus *xenbus, XenWatch *watch)
+{
+    trace_xen_bus_remove_watch(watch->node, watch->key, watch->token);
+
+    xs_node_unwatch(xenbus->xsh, watch->node, watch->key, watch->token);
+
+    notifier_remove(&watch->notifier);
+
+    g_free(watch->token);
+    g_free(watch->key);
+    g_free(watch->node);
+
+    g_free(watch);
+}
+
 static void xen_bus_unrealize(BusState *bus, Error **errp)
 {
     XenBus *xenbus = XEN_BUS(bus);
@@ -67,9 +142,34 @@ static void xen_bus_unrealize(BusState *bus, Error **errp)
         return;
     }
 
+    qemu_set_fd_handler(xs_fileno(xenbus->xsh), NULL, NULL, NULL);
+
     xs_close(xenbus->xsh);
 }
 
+static void xen_bus_watch(void *opaque)
+{
+    XenBus *xenbus = opaque;
+    char **v;
+    const char *token;
+    unsigned int n;
+
+    g_assert(xenbus->xsh);
+
+    v = xs_read_watch(xenbus->xsh, &n);
+    if (!v) {
+        return;
+    }
+
+    token = v[XS_WATCH_TOKEN];
+
+    trace_xen_bus_watch(token);
+
+    notifier_list_notify(&xenbus->watch_notifiers, (void *)token);
+
+    free(v);
+}
+
 static void xen_bus_realize(BusState *bus, Error **errp)
 {
     XenBus *xenbus = XEN_BUS(bus);
@@ -90,6 +190,9 @@ static void xen_bus_realize(BusState *bus, Error **errp)
         xenbus->backend_id = 0; /* Assume lack of node means dom0 */
     }
 
+    notifier_list_init(&xenbus->watch_notifiers);
+    qemu_set_fd_handler(xs_fileno(xenbus->xsh), xen_bus_watch, NULL,
+                        xenbus);
     return;
 
 fail:
@@ -127,8 +230,25 @@ static void xen_device_backend_printf(XenDevice *xendev, const char *key,
     va_end(ap);
 }
 
-static void xen_device_backend_set_state(XenDevice *xendev,
-                                         enum xenbus_state state)
+static int xen_device_backend_scanf(XenDevice *xendev, const char *key,
+                                    const char *fmt, ...)
+{
+    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
+    va_list ap;
+    int rc;
+
+    g_assert(xenbus->xsh);
+
+    va_start(ap, fmt);
+    rc = xs_node_vscanf(xenbus->xsh, xendev->backend_path, key, fmt,
+                        ap);
+    va_end(ap);
+
+    return rc;
+}
+
+void xen_device_backend_set_state(XenDevice *xendev,
+                                  enum xenbus_state state)
 {
     const char *type = object_get_typename(OBJECT(xendev));
 
@@ -143,6 +263,11 @@ static void xen_device_backend_set_state(XenDevice *xendev,
     xen_device_backend_printf(xendev, "state", "%u", state);
 }
 
+enum xenbus_state xen_device_backend_get_state(XenDevice *xendev)
+{
+    return xendev->backend_state;
+}
+
 static void xen_device_backend_create(XenDevice *xendev, Error **errp)
 {
     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
@@ -193,6 +318,23 @@ static void xen_device_frontend_printf(XenDevice *xendev, const char *key,
     va_end(ap);
 }
 
+static int xen_device_frontend_scanf(XenDevice *xendev, const char *key,
+                                      const char *fmt, ...)
+{
+    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
+    va_list ap;
+    int rc;
+
+    g_assert(xenbus->xsh);
+
+    va_start(ap, fmt);
+    rc = xs_node_vscanf(xenbus->xsh, xendev->frontend_path, key, fmt,
+                        ap);
+    va_end(ap);
+
+    return rc;
+}
+
 static void xen_device_frontend_set_state(XenDevice *xendev,
                                           enum xenbus_state state)
 {
@@ -209,6 +351,53 @@ static void xen_device_frontend_set_state(XenDevice *xendev,
     xen_device_frontend_printf(xendev, "state", "%u", state);
 }
 
+static void xen_device_frontend_changed(void *opaque)
+{
+    XenDevice *xendev = opaque;
+    XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
+    const char *type = object_get_typename(OBJECT(xendev));
+    enum xenbus_state state;
+
+    trace_xen_device_frontend_changed(type, xendev->name);
+
+    if (xen_device_frontend_scanf(xendev, "state", "%u", &state) != 1) {
+        state = XenbusStateUnknown;
+    }
+
+    xen_device_frontend_set_state(xendev, state);
+
+    if (xendev_class->frontend_changed) {
+        Error *local_err = NULL;
+
+        xendev_class->frontend_changed(xendev, state, &local_err);
+
+        if (local_err) {
+            const char *msg = error_get_pretty(local_err);
+
+            error_report("frontend change error: %s", msg);
+            error_free(local_err);
+        }
+    }
+
+    /*
+     * If a backend is still 'online' then its state should be cycled
+     * back round to InitWait in order for a new frontend instance to
+     * connect. This may happen when, for example, a frontend driver is
+     * re-installed or updated.
+     */
+    if (xendev->backend_state == XenbusStateClosed) {
+        unsigned int online;
+
+        if (xen_device_backend_scanf(xendev, "online", "%u", &online) != 1) {
+            online = 0;
+        }
+
+        if (online) {
+            xen_device_backend_set_state(xendev, XenbusStateInitWait);
+        }
+    }
+}
+
 static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
 {
     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
@@ -230,12 +419,24 @@ static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
         error_propagate(errp, local_err);
         error_prepend(errp, "failed to create frontend: ");
     }
+
+    xendev->frontend_state_watch =
+        xen_bus_add_watch(xenbus, xendev->frontend_path, "state",
+                          xen_device_frontend_changed, xendev, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to watch frontend state: ");
+    }
 }
 
 static void xen_device_frontend_destroy(XenDevice *xendev)
 {
     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
 
+    if (xendev->frontend_state_watch) {
+        xen_bus_remove_watch(xenbus, xendev->frontend_state_watch);
+    }
+
     if (!xendev->frontend_path) {
         return;
     }
diff --git a/include/hw/xen/xen-bus-helper.h b/include/hw/xen/xen-bus-helper.h
index 53570650db..3b88efaa0c 100644
--- a/include/hw/xen/xen-bus-helper.h
+++ b/include/hw/xen/xen-bus-helper.h
@@ -23,4 +23,9 @@ int xs_node_vscanf(struct xs_handle *xsh, const char *node, const char *key,
 int xs_node_scanf(struct xs_handle *xsh, const char *node, const char *key,
                   const char *fmt, ...);
 
+void xs_node_watch(struct xs_handle *xsh, const char *node, const char *key,
+                   char *token, Error **errp);
+void xs_node_unwatch(struct xs_handle *xsh, const char *node, const char *key,
+                     const char *token);
+
 #endif /* HW_XEN_BUS_HELPER_H */
diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h
index 434d1dbf58..954149e51b 100644
--- a/include/hw/xen/xen-bus.h
+++ b/include/hw/xen/xen-bus.h
@@ -8,6 +8,11 @@
 
 #include "hw/xen/xen_common.h"
 #include "hw/sysbus.h"
+#include "qemu/notify.h"
+
+typedef void (*XenWatchHandler)(void *opaque);
+
+typedef struct XenWatch XenWatch;
 
 typedef struct XenDevice {
     DeviceState qdev;
@@ -16,10 +21,14 @@ typedef struct XenDevice {
     char *backend_path, *frontend_path;
     enum xenbus_state backend_state, frontend_state;
     Notifier exit;
+    XenWatch *frontend_state_watch;
 } XenDevice;
 
 typedef char *(*XenDeviceGetName)(XenDevice *xendev, Error **errp);
 typedef void (*XenDeviceRealize)(XenDevice *xendev, Error **errp);
+typedef void (*XenDeviceFrontendChanged)(XenDevice *xendev,
+                                         enum xenbus_state frontend_state,
+                                         Error **errp);
 typedef void (*XenDeviceUnrealize)(XenDevice *xendev, Error **errp);
 
 typedef struct XenDeviceClass {
@@ -30,6 +39,7 @@ typedef struct XenDeviceClass {
     const char *device;
     XenDeviceGetName get_name;
     XenDeviceRealize realize;
+    XenDeviceFrontendChanged frontend_changed;
     XenDeviceUnrealize unrealize;
 } XenDeviceClass;
 
@@ -45,6 +55,7 @@ typedef struct XenBus {
     BusState qbus;
     domid_t backend_id;
     struct xs_handle *xsh;
+    NotifierList watch_notifiers;
 } XenBus;
 
 typedef struct XenBusClass {
@@ -62,4 +73,8 @@ typedef struct XenBusClass {
 
 void xen_bus_init(void);
 
+void xen_device_backend_set_state(XenDevice *xendev,
+                                  enum xenbus_state state);
+enum xenbus_state xen_device_backend_get_state(XenDevice *xendev);
+
 #endif /* HW_XEN_BUS_H */
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [Qemu-devel] [PATCH 06/18] xen: add grant table interface for XenDevice-s
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
@ 2018-11-21 15:11   ` Paul Durrant
  2018-11-21 15:11 ` [Qemu-devel] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy Paul Durrant
                     ` (24 subsequent siblings)
  25 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:11 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Paul Durrant, Stefano Stabellini, Anthony Perard

The legacy PV backend infrastructure provides functions to map, unmap and
copy pages granted by frontends. Similar functionality will be required
by XenDevice implementations so this patch adds the necessary support.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
---
 hw/xen/xen-bus.c         | 145 +++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/xen/xen-bus.h |  25 ++++++++
 2 files changed, 170 insertions(+)

diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index 99988f8568..7a152d2a2f 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -447,6 +447,138 @@ static void xen_device_frontend_destroy(XenDevice *xendev)
     g_free(xendev->frontend_path);
 }
 
+void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs,
+                                   Error **errp)
+{
+    if (xengnttab_set_max_grants(xendev->xgth, nr_refs)) {
+        error_setg_errno(errp, errno, "xengnttab_set_max_grants failed");
+    }
+}
+
+void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs,
+                                unsigned int nr_refs, int prot,
+                                Error **errp)
+{
+    void *map = xengnttab_map_domain_grant_refs(xendev->xgth, nr_refs,
+                                                xendev->frontend_id, refs,
+                                                prot);
+
+    if (!map) {
+        error_setg_errno(errp, errno,
+                         "xengnttab_map_domain_grant_refs failed");
+    }
+
+    return map;
+}
+
+void xen_device_unmap_grant_refs(XenDevice *xendev, void *map,
+                                 unsigned int nr_refs, Error **errp)
+{
+    if (xengnttab_unmap(xendev->xgth, map, nr_refs)) {
+        error_setg_errno(errp, errno, "xengnttab_unmap failed");
+    }
+}
+
+static void compat_copy_grant_refs(XenDevice *xendev, bool to_domain,
+                                   XenDeviceGrantCopySegment segs[],
+                                   unsigned int nr_segs, Error **errp)
+{
+    uint32_t *refs = g_new(uint32_t, nr_segs);
+    int prot = to_domain ? PROT_WRITE : PROT_READ;
+    void *map;
+    unsigned int i;
+
+    for (i = 0; i < nr_segs; i++) {
+        XenDeviceGrantCopySegment *seg = &segs[i];
+
+        refs[i] = to_domain ? seg->dest.foreign.ref :
+            seg->source.foreign.ref;
+    }
+
+    map = xengnttab_map_domain_grant_refs(xendev->xgth, nr_segs,
+                                          xendev->frontend_id, refs,
+                                          prot);
+    if (!map) {
+        error_setg_errno(errp, errno,
+                         "xengnttab_map_domain_grant_refs failed");
+        goto done;
+    }
+
+    for (i = 0; i < nr_segs; i++) {
+        XenDeviceGrantCopySegment *seg = &segs[i];
+        void *page = map + (i * XC_PAGE_SIZE);
+
+        if (to_domain) {
+            memcpy(page + seg->dest.foreign.offset, seg->source.virt,
+                   seg->len);
+        } else {
+            memcpy(seg->dest.virt, page + seg->source.foreign.offset,
+                   seg->len);
+        }
+    }
+
+    if (xengnttab_unmap(xendev->xgth, map, nr_segs)) {
+        error_setg_errno(errp, errno, "xengnttab_unmap failed");
+    }
+
+done:
+    g_free(refs);
+}
+
+void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain,
+                                XenDeviceGrantCopySegment segs[],
+                                unsigned int nr_segs, Error **errp)
+{
+    xengnttab_grant_copy_segment_t *xengnttab_segs;
+    unsigned int i;
+
+    if (!xendev->feature_grant_copy) {
+        compat_copy_grant_refs(xendev, to_domain, segs, nr_segs, errp);
+        return;
+    }
+
+    xengnttab_segs = g_new0(xengnttab_grant_copy_segment_t, nr_segs);
+
+    for (i = 0; i < nr_segs; i++) {
+        XenDeviceGrantCopySegment *seg = &segs[i];
+        xengnttab_grant_copy_segment_t *xengnttab_seg = &xengnttab_segs[i];
+
+        if (to_domain) {
+            xengnttab_seg->flags = GNTCOPY_dest_gref;
+            xengnttab_seg->dest.foreign.domid = xendev->frontend_id;
+            xengnttab_seg->dest.foreign.ref = seg->dest.foreign.ref;
+            xengnttab_seg->dest.foreign.offset = seg->dest.foreign.offset;
+            xengnttab_seg->source.virt = seg->source.virt;
+        } else {
+            xengnttab_seg->flags = GNTCOPY_source_gref;
+            xengnttab_seg->source.foreign.domid = xendev->frontend_id;
+            xengnttab_seg->source.foreign.ref = seg->source.foreign.ref;
+            xengnttab_seg->source.foreign.offset =
+                seg->source.foreign.offset;
+            xengnttab_seg->dest.virt = seg->dest.virt;
+        }
+
+        xengnttab_seg->len = seg->len;
+    }
+
+    if (xengnttab_grant_copy(xendev->xgth, nr_segs, xengnttab_segs)) {
+        error_setg_errno(errp, errno, "xengnttab_grant_copy failed");
+        goto done;
+    }
+
+    for (i = 0; i < nr_segs; i++) {
+        xengnttab_grant_copy_segment_t *xengnttab_seg = &xengnttab_segs[i];
+
+        if (xengnttab_seg->status != GNTST_okay) {
+            error_setg(errp, "xengnttab_grant_copy seg[%u] failed", i);
+            break;
+        }
+    }
+
+done:
+    g_free(xengnttab_segs);
+}
+
 static void xen_device_unrealize(DeviceState *dev, Error **errp)
 {
     XenDevice *xendev = XEN_DEVICE(dev);
@@ -470,6 +602,10 @@ static void xen_device_unrealize(DeviceState *dev, Error **errp)
     xen_device_frontend_destroy(xendev);
     xen_device_backend_destroy(xendev);
 
+    if (xendev->xgth) {
+        xengnttab_close(xendev->xgth);
+    }
+
     g_free(xendev->name);
 }
 
@@ -511,6 +647,15 @@ static void xen_device_realize(DeviceState *dev, Error **errp)
 
     trace_xen_device_realize(type, xendev->name);
 
+    xendev->xgth = xengnttab_open(NULL, 0);
+    if (!xendev->xgth) {
+        error_setg_errno(errp, errno, "failed xengnttab_open");
+        goto unrealize;
+    }
+
+    xendev->feature_grant_copy =
+        (xengnttab_grant_copy(xendev->xgth, 0, NULL) == 0);
+
     xen_device_backend_create(xendev, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h
index 954149e51b..db14d49027 100644
--- a/include/hw/xen/xen-bus.h
+++ b/include/hw/xen/xen-bus.h
@@ -22,6 +22,8 @@ typedef struct XenDevice {
     enum xenbus_state backend_state, frontend_state;
     Notifier exit;
     XenWatch *frontend_state_watch;
+    xengnttab_handle *xgth;
+    bool feature_grant_copy;
 } XenDevice;
 
 typedef char *(*XenDeviceGetName)(XenDevice *xendev, Error **errp);
@@ -77,4 +79,27 @@ void xen_device_backend_set_state(XenDevice *xendev,
                                   enum xenbus_state state);
 enum xenbus_state xen_device_backend_get_state(XenDevice *xendev);
 
+void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs,
+                                   Error **errp);
+void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs,
+                                unsigned int nr_refs, int prot,
+                                Error **errp);
+void xen_device_unmap_grant_refs(XenDevice *xendev, void *map,
+                                 unsigned int nr_refs, Error **errp);
+
+typedef struct XenDeviceGrantCopySegment {
+    union {
+        void *virt;
+        struct {
+            uint32_t ref;
+            off_t offset;
+        } foreign;
+    } source, dest;
+    size_t len;
+} XenDeviceGrantCopySegment;
+
+void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain,
+                                XenDeviceGrantCopySegment segs[],
+                                unsigned int nr_segs, Error **errp);
+
 #endif /* HW_XEN_BUS_H */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [PATCH 06/18] xen: add grant table interface for XenDevice-s
@ 2018-11-21 15:11   ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:11 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Anthony Perard, Paul Durrant, Stefano Stabellini

The legacy PV backend infrastructure provides functions to map, unmap and
copy pages granted by frontends. Similar functionality will be required
by XenDevice implementations so this patch adds the necessary support.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
---
 hw/xen/xen-bus.c         | 145 +++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/xen/xen-bus.h |  25 ++++++++
 2 files changed, 170 insertions(+)

diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index 99988f8568..7a152d2a2f 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -447,6 +447,138 @@ static void xen_device_frontend_destroy(XenDevice *xendev)
     g_free(xendev->frontend_path);
 }
 
+void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs,
+                                   Error **errp)
+{
+    if (xengnttab_set_max_grants(xendev->xgth, nr_refs)) {
+        error_setg_errno(errp, errno, "xengnttab_set_max_grants failed");
+    }
+}
+
+void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs,
+                                unsigned int nr_refs, int prot,
+                                Error **errp)
+{
+    void *map = xengnttab_map_domain_grant_refs(xendev->xgth, nr_refs,
+                                                xendev->frontend_id, refs,
+                                                prot);
+
+    if (!map) {
+        error_setg_errno(errp, errno,
+                         "xengnttab_map_domain_grant_refs failed");
+    }
+
+    return map;
+}
+
+void xen_device_unmap_grant_refs(XenDevice *xendev, void *map,
+                                 unsigned int nr_refs, Error **errp)
+{
+    if (xengnttab_unmap(xendev->xgth, map, nr_refs)) {
+        error_setg_errno(errp, errno, "xengnttab_unmap failed");
+    }
+}
+
+static void compat_copy_grant_refs(XenDevice *xendev, bool to_domain,
+                                   XenDeviceGrantCopySegment segs[],
+                                   unsigned int nr_segs, Error **errp)
+{
+    uint32_t *refs = g_new(uint32_t, nr_segs);
+    int prot = to_domain ? PROT_WRITE : PROT_READ;
+    void *map;
+    unsigned int i;
+
+    for (i = 0; i < nr_segs; i++) {
+        XenDeviceGrantCopySegment *seg = &segs[i];
+
+        refs[i] = to_domain ? seg->dest.foreign.ref :
+            seg->source.foreign.ref;
+    }
+
+    map = xengnttab_map_domain_grant_refs(xendev->xgth, nr_segs,
+                                          xendev->frontend_id, refs,
+                                          prot);
+    if (!map) {
+        error_setg_errno(errp, errno,
+                         "xengnttab_map_domain_grant_refs failed");
+        goto done;
+    }
+
+    for (i = 0; i < nr_segs; i++) {
+        XenDeviceGrantCopySegment *seg = &segs[i];
+        void *page = map + (i * XC_PAGE_SIZE);
+
+        if (to_domain) {
+            memcpy(page + seg->dest.foreign.offset, seg->source.virt,
+                   seg->len);
+        } else {
+            memcpy(seg->dest.virt, page + seg->source.foreign.offset,
+                   seg->len);
+        }
+    }
+
+    if (xengnttab_unmap(xendev->xgth, map, nr_segs)) {
+        error_setg_errno(errp, errno, "xengnttab_unmap failed");
+    }
+
+done:
+    g_free(refs);
+}
+
+void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain,
+                                XenDeviceGrantCopySegment segs[],
+                                unsigned int nr_segs, Error **errp)
+{
+    xengnttab_grant_copy_segment_t *xengnttab_segs;
+    unsigned int i;
+
+    if (!xendev->feature_grant_copy) {
+        compat_copy_grant_refs(xendev, to_domain, segs, nr_segs, errp);
+        return;
+    }
+
+    xengnttab_segs = g_new0(xengnttab_grant_copy_segment_t, nr_segs);
+
+    for (i = 0; i < nr_segs; i++) {
+        XenDeviceGrantCopySegment *seg = &segs[i];
+        xengnttab_grant_copy_segment_t *xengnttab_seg = &xengnttab_segs[i];
+
+        if (to_domain) {
+            xengnttab_seg->flags = GNTCOPY_dest_gref;
+            xengnttab_seg->dest.foreign.domid = xendev->frontend_id;
+            xengnttab_seg->dest.foreign.ref = seg->dest.foreign.ref;
+            xengnttab_seg->dest.foreign.offset = seg->dest.foreign.offset;
+            xengnttab_seg->source.virt = seg->source.virt;
+        } else {
+            xengnttab_seg->flags = GNTCOPY_source_gref;
+            xengnttab_seg->source.foreign.domid = xendev->frontend_id;
+            xengnttab_seg->source.foreign.ref = seg->source.foreign.ref;
+            xengnttab_seg->source.foreign.offset =
+                seg->source.foreign.offset;
+            xengnttab_seg->dest.virt = seg->dest.virt;
+        }
+
+        xengnttab_seg->len = seg->len;
+    }
+
+    if (xengnttab_grant_copy(xendev->xgth, nr_segs, xengnttab_segs)) {
+        error_setg_errno(errp, errno, "xengnttab_grant_copy failed");
+        goto done;
+    }
+
+    for (i = 0; i < nr_segs; i++) {
+        xengnttab_grant_copy_segment_t *xengnttab_seg = &xengnttab_segs[i];
+
+        if (xengnttab_seg->status != GNTST_okay) {
+            error_setg(errp, "xengnttab_grant_copy seg[%u] failed", i);
+            break;
+        }
+    }
+
+done:
+    g_free(xengnttab_segs);
+}
+
 static void xen_device_unrealize(DeviceState *dev, Error **errp)
 {
     XenDevice *xendev = XEN_DEVICE(dev);
@@ -470,6 +602,10 @@ static void xen_device_unrealize(DeviceState *dev, Error **errp)
     xen_device_frontend_destroy(xendev);
     xen_device_backend_destroy(xendev);
 
+    if (xendev->xgth) {
+        xengnttab_close(xendev->xgth);
+    }
+
     g_free(xendev->name);
 }
 
@@ -511,6 +647,15 @@ static void xen_device_realize(DeviceState *dev, Error **errp)
 
     trace_xen_device_realize(type, xendev->name);
 
+    xendev->xgth = xengnttab_open(NULL, 0);
+    if (!xendev->xgth) {
+        error_setg_errno(errp, errno, "failed xengnttab_open");
+        goto unrealize;
+    }
+
+    xendev->feature_grant_copy =
+        (xengnttab_grant_copy(xendev->xgth, 0, NULL) == 0);
+
     xen_device_backend_create(xendev, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h
index 954149e51b..db14d49027 100644
--- a/include/hw/xen/xen-bus.h
+++ b/include/hw/xen/xen-bus.h
@@ -22,6 +22,8 @@ typedef struct XenDevice {
     enum xenbus_state backend_state, frontend_state;
     Notifier exit;
     XenWatch *frontend_state_watch;
+    xengnttab_handle *xgth;
+    bool feature_grant_copy;
 } XenDevice;
 
 typedef char *(*XenDeviceGetName)(XenDevice *xendev, Error **errp);
@@ -77,4 +79,27 @@ void xen_device_backend_set_state(XenDevice *xendev,
                                   enum xenbus_state state);
 enum xenbus_state xen_device_backend_get_state(XenDevice *xendev);
 
+void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs,
+                                   Error **errp);
+void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs,
+                                unsigned int nr_refs, int prot,
+                                Error **errp);
+void xen_device_unmap_grant_refs(XenDevice *xendev, void *map,
+                                 unsigned int nr_refs, Error **errp);
+
+typedef struct XenDeviceGrantCopySegment {
+    union {
+        void *virt;
+        struct {
+            uint32_t ref;
+            off_t offset;
+        } foreign;
+    } source, dest;
+    size_t len;
+} XenDeviceGrantCopySegment;
+
+void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain,
+                                XenDeviceGrantCopySegment segs[],
+                                unsigned int nr_segs, Error **errp);
+
 #endif /* HW_XEN_BUS_H */
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [Qemu-devel] [PATCH 07/18] xen: add event channel interface for XenDevice-s
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
                   ` (10 preceding siblings ...)
  2018-11-21 15:12 ` [PATCH 07/18] xen: add event channel " Paul Durrant
@ 2018-11-21 15:12 ` Paul Durrant
  2018-12-03 16:24     ` Anthony PERARD
  2018-11-21 15:12   ` Paul Durrant
                   ` (13 subsequent siblings)
  25 siblings, 1 reply; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Paul Durrant, Stefano Stabellini, Anthony Perard

The legacy PV backend infrastructure provides functions to bind, unbind
and send notifications to event channnels. Similar functionality will be
required by XenDevice implementations so this patch adds the necessary
support.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
---
 hw/xen/xen-bus.c         | 84 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/xen/xen-bus.h | 16 +++++++++
 2 files changed, 100 insertions(+)

diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index 7a152d2a2f..64c8af54b0 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -579,6 +579,65 @@ done:
     g_free(xengnttab_segs);
 }
 
+struct XenEventChannel {
+    unsigned int local_port;
+    XenEventHandler handler;
+    void *opaque;
+    Notifier notifier;
+};
+
+static void event_notify(Notifier *n, void *data)
+{
+    XenEventChannel *channel = container_of(n, XenEventChannel, notifier);
+    unsigned long port = (unsigned long)data;
+
+    if (port == channel->local_port) {
+        channel->handler(channel->opaque);
+    }
+}
+
+XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev,
+                                               unsigned int port,
+                                               XenEventHandler handler,
+                                               void *opaque, Error **errp)
+{
+    XenEventChannel *channel = g_new0(XenEventChannel, 1);
+
+    channel->local_port = xenevtchn_bind_interdomain(xendev->xeh,
+                                                     xendev->frontend_id,
+                                                     port);
+    if (xendev->local_port < 0) {
+        error_setg_errno(errp, errno, "xenevtchn_bind_interdomain failed");
+
+        g_free(channel);
+        return NULL;
+    }
+
+    channel->handler = handler;
+    channel->opaque = opaque;
+    channel->notifier.notify = event_notify;
+
+    notifier_list_add(&xendev->event_notifiers, &channel->notifier);
+
+    return channel;
+}
+
+void xen_device_notify_event_channel(XenDevice *xendev,
+                                     XenEventChannel *channel)
+{
+    xenevtchn_notify(xendev->xeh, channel->local_port);
+}
+
+void xen_device_unbind_event_channel(XenDevice *xendev,
+                                     XenEventChannel *channel)
+{
+    notifier_remove(&channel->notifier);
+
+    xenevtchn_unbind(xendev->xeh, channel->local_port);
+
+    g_free(channel);
+}
+
 static void xen_device_unrealize(DeviceState *dev, Error **errp)
 {
     XenDevice *xendev = XEN_DEVICE(dev);
@@ -602,6 +661,11 @@ static void xen_device_unrealize(DeviceState *dev, Error **errp)
     xen_device_frontend_destroy(xendev);
     xen_device_backend_destroy(xendev);
 
+    if (xendev->xeh) {
+        qemu_set_fd_handler(xenevtchn_fd(xendev->xeh), NULL, NULL, NULL);
+        xenevtchn_close(xendev->xeh);
+    }
+
     if (xendev->xgth) {
         xengnttab_close(xendev->xgth);
     }
@@ -616,6 +680,16 @@ static void xen_device_exit(Notifier *n, void *data)
     xen_device_unrealize(DEVICE(xendev), &error_abort);
 }
 
+static void xen_device_event(void *opaque)
+{
+    XenDevice *xendev = opaque;
+    unsigned long port = xenevtchn_pending(xendev->xeh);
+
+    notifier_list_notify(&xendev->event_notifiers, (void *)port);
+
+    xenevtchn_unmask(xendev->xeh, port);
+}
+
 static void xen_device_realize(DeviceState *dev, Error **errp)
 {
     XenDevice *xendev = XEN_DEVICE(dev);
@@ -656,6 +730,16 @@ static void xen_device_realize(DeviceState *dev, Error **errp)
     xendev->feature_grant_copy =
         (xengnttab_grant_copy(xendev->xgth, 0, NULL) == 0);
 
+    xendev->xeh = xenevtchn_open(NULL, 0);
+    if (!xendev->xeh) {
+        error_setg_errno(errp, errno, "failed xenevtchn_open");
+        goto unrealize;
+    }
+
+    notifier_list_init(&xendev->event_notifiers);
+    qemu_set_fd_handler(xenevtchn_fd(xendev->xeh), xen_device_event, NULL,
+                        xendev);
+
     xen_device_backend_create(xendev, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h
index db14d49027..386f6bfc93 100644
--- a/include/hw/xen/xen-bus.h
+++ b/include/hw/xen/xen-bus.h
@@ -24,6 +24,9 @@ typedef struct XenDevice {
     XenWatch *frontend_state_watch;
     xengnttab_handle *xgth;
     bool feature_grant_copy;
+    xenevtchn_handle *xeh;
+    xenevtchn_port_or_error_t local_port;
+    NotifierList event_notifiers;
 } XenDevice;
 
 typedef char *(*XenDeviceGetName)(XenDevice *xendev, Error **errp);
@@ -102,4 +105,17 @@ void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain,
                                 XenDeviceGrantCopySegment segs[],
                                 unsigned int nr_segs, Error **errp);
 
+typedef struct XenEventChannel XenEventChannel;
+
+typedef void (*XenEventHandler)(void *opaque);
+
+XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev,
+                                               unsigned int port,
+                                               XenEventHandler handler,
+                                               void *opaque, Error **errp);
+void xen_device_notify_event_channel(XenDevice *xendev,
+                                     XenEventChannel *channel);
+void xen_device_unbind_event_channel(XenDevice *xendev,
+                                     XenEventChannel *channel);
+
 #endif /* HW_XEN_BUS_H */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [PATCH 07/18] xen: add event channel interface for XenDevice-s
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
                   ` (9 preceding siblings ...)
  2018-11-21 15:11   ` Paul Durrant
@ 2018-11-21 15:12 ` Paul Durrant
  2018-11-21 15:12 ` [Qemu-devel] " Paul Durrant
                   ` (14 subsequent siblings)
  25 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Anthony Perard, Paul Durrant, Stefano Stabellini

The legacy PV backend infrastructure provides functions to bind, unbind
and send notifications to event channnels. Similar functionality will be
required by XenDevice implementations so this patch adds the necessary
support.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
---
 hw/xen/xen-bus.c         | 84 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/xen/xen-bus.h | 16 +++++++++
 2 files changed, 100 insertions(+)

diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index 7a152d2a2f..64c8af54b0 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -579,6 +579,65 @@ done:
     g_free(xengnttab_segs);
 }
 
+struct XenEventChannel {
+    unsigned int local_port;
+    XenEventHandler handler;
+    void *opaque;
+    Notifier notifier;
+};
+
+static void event_notify(Notifier *n, void *data)
+{
+    XenEventChannel *channel = container_of(n, XenEventChannel, notifier);
+    unsigned long port = (unsigned long)data;
+
+    if (port == channel->local_port) {
+        channel->handler(channel->opaque);
+    }
+}
+
+XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev,
+                                               unsigned int port,
+                                               XenEventHandler handler,
+                                               void *opaque, Error **errp)
+{
+    XenEventChannel *channel = g_new0(XenEventChannel, 1);
+
+    channel->local_port = xenevtchn_bind_interdomain(xendev->xeh,
+                                                     xendev->frontend_id,
+                                                     port);
+    if (xendev->local_port < 0) {
+        error_setg_errno(errp, errno, "xenevtchn_bind_interdomain failed");
+
+        g_free(channel);
+        return NULL;
+    }
+
+    channel->handler = handler;
+    channel->opaque = opaque;
+    channel->notifier.notify = event_notify;
+
+    notifier_list_add(&xendev->event_notifiers, &channel->notifier);
+
+    return channel;
+}
+
+void xen_device_notify_event_channel(XenDevice *xendev,
+                                     XenEventChannel *channel)
+{
+    xenevtchn_notify(xendev->xeh, channel->local_port);
+}
+
+void xen_device_unbind_event_channel(XenDevice *xendev,
+                                     XenEventChannel *channel)
+{
+    notifier_remove(&channel->notifier);
+
+    xenevtchn_unbind(xendev->xeh, channel->local_port);
+
+    g_free(channel);
+}
+
 static void xen_device_unrealize(DeviceState *dev, Error **errp)
 {
     XenDevice *xendev = XEN_DEVICE(dev);
@@ -602,6 +661,11 @@ static void xen_device_unrealize(DeviceState *dev, Error **errp)
     xen_device_frontend_destroy(xendev);
     xen_device_backend_destroy(xendev);
 
+    if (xendev->xeh) {
+        qemu_set_fd_handler(xenevtchn_fd(xendev->xeh), NULL, NULL, NULL);
+        xenevtchn_close(xendev->xeh);
+    }
+
     if (xendev->xgth) {
         xengnttab_close(xendev->xgth);
     }
@@ -616,6 +680,16 @@ static void xen_device_exit(Notifier *n, void *data)
     xen_device_unrealize(DEVICE(xendev), &error_abort);
 }
 
+static void xen_device_event(void *opaque)
+{
+    XenDevice *xendev = opaque;
+    unsigned long port = xenevtchn_pending(xendev->xeh);
+
+    notifier_list_notify(&xendev->event_notifiers, (void *)port);
+
+    xenevtchn_unmask(xendev->xeh, port);
+}
+
 static void xen_device_realize(DeviceState *dev, Error **errp)
 {
     XenDevice *xendev = XEN_DEVICE(dev);
@@ -656,6 +730,16 @@ static void xen_device_realize(DeviceState *dev, Error **errp)
     xendev->feature_grant_copy =
         (xengnttab_grant_copy(xendev->xgth, 0, NULL) == 0);
 
+    xendev->xeh = xenevtchn_open(NULL, 0);
+    if (!xendev->xeh) {
+        error_setg_errno(errp, errno, "failed xenevtchn_open");
+        goto unrealize;
+    }
+
+    notifier_list_init(&xendev->event_notifiers);
+    qemu_set_fd_handler(xenevtchn_fd(xendev->xeh), xen_device_event, NULL,
+                        xendev);
+
     xen_device_backend_create(xendev, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h
index db14d49027..386f6bfc93 100644
--- a/include/hw/xen/xen-bus.h
+++ b/include/hw/xen/xen-bus.h
@@ -24,6 +24,9 @@ typedef struct XenDevice {
     XenWatch *frontend_state_watch;
     xengnttab_handle *xgth;
     bool feature_grant_copy;
+    xenevtchn_handle *xeh;
+    xenevtchn_port_or_error_t local_port;
+    NotifierList event_notifiers;
 } XenDevice;
 
 typedef char *(*XenDeviceGetName)(XenDevice *xendev, Error **errp);
@@ -102,4 +105,17 @@ void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain,
                                 XenDeviceGrantCopySegment segs[],
                                 unsigned int nr_segs, Error **errp);
 
+typedef struct XenEventChannel XenEventChannel;
+
+typedef void (*XenEventHandler)(void *opaque);
+
+XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev,
+                                               unsigned int port,
+                                               XenEventHandler handler,
+                                               void *opaque, Error **errp);
+void xen_device_notify_event_channel(XenDevice *xendev,
+                                     XenEventChannel *channel);
+void xen_device_unbind_event_channel(XenDevice *xendev,
+                                     XenEventChannel *channel);
+
 #endif /* HW_XEN_BUS_H */
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [Qemu-devel] [PATCH 08/18] xen: duplicate xen_disk.c as basis of dataplane/xen-qdisk.c
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
@ 2018-11-21 15:12   ` Paul Durrant
  2018-11-21 15:11 ` [Qemu-devel] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy Paul Durrant
                     ` (24 subsequent siblings)
  25 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Paul Durrant, Stefano Stabellini, Anthony Perard,
	Stefan Hajnoczi, Kevin Wolf, Max Reitz

The new xen-qdisk XenDevice implementation requires the same core dataplane
as the legacy xen_disk implementation it will eventually replace. This
patch therefore copies the legacy xen_disk.c source module into a new
dataplane/xen-qdisk.c source module as the basis for the new dataplane and
adjusts the MAINTAINERS file accordingly.

NOTE: The duplicated code is not yet built. It is simply put into place by
      this patch (just fixing style violations) such that the
      modifications that will need to be made to the code are not
      conflated with code movement, thus making review harder.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
---
 MAINTAINERS                    |    1 +
 hw/block/dataplane/xen-qdisk.c | 1019 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1020 insertions(+)
 create mode 100644 hw/block/dataplane/xen-qdisk.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 10f048a503..4bfbfc9985 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -390,6 +390,7 @@ F: hw/char/xen_console.c
 F: hw/display/xenfb.c
 F: hw/net/xen_nic.c
 F: hw/block/xen*
+F: hw/block/dataplane/xen*
 F: hw/xen/
 F: hw/xenpv/
 F: hw/i386/xen/
diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-qdisk.c
new file mode 100644
index 0000000000..9fae50534e
--- /dev/null
+++ b/hw/block/dataplane/xen-qdisk.c
@@ -0,0 +1,1019 @@
+/*
+ *  xen paravirt block device backend
+ *
+ *  (c) Gerd Hoffmann <kraxel@redhat.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; under version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ *  Contributions after 2012-01-13 are licensed under the terms of the
+ *  GNU GPL, version 2 or (at your option) any later version.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include <sys/ioctl.h>
+#include <sys/uio.h>
+
+#include "hw/hw.h"
+#include "hw/xen/xen_backend.h"
+#include "xen_blkif.h"
+#include "sysemu/blockdev.h"
+#include "sysemu/iothread.h"
+#include "sysemu/block-backend.h"
+#include "qapi/error.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qstring.h"
+#include "trace.h"
+
+/* ------------------------------------------------------------- */
+
+#define BLOCK_SIZE  512
+#define IOCB_COUNT  (BLKIF_MAX_SEGMENTS_PER_REQUEST + 2)
+
+struct ioreq {
+    blkif_request_t     req;
+    int16_t             status;
+
+    /* parsed request */
+    off_t               start;
+    QEMUIOVector        v;
+    void                *buf;
+    size_t              size;
+    int                 presync;
+
+    /* aio status */
+    int                 aio_inflight;
+    int                 aio_errors;
+
+    struct XenBlkDev    *blkdev;
+    QLIST_ENTRY(ioreq)   list;
+    BlockAcctCookie     acct;
+};
+
+#define MAX_RING_PAGE_ORDER 4
+
+struct XenBlkDev {
+    struct XenLegacyDevice    xendev;  /* must be first */
+    char                *params;
+    char                *mode;
+    char                *type;
+    char                *dev;
+    char                *devtype;
+    bool                directiosafe;
+    const char          *fileproto;
+    const char          *filename;
+    unsigned int        ring_ref[1 << MAX_RING_PAGE_ORDER];
+    unsigned int        nr_ring_ref;
+    void                *sring;
+    int64_t             file_blk;
+    int64_t             file_size;
+    int                 protocol;
+    blkif_back_rings_t  rings;
+    int                 more_work;
+
+    /* request lists */
+    QLIST_HEAD(inflight_head, ioreq) inflight;
+    QLIST_HEAD(finished_head, ioreq) finished;
+    QLIST_HEAD(freelist_head, ioreq) freelist;
+    int                 requests_total;
+    int                 requests_inflight;
+    int                 requests_finished;
+    unsigned int        max_requests;
+
+    gboolean            feature_discard;
+
+    /* qemu block driver */
+    DriveInfo           *dinfo;
+    BlockBackend        *blk;
+    QEMUBH              *bh;
+
+    IOThread            *iothread;
+    AioContext          *ctx;
+};
+
+/* ------------------------------------------------------------- */
+
+static void ioreq_reset(struct ioreq *ioreq)
+{
+    memset(&ioreq->req, 0, sizeof(ioreq->req));
+    ioreq->status = 0;
+    ioreq->start = 0;
+    ioreq->buf = NULL;
+    ioreq->size = 0;
+    ioreq->presync = 0;
+
+    ioreq->aio_inflight = 0;
+    ioreq->aio_errors = 0;
+
+    ioreq->blkdev = NULL;
+    memset(&ioreq->list, 0, sizeof(ioreq->list));
+    memset(&ioreq->acct, 0, sizeof(ioreq->acct));
+
+    qemu_iovec_reset(&ioreq->v);
+}
+
+static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
+{
+    struct ioreq *ioreq = NULL;
+
+    if (QLIST_EMPTY(&blkdev->freelist)) {
+        if (blkdev->requests_total >= blkdev->max_requests) {
+            goto out;
+        }
+        /* allocate new struct */
+        ioreq = g_malloc0(sizeof(*ioreq));
+        ioreq->blkdev = blkdev;
+        blkdev->requests_total++;
+        qemu_iovec_init(&ioreq->v, 1);
+    } else {
+        /* get one from freelist */
+        ioreq = QLIST_FIRST(&blkdev->freelist);
+        QLIST_REMOVE(ioreq, list);
+    }
+    QLIST_INSERT_HEAD(&blkdev->inflight, ioreq, list);
+    blkdev->requests_inflight++;
+
+out:
+    return ioreq;
+}
+
+static void ioreq_finish(struct ioreq *ioreq)
+{
+    struct XenBlkDev *blkdev = ioreq->blkdev;
+
+    QLIST_REMOVE(ioreq, list);
+    QLIST_INSERT_HEAD(&blkdev->finished, ioreq, list);
+    blkdev->requests_inflight--;
+    blkdev->requests_finished++;
+}
+
+static void ioreq_release(struct ioreq *ioreq, bool finish)
+{
+    struct XenBlkDev *blkdev = ioreq->blkdev;
+
+    QLIST_REMOVE(ioreq, list);
+    ioreq_reset(ioreq);
+    ioreq->blkdev = blkdev;
+    QLIST_INSERT_HEAD(&blkdev->freelist, ioreq, list);
+    if (finish) {
+        blkdev->requests_finished--;
+    } else {
+        blkdev->requests_inflight--;
+    }
+}
+
+/*
+ * translate request into iovec + start offset
+ * do sanity checks along the way
+ */
+static int ioreq_parse(struct ioreq *ioreq)
+{
+    struct XenBlkDev *blkdev = ioreq->blkdev;
+    struct XenLegacyDevice *xendev = &blkdev->xendev;
+    size_t len;
+    int i;
+
+    xen_pv_printf(
+        xendev, 3,
+        "op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 "\n",
+        ioreq->req.operation, ioreq->req.nr_segments,
+        ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number);
+    switch (ioreq->req.operation) {
+    case BLKIF_OP_READ:
+        break;
+    case BLKIF_OP_FLUSH_DISKCACHE:
+        ioreq->presync = 1;
+        if (!ioreq->req.nr_segments) {
+            return 0;
+        }
+        /* fall through */
+    case BLKIF_OP_WRITE:
+        break;
+    case BLKIF_OP_DISCARD:
+        return 0;
+    default:
+        xen_pv_printf(xendev, 0, "error: unknown operation (%d)\n",
+                      ioreq->req.operation);
+        goto err;
+    };
+
+    if (ioreq->req.operation != BLKIF_OP_READ && blkdev->mode[0] != 'w') {
+        xen_pv_printf(xendev, 0, "error: write req for ro device\n");
+        goto err;
+    }
+
+    ioreq->start = ioreq->req.sector_number * blkdev->file_blk;
+    for (i = 0; i < ioreq->req.nr_segments; i++) {
+        if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
+            xen_pv_printf(xendev, 0, "error: nr_segments too big\n");
+            goto err;
+        }
+        if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) {
+            xen_pv_printf(xendev, 0, "error: first > last sector\n");
+            goto err;
+        }
+        if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >= XC_PAGE_SIZE) {
+            xen_pv_printf(xendev, 0, "error: page crossing\n");
+            goto err;
+        }
+
+        len = (ioreq->req.seg[i].last_sect -
+               ioreq->req.seg[i].first_sect + 1) * blkdev->file_blk;
+        ioreq->size += len;
+    }
+    if (ioreq->start + ioreq->size > blkdev->file_size) {
+        xen_pv_printf(xendev, 0, "error: access beyond end of file\n");
+        goto err;
+    }
+    return 0;
+
+err:
+    ioreq->status = BLKIF_RSP_ERROR;
+    return -1;
+}
+
+static int ioreq_grant_copy(struct ioreq *ioreq)
+{
+    struct XenBlkDev *blkdev = ioreq->blkdev;
+    struct XenLegacyDevice *xendev = &blkdev->xendev;
+    XenGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+    int i, count, rc;
+    int64_t file_blk = blkdev->file_blk;
+    bool to_domain = (ioreq->req.operation == BLKIF_OP_READ);
+    void *virt = ioreq->buf;
+
+    if (ioreq->req.nr_segments == 0) {
+        return 0;
+    }
+
+    count = ioreq->req.nr_segments;
+
+    for (i = 0; i < count; i++) {
+        if (to_domain) {
+            segs[i].dest.foreign.ref = ioreq->req.seg[i].gref;
+            segs[i].dest.foreign.offset = ioreq->req.seg[i].first_sect *
+                file_blk;
+            segs[i].source.virt = virt;
+        } else {
+            segs[i].source.foreign.ref = ioreq->req.seg[i].gref;
+            segs[i].source.foreign.offset = ioreq->req.seg[i].first_sect *
+                file_blk;
+            segs[i].dest.virt = virt;
+        }
+        segs[i].len = (ioreq->req.seg[i].last_sect
+                       - ioreq->req.seg[i].first_sect + 1) * file_blk;
+        virt += segs[i].len;
+    }
+
+    rc = xen_be_copy_grant_refs(xendev, to_domain, segs, count);
+
+    if (rc) {
+        xen_pv_printf(xendev, 0,
+                      "failed to copy data %d\n", rc);
+        ioreq->aio_errors++;
+        return -1;
+    }
+
+    return rc;
+}
+
+static int ioreq_runio_qemu_aio(struct ioreq *ioreq);
+
+static void qemu_aio_complete(void *opaque, int ret)
+{
+    struct ioreq *ioreq = opaque;
+    struct XenBlkDev *blkdev = ioreq->blkdev;
+    struct XenLegacyDevice *xendev = &blkdev->xendev;
+
+    aio_context_acquire(blkdev->ctx);
+
+    if (ret != 0) {
+        xen_pv_printf(xendev, 0, "%s I/O error\n",
+                      ioreq->req.operation == BLKIF_OP_READ ? "read" : "write");
+        ioreq->aio_errors++;
+    }
+
+    ioreq->aio_inflight--;
+    if (ioreq->presync) {
+        ioreq->presync = 0;
+        ioreq_runio_qemu_aio(ioreq);
+        goto done;
+    }
+    if (ioreq->aio_inflight > 0) {
+        goto done;
+    }
+
+    switch (ioreq->req.operation) {
+    case BLKIF_OP_READ:
+        /* in case of failure ioreq->aio_errors is increased */
+        if (ret == 0) {
+            ioreq_grant_copy(ioreq);
+        }
+        qemu_vfree(ioreq->buf);
+        break;
+    case BLKIF_OP_WRITE:
+    case BLKIF_OP_FLUSH_DISKCACHE:
+        if (!ioreq->req.nr_segments) {
+            break;
+        }
+        qemu_vfree(ioreq->buf);
+        break;
+    default:
+        break;
+    }
+
+    ioreq->status = ioreq->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY;
+    ioreq_finish(ioreq);
+
+    switch (ioreq->req.operation) {
+    case BLKIF_OP_WRITE:
+    case BLKIF_OP_FLUSH_DISKCACHE:
+        if (!ioreq->req.nr_segments) {
+            break;
+        }
+    case BLKIF_OP_READ:
+        if (ioreq->status == BLKIF_RSP_OKAY) {
+            block_acct_done(blk_get_stats(blkdev->blk), &ioreq->acct);
+        } else {
+            block_acct_failed(blk_get_stats(blkdev->blk), &ioreq->acct);
+        }
+        break;
+    case BLKIF_OP_DISCARD:
+    default:
+        break;
+    }
+    qemu_bh_schedule(blkdev->bh);
+
+done:
+    aio_context_release(blkdev->ctx);
+}
+
+static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_number,
+                              uint64_t nr_sectors)
+{
+    struct XenBlkDev *blkdev = ioreq->blkdev;
+    int64_t byte_offset;
+    int byte_chunk;
+    uint64_t byte_remaining, limit;
+    uint64_t sec_start = sector_number;
+    uint64_t sec_count = nr_sectors;
+
+    /* Wrap around, or overflowing byte limit? */
+    if (sec_start + sec_count < sec_count ||
+        sec_start + sec_count > INT64_MAX >> BDRV_SECTOR_BITS) {
+        return false;
+    }
+
+    limit = BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS;
+    byte_offset = sec_start << BDRV_SECTOR_BITS;
+    byte_remaining = sec_count << BDRV_SECTOR_BITS;
+
+    do {
+        byte_chunk = byte_remaining > limit ? limit : byte_remaining;
+        ioreq->aio_inflight++;
+        blk_aio_pdiscard(blkdev->blk, byte_offset, byte_chunk,
+                         qemu_aio_complete, ioreq);
+        byte_remaining -= byte_chunk;
+        byte_offset += byte_chunk;
+    } while (byte_remaining > 0);
+
+    return true;
+}
+
+static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
+{
+    struct XenBlkDev *blkdev = ioreq->blkdev;
+
+    ioreq->buf = qemu_memalign(XC_PAGE_SIZE, ioreq->size);
+    if (ioreq->req.nr_segments &&
+        (ioreq->req.operation == BLKIF_OP_WRITE ||
+         ioreq->req.operation == BLKIF_OP_FLUSH_DISKCACHE) &&
+        ioreq_grant_copy(ioreq)) {
+        qemu_vfree(ioreq->buf);
+        goto err;
+    }
+
+    ioreq->aio_inflight++;
+    if (ioreq->presync) {
+        blk_aio_flush(ioreq->blkdev->blk, qemu_aio_complete, ioreq);
+        return 0;
+    }
+
+    switch (ioreq->req.operation) {
+    case BLKIF_OP_READ:
+        qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size);
+        block_acct_start(blk_get_stats(blkdev->blk), &ioreq->acct,
+                         ioreq->v.size, BLOCK_ACCT_READ);
+        ioreq->aio_inflight++;
+        blk_aio_preadv(blkdev->blk, ioreq->start, &ioreq->v, 0,
+                       qemu_aio_complete, ioreq);
+        break;
+    case BLKIF_OP_WRITE:
+    case BLKIF_OP_FLUSH_DISKCACHE:
+        if (!ioreq->req.nr_segments) {
+            break;
+        }
+
+        qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size);
+        block_acct_start(blk_get_stats(blkdev->blk), &ioreq->acct,
+                         ioreq->v.size,
+                         ioreq->req.operation == BLKIF_OP_WRITE ?
+                         BLOCK_ACCT_WRITE : BLOCK_ACCT_FLUSH);
+        ioreq->aio_inflight++;
+        blk_aio_pwritev(blkdev->blk, ioreq->start, &ioreq->v, 0,
+                        qemu_aio_complete, ioreq);
+        break;
+    case BLKIF_OP_DISCARD:
+    {
+        struct blkif_request_discard *req = (void *)&ioreq->req;
+        if (!blk_split_discard(ioreq, req->sector_number, req->nr_sectors)) {
+            goto err;
+        }
+        break;
+    }
+    default:
+        /* unknown operation (shouldn't happen -- parse catches this) */
+        goto err;
+    }
+
+    qemu_aio_complete(ioreq, 0);
+
+    return 0;
+
+err:
+    ioreq_finish(ioreq);
+    ioreq->status = BLKIF_RSP_ERROR;
+    return -1;
+}
+
+static int blk_send_response_one(struct ioreq *ioreq)
+{
+    struct XenBlkDev  *blkdev = ioreq->blkdev;
+    int               send_notify   = 0;
+    int               have_requests = 0;
+    blkif_response_t  *resp;
+
+    /* Place on the response ring for the relevant domain. */
+    switch (blkdev->protocol) {
+    case BLKIF_PROTOCOL_NATIVE:
+        resp = (blkif_response_t *)RING_GET_RESPONSE(
+            &blkdev->rings.native,
+            blkdev->rings.native.rsp_prod_pvt);
+        break;
+    case BLKIF_PROTOCOL_X86_32:
+        resp = (blkif_response_t *)RING_GET_RESPONSE(
+            &blkdev->rings.x86_32_part,
+            blkdev->rings.x86_32_part.rsp_prod_pvt);
+        break;
+    case BLKIF_PROTOCOL_X86_64:
+        resp = (blkif_response_t *)RING_GET_RESPONSE(
+            &blkdev->rings.x86_64_part,
+            blkdev->rings.x86_64_part.rsp_prod_pvt);
+        break;
+    default:
+        return 0;
+    }
+
+    resp->id        = ioreq->req.id;
+    resp->operation = ioreq->req.operation;
+    resp->status    = ioreq->status;
+
+    blkdev->rings.common.rsp_prod_pvt++;
+
+    RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blkdev->rings.common, send_notify);
+    if (blkdev->rings.common.rsp_prod_pvt == blkdev->rings.common.req_cons) {
+        /*
+         * Tail check for pending requests. Allows frontend to avoid
+         * notifications if requests are already in flight (lower
+         * overheads and promotes batching).
+         */
+        RING_FINAL_CHECK_FOR_REQUESTS(&blkdev->rings.common, have_requests);
+    } else if (RING_HAS_UNCONSUMED_REQUESTS(&blkdev->rings.common)) {
+        have_requests = 1;
+    }
+
+    if (have_requests) {
+        blkdev->more_work++;
+    }
+    return send_notify;
+}
+
+/* walk finished list, send outstanding responses, free requests */
+static void blk_send_response_all(struct XenBlkDev *blkdev)
+{
+    struct ioreq *ioreq;
+    int send_notify = 0;
+
+    while (!QLIST_EMPTY(&blkdev->finished)) {
+        ioreq = QLIST_FIRST(&blkdev->finished);
+        send_notify += blk_send_response_one(ioreq);
+        ioreq_release(ioreq, true);
+    }
+    if (send_notify) {
+        xen_pv_send_notify(&blkdev->xendev);
+    }
+}
+
+static int blk_get_request(struct XenBlkDev *blkdev, struct ioreq *ioreq,
+                           RING_IDX rc)
+{
+    switch (blkdev->protocol) {
+    case BLKIF_PROTOCOL_NATIVE:
+        memcpy(&ioreq->req, RING_GET_REQUEST(&blkdev->rings.native, rc),
+               sizeof(ioreq->req));
+        break;
+    case BLKIF_PROTOCOL_X86_32:
+        blkif_get_x86_32_req(&ioreq->req,
+                             RING_GET_REQUEST(&blkdev->rings.x86_32_part, rc));
+        break;
+    case BLKIF_PROTOCOL_X86_64:
+        blkif_get_x86_64_req(&ioreq->req,
+                             RING_GET_REQUEST(&blkdev->rings.x86_64_part, rc));
+        break;
+    }
+    /* Prevent the compiler from accessing the on-ring fields instead. */
+    barrier();
+    return 0;
+}
+
+static void blk_handle_requests(struct XenBlkDev *blkdev)
+{
+    RING_IDX rc, rp;
+    struct ioreq *ioreq;
+
+    blkdev->more_work = 0;
+
+    rc = blkdev->rings.common.req_cons;
+    rp = blkdev->rings.common.sring->req_prod;
+    xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
+
+    blk_send_response_all(blkdev);
+    while (rc != rp) {
+        /* pull request from ring */
+        if (RING_REQUEST_CONS_OVERFLOW(&blkdev->rings.common, rc)) {
+            break;
+        }
+        ioreq = ioreq_start(blkdev);
+        if (ioreq == NULL) {
+            blkdev->more_work++;
+            break;
+        }
+        blk_get_request(blkdev, ioreq, rc);
+        blkdev->rings.common.req_cons = ++rc;
+
+        /* parse them */
+        if (ioreq_parse(ioreq) != 0) {
+
+            switch (ioreq->req.operation) {
+            case BLKIF_OP_READ:
+                block_acct_invalid(blk_get_stats(blkdev->blk),
+                                   BLOCK_ACCT_READ);
+                break;
+            case BLKIF_OP_WRITE:
+                block_acct_invalid(blk_get_stats(blkdev->blk),
+                                   BLOCK_ACCT_WRITE);
+                break;
+            case BLKIF_OP_FLUSH_DISKCACHE:
+                block_acct_invalid(blk_get_stats(blkdev->blk),
+                                   BLOCK_ACCT_FLUSH);
+            default:
+                break;
+            };
+
+            if (blk_send_response_one(ioreq)) {
+                xen_pv_send_notify(&blkdev->xendev);
+            }
+            ioreq_release(ioreq, false);
+            continue;
+        }
+
+        ioreq_runio_qemu_aio(ioreq);
+    }
+
+    if (blkdev->more_work && blkdev->requests_inflight < blkdev->max_requests) {
+        qemu_bh_schedule(blkdev->bh);
+    }
+}
+
+/* ------------------------------------------------------------- */
+
+static void blk_bh(void *opaque)
+{
+    struct XenBlkDev *blkdev = opaque;
+
+    aio_context_acquire(blkdev->ctx);
+    blk_handle_requests(blkdev);
+    aio_context_release(blkdev->ctx);
+}
+
+static void blk_alloc(struct XenLegacyDevice *xendev)
+{
+    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
+    Error *err = NULL;
+
+    trace_xen_disk_alloc(xendev->name);
+
+    QLIST_INIT(&blkdev->inflight);
+    QLIST_INIT(&blkdev->finished);
+    QLIST_INIT(&blkdev->freelist);
+
+    blkdev->iothread = iothread_create(xendev->name, &err);
+    assert(!err);
+
+    blkdev->ctx = iothread_get_aio_context(blkdev->iothread);
+    blkdev->bh = aio_bh_new(blkdev->ctx, blk_bh, blkdev);
+}
+
+static void blk_parse_discard(struct XenBlkDev *blkdev)
+{
+    struct XenLegacyDevice *xendev = &blkdev->xendev;
+    int enable;
+
+    blkdev->feature_discard = true;
+
+    if (xenstore_read_be_int(xendev, "discard-enable", &enable) == 0) {
+        blkdev->feature_discard = !!enable;
+    }
+
+    if (blkdev->feature_discard) {
+        xenstore_write_be_int(xendev, "feature-discard", 1);
+    }
+}
+
+static int blk_init(struct XenLegacyDevice *xendev)
+{
+    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
+    int info = 0;
+    char *directiosafe = NULL;
+
+    trace_xen_disk_init(xendev->name);
+
+    /* read xenstore entries */
+    if (blkdev->params == NULL) {
+        char *h = NULL;
+        blkdev->params = xenstore_read_be_str(xendev, "params");
+        if (blkdev->params != NULL) {
+            h = strchr(blkdev->params, ':');
+        }
+        if (h != NULL) {
+            blkdev->fileproto = blkdev->params;
+            blkdev->filename  = h + 1;
+            *h = 0;
+        } else {
+            blkdev->fileproto = "<unset>";
+            blkdev->filename  = blkdev->params;
+        }
+    }
+    if (!strcmp("aio", blkdev->fileproto)) {
+        blkdev->fileproto = "raw";
+    }
+    if (!strcmp("vhd", blkdev->fileproto)) {
+        blkdev->fileproto = "vpc";
+    }
+    if (blkdev->mode == NULL) {
+        blkdev->mode = xenstore_read_be_str(xendev, "mode");
+    }
+    if (blkdev->type == NULL) {
+        blkdev->type = xenstore_read_be_str(xendev, "type");
+    }
+    if (blkdev->dev == NULL) {
+        blkdev->dev = xenstore_read_be_str(xendev, "dev");
+    }
+    if (blkdev->devtype == NULL) {
+        blkdev->devtype = xenstore_read_be_str(xendev, "device-type");
+    }
+    directiosafe = xenstore_read_be_str(xendev, "direct-io-safe");
+    blkdev->directiosafe = (directiosafe && atoi(directiosafe));
+
+    /* do we have all we need? */
+    if (blkdev->params == NULL ||
+        blkdev->mode == NULL   ||
+        blkdev->type == NULL   ||
+        blkdev->dev == NULL) {
+        goto out_error;
+    }
+
+    /* read-only ? */
+    if (strcmp(blkdev->mode, "w")) {
+        info  |= VDISK_READONLY;
+    }
+
+    /* cdrom ? */
+    if (blkdev->devtype && !strcmp(blkdev->devtype, "cdrom")) {
+        info  |= VDISK_CDROM;
+    }
+
+    blkdev->file_blk  = BLOCK_SIZE;
+
+    /* fill info
+     * blk_connect supplies sector-size and sectors
+     */
+    xenstore_write_be_int(xendev, "feature-flush-cache", 1);
+    xenstore_write_be_int(xendev, "info", info);
+
+    xenstore_write_be_int(xendev, "max-ring-page-order",
+                          MAX_RING_PAGE_ORDER);
+
+    blk_parse_discard(blkdev);
+
+    g_free(directiosafe);
+    return 0;
+
+out_error:
+    g_free(blkdev->params);
+    blkdev->params = NULL;
+    g_free(blkdev->mode);
+    blkdev->mode = NULL;
+    g_free(blkdev->type);
+    blkdev->type = NULL;
+    g_free(blkdev->dev);
+    blkdev->dev = NULL;
+    g_free(blkdev->devtype);
+    blkdev->devtype = NULL;
+    g_free(directiosafe);
+    blkdev->directiosafe = false;
+    return -1;
+}
+
+static int blk_connect(struct XenLegacyDevice *xendev)
+{
+    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
+    int index, qflags;
+    bool readonly = true;
+    bool writethrough = true;
+    int order, ring_ref;
+    unsigned int ring_size, max_grants;
+    unsigned int i;
+
+    trace_xen_disk_connect(xendev->name);
+
+    /* read-only ? */
+    if (blkdev->directiosafe) {
+        qflags = BDRV_O_NOCACHE | BDRV_O_NATIVE_AIO;
+    } else {
+        qflags = 0;
+        writethrough = false;
+    }
+    if (strcmp(blkdev->mode, "w") == 0) {
+        qflags |= BDRV_O_RDWR;
+        readonly = false;
+    }
+    if (blkdev->feature_discard) {
+        qflags |= BDRV_O_UNMAP;
+    }
+
+    /* init qemu block driver */
+    index = (xendev->dev - 202 * 256) / 16;
+    blkdev->dinfo = drive_get(IF_XEN, 0, index);
+    if (!blkdev->dinfo) {
+        Error *local_err = NULL;
+        QDict *options = NULL;
+
+        if (strcmp(blkdev->fileproto, "<unset>")) {
+            options = qdict_new();
+            qdict_put_str(options, "driver", blkdev->fileproto);
+        }
+
+        /* setup via xenbus -> create new block driver instance */
+        xen_pv_printf(xendev, 2, "create new bdrv (xenbus setup)\n");
+        blkdev->blk = blk_new_open(blkdev->filename, NULL, options,
+                                   qflags, &local_err);
+        if (!blkdev->blk) {
+            xen_pv_printf(xendev, 0, "error: %s\n",
+                          error_get_pretty(local_err));
+            error_free(local_err);
+            return -1;
+        }
+        blk_set_enable_write_cache(blkdev->blk, !writethrough);
+    } else {
+        /* setup via qemu cmdline -> already setup for us */
+        xen_pv_printf(xendev, 2,
+                      "get configured bdrv (cmdline setup)\n");
+        blkdev->blk = blk_by_legacy_dinfo(blkdev->dinfo);
+        if (blk_is_read_only(blkdev->blk) && !readonly) {
+            xen_pv_printf(xendev, 0, "Unexpected read-only drive");
+            blkdev->blk = NULL;
+            return -1;
+        }
+        /* blkdev->blk is not create by us, we get a reference
+         * so we can blk_unref() unconditionally */
+        blk_ref(blkdev->blk);
+    }
+    blk_attach_dev_legacy(blkdev->blk, blkdev);
+    blkdev->file_size = blk_getlength(blkdev->blk);
+    if (blkdev->file_size < 0) {
+        BlockDriverState *bs = blk_bs(blkdev->blk);
+        const char *drv_name = bs ? bdrv_get_format_name(bs) : NULL;
+        xen_pv_printf(xendev, 1, "blk_getlength: %d (%s) | drv %s\n",
+                      (int)blkdev->file_size, strerror(-blkdev->file_size),
+                      drv_name ?: "-");
+        blkdev->file_size = 0;
+    }
+
+    xen_pv_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\","
+                  " size %" PRId64 " (%" PRId64 " MB)\n",
+                  blkdev->type, blkdev->fileproto, blkdev->filename,
+                  blkdev->file_size, blkdev->file_size / MiB);
+
+    /* Fill in number of sector size and number of sectors */
+    xenstore_write_be_int(xendev, "sector-size", blkdev->file_blk);
+    xenstore_write_be_int64(xendev, "sectors",
+                            blkdev->file_size / blkdev->file_blk);
+
+    if (xenstore_read_fe_int(xendev, "ring-page-order",
+                             &order) == -1) {
+        blkdev->nr_ring_ref = 1;
+
+        if (xenstore_read_fe_int(xendev, "ring-ref",
+                                 &ring_ref) == -1) {
+            return -1;
+        }
+        blkdev->ring_ref[0] = ring_ref;
+
+    } else if (order >= 0 && order <= MAX_RING_PAGE_ORDER) {
+        blkdev->nr_ring_ref = 1 << order;
+
+        for (i = 0; i < blkdev->nr_ring_ref; i++) {
+            char *key;
+
+            key = g_strdup_printf("ring-ref%u", i);
+            if (!key) {
+                return -1;
+            }
+
+            if (xenstore_read_fe_int(xendev, key,
+                                     &ring_ref) == -1) {
+                g_free(key);
+                return -1;
+            }
+            blkdev->ring_ref[i] = ring_ref;
+
+            g_free(key);
+        }
+    } else {
+        xen_pv_printf(xendev, 0, "invalid ring-page-order: %d\n",
+                      order);
+        return -1;
+    }
+
+    if (xenstore_read_fe_int(xendev, "event-channel",
+                             &xendev->remote_port) == -1) {
+        return -1;
+    }
+
+    if (!xendev->protocol) {
+        blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
+    } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_NATIVE) == 0) {
+        blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
+    } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_X86_32) == 0) {
+        blkdev->protocol = BLKIF_PROTOCOL_X86_32;
+    } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_X86_64) == 0) {
+        blkdev->protocol = BLKIF_PROTOCOL_X86_64;
+    } else {
+        blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
+    }
+
+    ring_size = XC_PAGE_SIZE * blkdev->nr_ring_ref;
+    switch (blkdev->protocol) {
+    case BLKIF_PROTOCOL_NATIVE:
+    {
+        blkdev->max_requests = __CONST_RING_SIZE(blkif, ring_size);
+        break;
+    }
+    case BLKIF_PROTOCOL_X86_32:
+    {
+        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_32, ring_size);
+        break;
+    }
+    case BLKIF_PROTOCOL_X86_64:
+    {
+        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_64, ring_size);
+        break;
+    }
+    default:
+        return -1;
+    }
+
+    /* Add on the number needed for the ring pages */
+    max_grants = blkdev->nr_ring_ref;
+
+    xen_be_set_max_grant_refs(xendev, max_grants);
+    blkdev->sring = xen_be_map_grant_refs(xendev, blkdev->ring_ref,
+                                          blkdev->nr_ring_ref,
+                                          PROT_READ | PROT_WRITE);
+    if (!blkdev->sring) {
+        return -1;
+    }
+
+    switch (blkdev->protocol) {
+    case BLKIF_PROTOCOL_NATIVE:
+    {
+        blkif_sring_t *sring_native = blkdev->sring;
+        BACK_RING_INIT(&blkdev->rings.native, sring_native, ring_size);
+        break;
+    }
+    case BLKIF_PROTOCOL_X86_32:
+    {
+        blkif_x86_32_sring_t *sring_x86_32 = blkdev->sring;
+
+        BACK_RING_INIT(&blkdev->rings.x86_32_part, sring_x86_32, ring_size);
+        break;
+    }
+    case BLKIF_PROTOCOL_X86_64:
+    {
+        blkif_x86_64_sring_t *sring_x86_64 = blkdev->sring;
+
+        BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64, ring_size);
+        break;
+    }
+    }
+
+    blk_set_aio_context(blkdev->blk, blkdev->ctx);
+
+    xen_be_bind_evtchn(xendev);
+
+    xen_pv_printf(xendev, 1, "ok: proto %s, nr-ring-ref %u, "
+                  "remote port %d, local port %d\n",
+                  xendev->protocol, blkdev->nr_ring_ref,
+                  xendev->remote_port, xendev->local_port);
+    return 0;
+}
+
+static void blk_disconnect(struct XenLegacyDevice *xendev)
+{
+    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
+
+    trace_xen_disk_disconnect(xendev->name);
+
+    aio_context_acquire(blkdev->ctx);
+
+    if (blkdev->blk) {
+        blk_set_aio_context(blkdev->blk, qemu_get_aio_context());
+        blk_detach_dev(blkdev->blk, blkdev);
+        blk_unref(blkdev->blk);
+        blkdev->blk = NULL;
+    }
+    xen_pv_unbind_evtchn(xendev);
+
+    aio_context_release(blkdev->ctx);
+
+    if (blkdev->sring) {
+        xen_be_unmap_grant_refs(xendev, blkdev->sring,
+                                blkdev->nr_ring_ref);
+        blkdev->sring = NULL;
+    }
+}
+
+static int blk_free(struct XenLegacyDevice *xendev)
+{
+    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
+    struct ioreq *ioreq;
+
+    trace_xen_disk_free(xendev->name);
+
+    blk_disconnect(xendev);
+
+    while (!QLIST_EMPTY(&blkdev->freelist)) {
+        ioreq = QLIST_FIRST(&blkdev->freelist);
+        QLIST_REMOVE(ioreq, list);
+        qemu_iovec_destroy(&ioreq->v);
+        g_free(ioreq);
+    }
+
+    g_free(blkdev->params);
+    g_free(blkdev->mode);
+    g_free(blkdev->type);
+    g_free(blkdev->dev);
+    g_free(blkdev->devtype);
+    qemu_bh_delete(blkdev->bh);
+    iothread_destroy(blkdev->iothread);
+    return 0;
+}
+
+static void blk_event(struct XenLegacyDevice *xendev)
+{
+    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
+
+    qemu_bh_schedule(blkdev->bh);
+}
+
+struct XenDevOps xen_blkdev_ops = {
+    .flags      = DEVOPS_FLAG_NEED_GNTDEV,
+    .size       = sizeof(struct XenBlkDev),
+    .alloc      = blk_alloc,
+    .init       = blk_init,
+    .initialise = blk_connect,
+    .disconnect = blk_disconnect,
+    .event      = blk_event,
+    .free       = blk_free,
+};
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [PATCH 08/18] xen: duplicate xen_disk.c as basis of dataplane/xen-qdisk.c
@ 2018-11-21 15:12   ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Kevin Wolf, Stefano Stabellini, Max Reitz, Paul Durrant,
	Stefan Hajnoczi, Anthony Perard

The new xen-qdisk XenDevice implementation requires the same core dataplane
as the legacy xen_disk implementation it will eventually replace. This
patch therefore copies the legacy xen_disk.c source module into a new
dataplane/xen-qdisk.c source module as the basis for the new dataplane and
adjusts the MAINTAINERS file accordingly.

NOTE: The duplicated code is not yet built. It is simply put into place by
      this patch (just fixing style violations) such that the
      modifications that will need to be made to the code are not
      conflated with code movement, thus making review harder.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
---
 MAINTAINERS                    |    1 +
 hw/block/dataplane/xen-qdisk.c | 1019 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1020 insertions(+)
 create mode 100644 hw/block/dataplane/xen-qdisk.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 10f048a503..4bfbfc9985 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -390,6 +390,7 @@ F: hw/char/xen_console.c
 F: hw/display/xenfb.c
 F: hw/net/xen_nic.c
 F: hw/block/xen*
+F: hw/block/dataplane/xen*
 F: hw/xen/
 F: hw/xenpv/
 F: hw/i386/xen/
diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-qdisk.c
new file mode 100644
index 0000000000..9fae50534e
--- /dev/null
+++ b/hw/block/dataplane/xen-qdisk.c
@@ -0,0 +1,1019 @@
+/*
+ *  xen paravirt block device backend
+ *
+ *  (c) Gerd Hoffmann <kraxel@redhat.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; under version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ *  Contributions after 2012-01-13 are licensed under the terms of the
+ *  GNU GPL, version 2 or (at your option) any later version.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include <sys/ioctl.h>
+#include <sys/uio.h>
+
+#include "hw/hw.h"
+#include "hw/xen/xen_backend.h"
+#include "xen_blkif.h"
+#include "sysemu/blockdev.h"
+#include "sysemu/iothread.h"
+#include "sysemu/block-backend.h"
+#include "qapi/error.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qstring.h"
+#include "trace.h"
+
+/* ------------------------------------------------------------- */
+
+#define BLOCK_SIZE  512
+#define IOCB_COUNT  (BLKIF_MAX_SEGMENTS_PER_REQUEST + 2)
+
+struct ioreq {
+    blkif_request_t     req;
+    int16_t             status;
+
+    /* parsed request */
+    off_t               start;
+    QEMUIOVector        v;
+    void                *buf;
+    size_t              size;
+    int                 presync;
+
+    /* aio status */
+    int                 aio_inflight;
+    int                 aio_errors;
+
+    struct XenBlkDev    *blkdev;
+    QLIST_ENTRY(ioreq)   list;
+    BlockAcctCookie     acct;
+};
+
+#define MAX_RING_PAGE_ORDER 4
+
+struct XenBlkDev {
+    struct XenLegacyDevice    xendev;  /* must be first */
+    char                *params;
+    char                *mode;
+    char                *type;
+    char                *dev;
+    char                *devtype;
+    bool                directiosafe;
+    const char          *fileproto;
+    const char          *filename;
+    unsigned int        ring_ref[1 << MAX_RING_PAGE_ORDER];
+    unsigned int        nr_ring_ref;
+    void                *sring;
+    int64_t             file_blk;
+    int64_t             file_size;
+    int                 protocol;
+    blkif_back_rings_t  rings;
+    int                 more_work;
+
+    /* request lists */
+    QLIST_HEAD(inflight_head, ioreq) inflight;
+    QLIST_HEAD(finished_head, ioreq) finished;
+    QLIST_HEAD(freelist_head, ioreq) freelist;
+    int                 requests_total;
+    int                 requests_inflight;
+    int                 requests_finished;
+    unsigned int        max_requests;
+
+    gboolean            feature_discard;
+
+    /* qemu block driver */
+    DriveInfo           *dinfo;
+    BlockBackend        *blk;
+    QEMUBH              *bh;
+
+    IOThread            *iothread;
+    AioContext          *ctx;
+};
+
+/* ------------------------------------------------------------- */
+
+static void ioreq_reset(struct ioreq *ioreq)
+{
+    memset(&ioreq->req, 0, sizeof(ioreq->req));
+    ioreq->status = 0;
+    ioreq->start = 0;
+    ioreq->buf = NULL;
+    ioreq->size = 0;
+    ioreq->presync = 0;
+
+    ioreq->aio_inflight = 0;
+    ioreq->aio_errors = 0;
+
+    ioreq->blkdev = NULL;
+    memset(&ioreq->list, 0, sizeof(ioreq->list));
+    memset(&ioreq->acct, 0, sizeof(ioreq->acct));
+
+    qemu_iovec_reset(&ioreq->v);
+}
+
+static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
+{
+    struct ioreq *ioreq = NULL;
+
+    if (QLIST_EMPTY(&blkdev->freelist)) {
+        if (blkdev->requests_total >= blkdev->max_requests) {
+            goto out;
+        }
+        /* allocate new struct */
+        ioreq = g_malloc0(sizeof(*ioreq));
+        ioreq->blkdev = blkdev;
+        blkdev->requests_total++;
+        qemu_iovec_init(&ioreq->v, 1);
+    } else {
+        /* get one from freelist */
+        ioreq = QLIST_FIRST(&blkdev->freelist);
+        QLIST_REMOVE(ioreq, list);
+    }
+    QLIST_INSERT_HEAD(&blkdev->inflight, ioreq, list);
+    blkdev->requests_inflight++;
+
+out:
+    return ioreq;
+}
+
+static void ioreq_finish(struct ioreq *ioreq)
+{
+    struct XenBlkDev *blkdev = ioreq->blkdev;
+
+    QLIST_REMOVE(ioreq, list);
+    QLIST_INSERT_HEAD(&blkdev->finished, ioreq, list);
+    blkdev->requests_inflight--;
+    blkdev->requests_finished++;
+}
+
+static void ioreq_release(struct ioreq *ioreq, bool finish)
+{
+    struct XenBlkDev *blkdev = ioreq->blkdev;
+
+    QLIST_REMOVE(ioreq, list);
+    ioreq_reset(ioreq);
+    ioreq->blkdev = blkdev;
+    QLIST_INSERT_HEAD(&blkdev->freelist, ioreq, list);
+    if (finish) {
+        blkdev->requests_finished--;
+    } else {
+        blkdev->requests_inflight--;
+    }
+}
+
+/*
+ * translate request into iovec + start offset
+ * do sanity checks along the way
+ */
+static int ioreq_parse(struct ioreq *ioreq)
+{
+    struct XenBlkDev *blkdev = ioreq->blkdev;
+    struct XenLegacyDevice *xendev = &blkdev->xendev;
+    size_t len;
+    int i;
+
+    xen_pv_printf(
+        xendev, 3,
+        "op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 "\n",
+        ioreq->req.operation, ioreq->req.nr_segments,
+        ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number);
+    switch (ioreq->req.operation) {
+    case BLKIF_OP_READ:
+        break;
+    case BLKIF_OP_FLUSH_DISKCACHE:
+        ioreq->presync = 1;
+        if (!ioreq->req.nr_segments) {
+            return 0;
+        }
+        /* fall through */
+    case BLKIF_OP_WRITE:
+        break;
+    case BLKIF_OP_DISCARD:
+        return 0;
+    default:
+        xen_pv_printf(xendev, 0, "error: unknown operation (%d)\n",
+                      ioreq->req.operation);
+        goto err;
+    };
+
+    if (ioreq->req.operation != BLKIF_OP_READ && blkdev->mode[0] != 'w') {
+        xen_pv_printf(xendev, 0, "error: write req for ro device\n");
+        goto err;
+    }
+
+    ioreq->start = ioreq->req.sector_number * blkdev->file_blk;
+    for (i = 0; i < ioreq->req.nr_segments; i++) {
+        if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
+            xen_pv_printf(xendev, 0, "error: nr_segments too big\n");
+            goto err;
+        }
+        if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) {
+            xen_pv_printf(xendev, 0, "error: first > last sector\n");
+            goto err;
+        }
+        if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >= XC_PAGE_SIZE) {
+            xen_pv_printf(xendev, 0, "error: page crossing\n");
+            goto err;
+        }
+
+        len = (ioreq->req.seg[i].last_sect -
+               ioreq->req.seg[i].first_sect + 1) * blkdev->file_blk;
+        ioreq->size += len;
+    }
+    if (ioreq->start + ioreq->size > blkdev->file_size) {
+        xen_pv_printf(xendev, 0, "error: access beyond end of file\n");
+        goto err;
+    }
+    return 0;
+
+err:
+    ioreq->status = BLKIF_RSP_ERROR;
+    return -1;
+}
+
+static int ioreq_grant_copy(struct ioreq *ioreq)
+{
+    struct XenBlkDev *blkdev = ioreq->blkdev;
+    struct XenLegacyDevice *xendev = &blkdev->xendev;
+    XenGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+    int i, count, rc;
+    int64_t file_blk = blkdev->file_blk;
+    bool to_domain = (ioreq->req.operation == BLKIF_OP_READ);
+    void *virt = ioreq->buf;
+
+    if (ioreq->req.nr_segments == 0) {
+        return 0;
+    }
+
+    count = ioreq->req.nr_segments;
+
+    for (i = 0; i < count; i++) {
+        if (to_domain) {
+            segs[i].dest.foreign.ref = ioreq->req.seg[i].gref;
+            segs[i].dest.foreign.offset = ioreq->req.seg[i].first_sect *
+                file_blk;
+            segs[i].source.virt = virt;
+        } else {
+            segs[i].source.foreign.ref = ioreq->req.seg[i].gref;
+            segs[i].source.foreign.offset = ioreq->req.seg[i].first_sect *
+                file_blk;
+            segs[i].dest.virt = virt;
+        }
+        segs[i].len = (ioreq->req.seg[i].last_sect
+                       - ioreq->req.seg[i].first_sect + 1) * file_blk;
+        virt += segs[i].len;
+    }
+
+    rc = xen_be_copy_grant_refs(xendev, to_domain, segs, count);
+
+    if (rc) {
+        xen_pv_printf(xendev, 0,
+                      "failed to copy data %d\n", rc);
+        ioreq->aio_errors++;
+        return -1;
+    }
+
+    return rc;
+}
+
+static int ioreq_runio_qemu_aio(struct ioreq *ioreq);
+
+static void qemu_aio_complete(void *opaque, int ret)
+{
+    struct ioreq *ioreq = opaque;
+    struct XenBlkDev *blkdev = ioreq->blkdev;
+    struct XenLegacyDevice *xendev = &blkdev->xendev;
+
+    aio_context_acquire(blkdev->ctx);
+
+    if (ret != 0) {
+        xen_pv_printf(xendev, 0, "%s I/O error\n",
+                      ioreq->req.operation == BLKIF_OP_READ ? "read" : "write");
+        ioreq->aio_errors++;
+    }
+
+    ioreq->aio_inflight--;
+    if (ioreq->presync) {
+        ioreq->presync = 0;
+        ioreq_runio_qemu_aio(ioreq);
+        goto done;
+    }
+    if (ioreq->aio_inflight > 0) {
+        goto done;
+    }
+
+    switch (ioreq->req.operation) {
+    case BLKIF_OP_READ:
+        /* in case of failure ioreq->aio_errors is increased */
+        if (ret == 0) {
+            ioreq_grant_copy(ioreq);
+        }
+        qemu_vfree(ioreq->buf);
+        break;
+    case BLKIF_OP_WRITE:
+    case BLKIF_OP_FLUSH_DISKCACHE:
+        if (!ioreq->req.nr_segments) {
+            break;
+        }
+        qemu_vfree(ioreq->buf);
+        break;
+    default:
+        break;
+    }
+
+    ioreq->status = ioreq->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY;
+    ioreq_finish(ioreq);
+
+    switch (ioreq->req.operation) {
+    case BLKIF_OP_WRITE:
+    case BLKIF_OP_FLUSH_DISKCACHE:
+        if (!ioreq->req.nr_segments) {
+            break;
+        }
+    case BLKIF_OP_READ:
+        if (ioreq->status == BLKIF_RSP_OKAY) {
+            block_acct_done(blk_get_stats(blkdev->blk), &ioreq->acct);
+        } else {
+            block_acct_failed(blk_get_stats(blkdev->blk), &ioreq->acct);
+        }
+        break;
+    case BLKIF_OP_DISCARD:
+    default:
+        break;
+    }
+    qemu_bh_schedule(blkdev->bh);
+
+done:
+    aio_context_release(blkdev->ctx);
+}
+
+static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_number,
+                              uint64_t nr_sectors)
+{
+    struct XenBlkDev *blkdev = ioreq->blkdev;
+    int64_t byte_offset;
+    int byte_chunk;
+    uint64_t byte_remaining, limit;
+    uint64_t sec_start = sector_number;
+    uint64_t sec_count = nr_sectors;
+
+    /* Wrap around, or overflowing byte limit? */
+    if (sec_start + sec_count < sec_count ||
+        sec_start + sec_count > INT64_MAX >> BDRV_SECTOR_BITS) {
+        return false;
+    }
+
+    limit = BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS;
+    byte_offset = sec_start << BDRV_SECTOR_BITS;
+    byte_remaining = sec_count << BDRV_SECTOR_BITS;
+
+    do {
+        byte_chunk = byte_remaining > limit ? limit : byte_remaining;
+        ioreq->aio_inflight++;
+        blk_aio_pdiscard(blkdev->blk, byte_offset, byte_chunk,
+                         qemu_aio_complete, ioreq);
+        byte_remaining -= byte_chunk;
+        byte_offset += byte_chunk;
+    } while (byte_remaining > 0);
+
+    return true;
+}
+
+static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
+{
+    struct XenBlkDev *blkdev = ioreq->blkdev;
+
+    ioreq->buf = qemu_memalign(XC_PAGE_SIZE, ioreq->size);
+    if (ioreq->req.nr_segments &&
+        (ioreq->req.operation == BLKIF_OP_WRITE ||
+         ioreq->req.operation == BLKIF_OP_FLUSH_DISKCACHE) &&
+        ioreq_grant_copy(ioreq)) {
+        qemu_vfree(ioreq->buf);
+        goto err;
+    }
+
+    ioreq->aio_inflight++;
+    if (ioreq->presync) {
+        blk_aio_flush(ioreq->blkdev->blk, qemu_aio_complete, ioreq);
+        return 0;
+    }
+
+    switch (ioreq->req.operation) {
+    case BLKIF_OP_READ:
+        qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size);
+        block_acct_start(blk_get_stats(blkdev->blk), &ioreq->acct,
+                         ioreq->v.size, BLOCK_ACCT_READ);
+        ioreq->aio_inflight++;
+        blk_aio_preadv(blkdev->blk, ioreq->start, &ioreq->v, 0,
+                       qemu_aio_complete, ioreq);
+        break;
+    case BLKIF_OP_WRITE:
+    case BLKIF_OP_FLUSH_DISKCACHE:
+        if (!ioreq->req.nr_segments) {
+            break;
+        }
+
+        qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size);
+        block_acct_start(blk_get_stats(blkdev->blk), &ioreq->acct,
+                         ioreq->v.size,
+                         ioreq->req.operation == BLKIF_OP_WRITE ?
+                         BLOCK_ACCT_WRITE : BLOCK_ACCT_FLUSH);
+        ioreq->aio_inflight++;
+        blk_aio_pwritev(blkdev->blk, ioreq->start, &ioreq->v, 0,
+                        qemu_aio_complete, ioreq);
+        break;
+    case BLKIF_OP_DISCARD:
+    {
+        struct blkif_request_discard *req = (void *)&ioreq->req;
+        if (!blk_split_discard(ioreq, req->sector_number, req->nr_sectors)) {
+            goto err;
+        }
+        break;
+    }
+    default:
+        /* unknown operation (shouldn't happen -- parse catches this) */
+        goto err;
+    }
+
+    qemu_aio_complete(ioreq, 0);
+
+    return 0;
+
+err:
+    ioreq_finish(ioreq);
+    ioreq->status = BLKIF_RSP_ERROR;
+    return -1;
+}
+
+static int blk_send_response_one(struct ioreq *ioreq)
+{
+    struct XenBlkDev  *blkdev = ioreq->blkdev;
+    int               send_notify   = 0;
+    int               have_requests = 0;
+    blkif_response_t  *resp;
+
+    /* Place on the response ring for the relevant domain. */
+    switch (blkdev->protocol) {
+    case BLKIF_PROTOCOL_NATIVE:
+        resp = (blkif_response_t *)RING_GET_RESPONSE(
+            &blkdev->rings.native,
+            blkdev->rings.native.rsp_prod_pvt);
+        break;
+    case BLKIF_PROTOCOL_X86_32:
+        resp = (blkif_response_t *)RING_GET_RESPONSE(
+            &blkdev->rings.x86_32_part,
+            blkdev->rings.x86_32_part.rsp_prod_pvt);
+        break;
+    case BLKIF_PROTOCOL_X86_64:
+        resp = (blkif_response_t *)RING_GET_RESPONSE(
+            &blkdev->rings.x86_64_part,
+            blkdev->rings.x86_64_part.rsp_prod_pvt);
+        break;
+    default:
+        return 0;
+    }
+
+    resp->id        = ioreq->req.id;
+    resp->operation = ioreq->req.operation;
+    resp->status    = ioreq->status;
+
+    blkdev->rings.common.rsp_prod_pvt++;
+
+    RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blkdev->rings.common, send_notify);
+    if (blkdev->rings.common.rsp_prod_pvt == blkdev->rings.common.req_cons) {
+        /*
+         * Tail check for pending requests. Allows frontend to avoid
+         * notifications if requests are already in flight (lower
+         * overheads and promotes batching).
+         */
+        RING_FINAL_CHECK_FOR_REQUESTS(&blkdev->rings.common, have_requests);
+    } else if (RING_HAS_UNCONSUMED_REQUESTS(&blkdev->rings.common)) {
+        have_requests = 1;
+    }
+
+    if (have_requests) {
+        blkdev->more_work++;
+    }
+    return send_notify;
+}
+
+/* walk finished list, send outstanding responses, free requests */
+static void blk_send_response_all(struct XenBlkDev *blkdev)
+{
+    struct ioreq *ioreq;
+    int send_notify = 0;
+
+    while (!QLIST_EMPTY(&blkdev->finished)) {
+        ioreq = QLIST_FIRST(&blkdev->finished);
+        send_notify += blk_send_response_one(ioreq);
+        ioreq_release(ioreq, true);
+    }
+    if (send_notify) {
+        xen_pv_send_notify(&blkdev->xendev);
+    }
+}
+
+static int blk_get_request(struct XenBlkDev *blkdev, struct ioreq *ioreq,
+                           RING_IDX rc)
+{
+    switch (blkdev->protocol) {
+    case BLKIF_PROTOCOL_NATIVE:
+        memcpy(&ioreq->req, RING_GET_REQUEST(&blkdev->rings.native, rc),
+               sizeof(ioreq->req));
+        break;
+    case BLKIF_PROTOCOL_X86_32:
+        blkif_get_x86_32_req(&ioreq->req,
+                             RING_GET_REQUEST(&blkdev->rings.x86_32_part, rc));
+        break;
+    case BLKIF_PROTOCOL_X86_64:
+        blkif_get_x86_64_req(&ioreq->req,
+                             RING_GET_REQUEST(&blkdev->rings.x86_64_part, rc));
+        break;
+    }
+    /* Prevent the compiler from accessing the on-ring fields instead. */
+    barrier();
+    return 0;
+}
+
+static void blk_handle_requests(struct XenBlkDev *blkdev)
+{
+    RING_IDX rc, rp;
+    struct ioreq *ioreq;
+
+    blkdev->more_work = 0;
+
+    rc = blkdev->rings.common.req_cons;
+    rp = blkdev->rings.common.sring->req_prod;
+    xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
+
+    blk_send_response_all(blkdev);
+    while (rc != rp) {
+        /* pull request from ring */
+        if (RING_REQUEST_CONS_OVERFLOW(&blkdev->rings.common, rc)) {
+            break;
+        }
+        ioreq = ioreq_start(blkdev);
+        if (ioreq == NULL) {
+            blkdev->more_work++;
+            break;
+        }
+        blk_get_request(blkdev, ioreq, rc);
+        blkdev->rings.common.req_cons = ++rc;
+
+        /* parse them */
+        if (ioreq_parse(ioreq) != 0) {
+
+            switch (ioreq->req.operation) {
+            case BLKIF_OP_READ:
+                block_acct_invalid(blk_get_stats(blkdev->blk),
+                                   BLOCK_ACCT_READ);
+                break;
+            case BLKIF_OP_WRITE:
+                block_acct_invalid(blk_get_stats(blkdev->blk),
+                                   BLOCK_ACCT_WRITE);
+                break;
+            case BLKIF_OP_FLUSH_DISKCACHE:
+                block_acct_invalid(blk_get_stats(blkdev->blk),
+                                   BLOCK_ACCT_FLUSH);
+            default:
+                break;
+            };
+
+            if (blk_send_response_one(ioreq)) {
+                xen_pv_send_notify(&blkdev->xendev);
+            }
+            ioreq_release(ioreq, false);
+            continue;
+        }
+
+        ioreq_runio_qemu_aio(ioreq);
+    }
+
+    if (blkdev->more_work && blkdev->requests_inflight < blkdev->max_requests) {
+        qemu_bh_schedule(blkdev->bh);
+    }
+}
+
+/* ------------------------------------------------------------- */
+
+static void blk_bh(void *opaque)
+{
+    struct XenBlkDev *blkdev = opaque;
+
+    aio_context_acquire(blkdev->ctx);
+    blk_handle_requests(blkdev);
+    aio_context_release(blkdev->ctx);
+}
+
+static void blk_alloc(struct XenLegacyDevice *xendev)
+{
+    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
+    Error *err = NULL;
+
+    trace_xen_disk_alloc(xendev->name);
+
+    QLIST_INIT(&blkdev->inflight);
+    QLIST_INIT(&blkdev->finished);
+    QLIST_INIT(&blkdev->freelist);
+
+    blkdev->iothread = iothread_create(xendev->name, &err);
+    assert(!err);
+
+    blkdev->ctx = iothread_get_aio_context(blkdev->iothread);
+    blkdev->bh = aio_bh_new(blkdev->ctx, blk_bh, blkdev);
+}
+
+static void blk_parse_discard(struct XenBlkDev *blkdev)
+{
+    struct XenLegacyDevice *xendev = &blkdev->xendev;
+    int enable;
+
+    blkdev->feature_discard = true;
+
+    if (xenstore_read_be_int(xendev, "discard-enable", &enable) == 0) {
+        blkdev->feature_discard = !!enable;
+    }
+
+    if (blkdev->feature_discard) {
+        xenstore_write_be_int(xendev, "feature-discard", 1);
+    }
+}
+
+static int blk_init(struct XenLegacyDevice *xendev)
+{
+    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
+    int info = 0;
+    char *directiosafe = NULL;
+
+    trace_xen_disk_init(xendev->name);
+
+    /* read xenstore entries */
+    if (blkdev->params == NULL) {
+        char *h = NULL;
+        blkdev->params = xenstore_read_be_str(xendev, "params");
+        if (blkdev->params != NULL) {
+            h = strchr(blkdev->params, ':');
+        }
+        if (h != NULL) {
+            blkdev->fileproto = blkdev->params;
+            blkdev->filename  = h + 1;
+            *h = 0;
+        } else {
+            blkdev->fileproto = "<unset>";
+            blkdev->filename  = blkdev->params;
+        }
+    }
+    if (!strcmp("aio", blkdev->fileproto)) {
+        blkdev->fileproto = "raw";
+    }
+    if (!strcmp("vhd", blkdev->fileproto)) {
+        blkdev->fileproto = "vpc";
+    }
+    if (blkdev->mode == NULL) {
+        blkdev->mode = xenstore_read_be_str(xendev, "mode");
+    }
+    if (blkdev->type == NULL) {
+        blkdev->type = xenstore_read_be_str(xendev, "type");
+    }
+    if (blkdev->dev == NULL) {
+        blkdev->dev = xenstore_read_be_str(xendev, "dev");
+    }
+    if (blkdev->devtype == NULL) {
+        blkdev->devtype = xenstore_read_be_str(xendev, "device-type");
+    }
+    directiosafe = xenstore_read_be_str(xendev, "direct-io-safe");
+    blkdev->directiosafe = (directiosafe && atoi(directiosafe));
+
+    /* do we have all we need? */
+    if (blkdev->params == NULL ||
+        blkdev->mode == NULL   ||
+        blkdev->type == NULL   ||
+        blkdev->dev == NULL) {
+        goto out_error;
+    }
+
+    /* read-only ? */
+    if (strcmp(blkdev->mode, "w")) {
+        info  |= VDISK_READONLY;
+    }
+
+    /* cdrom ? */
+    if (blkdev->devtype && !strcmp(blkdev->devtype, "cdrom")) {
+        info  |= VDISK_CDROM;
+    }
+
+    blkdev->file_blk  = BLOCK_SIZE;
+
+    /* fill info
+     * blk_connect supplies sector-size and sectors
+     */
+    xenstore_write_be_int(xendev, "feature-flush-cache", 1);
+    xenstore_write_be_int(xendev, "info", info);
+
+    xenstore_write_be_int(xendev, "max-ring-page-order",
+                          MAX_RING_PAGE_ORDER);
+
+    blk_parse_discard(blkdev);
+
+    g_free(directiosafe);
+    return 0;
+
+out_error:
+    g_free(blkdev->params);
+    blkdev->params = NULL;
+    g_free(blkdev->mode);
+    blkdev->mode = NULL;
+    g_free(blkdev->type);
+    blkdev->type = NULL;
+    g_free(blkdev->dev);
+    blkdev->dev = NULL;
+    g_free(blkdev->devtype);
+    blkdev->devtype = NULL;
+    g_free(directiosafe);
+    blkdev->directiosafe = false;
+    return -1;
+}
+
+static int blk_connect(struct XenLegacyDevice *xendev)
+{
+    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
+    int index, qflags;
+    bool readonly = true;
+    bool writethrough = true;
+    int order, ring_ref;
+    unsigned int ring_size, max_grants;
+    unsigned int i;
+
+    trace_xen_disk_connect(xendev->name);
+
+    /* read-only ? */
+    if (blkdev->directiosafe) {
+        qflags = BDRV_O_NOCACHE | BDRV_O_NATIVE_AIO;
+    } else {
+        qflags = 0;
+        writethrough = false;
+    }
+    if (strcmp(blkdev->mode, "w") == 0) {
+        qflags |= BDRV_O_RDWR;
+        readonly = false;
+    }
+    if (blkdev->feature_discard) {
+        qflags |= BDRV_O_UNMAP;
+    }
+
+    /* init qemu block driver */
+    index = (xendev->dev - 202 * 256) / 16;
+    blkdev->dinfo = drive_get(IF_XEN, 0, index);
+    if (!blkdev->dinfo) {
+        Error *local_err = NULL;
+        QDict *options = NULL;
+
+        if (strcmp(blkdev->fileproto, "<unset>")) {
+            options = qdict_new();
+            qdict_put_str(options, "driver", blkdev->fileproto);
+        }
+
+        /* setup via xenbus -> create new block driver instance */
+        xen_pv_printf(xendev, 2, "create new bdrv (xenbus setup)\n");
+        blkdev->blk = blk_new_open(blkdev->filename, NULL, options,
+                                   qflags, &local_err);
+        if (!blkdev->blk) {
+            xen_pv_printf(xendev, 0, "error: %s\n",
+                          error_get_pretty(local_err));
+            error_free(local_err);
+            return -1;
+        }
+        blk_set_enable_write_cache(blkdev->blk, !writethrough);
+    } else {
+        /* setup via qemu cmdline -> already setup for us */
+        xen_pv_printf(xendev, 2,
+                      "get configured bdrv (cmdline setup)\n");
+        blkdev->blk = blk_by_legacy_dinfo(blkdev->dinfo);
+        if (blk_is_read_only(blkdev->blk) && !readonly) {
+            xen_pv_printf(xendev, 0, "Unexpected read-only drive");
+            blkdev->blk = NULL;
+            return -1;
+        }
+        /* blkdev->blk is not create by us, we get a reference
+         * so we can blk_unref() unconditionally */
+        blk_ref(blkdev->blk);
+    }
+    blk_attach_dev_legacy(blkdev->blk, blkdev);
+    blkdev->file_size = blk_getlength(blkdev->blk);
+    if (blkdev->file_size < 0) {
+        BlockDriverState *bs = blk_bs(blkdev->blk);
+        const char *drv_name = bs ? bdrv_get_format_name(bs) : NULL;
+        xen_pv_printf(xendev, 1, "blk_getlength: %d (%s) | drv %s\n",
+                      (int)blkdev->file_size, strerror(-blkdev->file_size),
+                      drv_name ?: "-");
+        blkdev->file_size = 0;
+    }
+
+    xen_pv_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\","
+                  " size %" PRId64 " (%" PRId64 " MB)\n",
+                  blkdev->type, blkdev->fileproto, blkdev->filename,
+                  blkdev->file_size, blkdev->file_size / MiB);
+
+    /* Fill in number of sector size and number of sectors */
+    xenstore_write_be_int(xendev, "sector-size", blkdev->file_blk);
+    xenstore_write_be_int64(xendev, "sectors",
+                            blkdev->file_size / blkdev->file_blk);
+
+    if (xenstore_read_fe_int(xendev, "ring-page-order",
+                             &order) == -1) {
+        blkdev->nr_ring_ref = 1;
+
+        if (xenstore_read_fe_int(xendev, "ring-ref",
+                                 &ring_ref) == -1) {
+            return -1;
+        }
+        blkdev->ring_ref[0] = ring_ref;
+
+    } else if (order >= 0 && order <= MAX_RING_PAGE_ORDER) {
+        blkdev->nr_ring_ref = 1 << order;
+
+        for (i = 0; i < blkdev->nr_ring_ref; i++) {
+            char *key;
+
+            key = g_strdup_printf("ring-ref%u", i);
+            if (!key) {
+                return -1;
+            }
+
+            if (xenstore_read_fe_int(xendev, key,
+                                     &ring_ref) == -1) {
+                g_free(key);
+                return -1;
+            }
+            blkdev->ring_ref[i] = ring_ref;
+
+            g_free(key);
+        }
+    } else {
+        xen_pv_printf(xendev, 0, "invalid ring-page-order: %d\n",
+                      order);
+        return -1;
+    }
+
+    if (xenstore_read_fe_int(xendev, "event-channel",
+                             &xendev->remote_port) == -1) {
+        return -1;
+    }
+
+    if (!xendev->protocol) {
+        blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
+    } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_NATIVE) == 0) {
+        blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
+    } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_X86_32) == 0) {
+        blkdev->protocol = BLKIF_PROTOCOL_X86_32;
+    } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_X86_64) == 0) {
+        blkdev->protocol = BLKIF_PROTOCOL_X86_64;
+    } else {
+        blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
+    }
+
+    ring_size = XC_PAGE_SIZE * blkdev->nr_ring_ref;
+    switch (blkdev->protocol) {
+    case BLKIF_PROTOCOL_NATIVE:
+    {
+        blkdev->max_requests = __CONST_RING_SIZE(blkif, ring_size);
+        break;
+    }
+    case BLKIF_PROTOCOL_X86_32:
+    {
+        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_32, ring_size);
+        break;
+    }
+    case BLKIF_PROTOCOL_X86_64:
+    {
+        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_64, ring_size);
+        break;
+    }
+    default:
+        return -1;
+    }
+
+    /* Add on the number needed for the ring pages */
+    max_grants = blkdev->nr_ring_ref;
+
+    xen_be_set_max_grant_refs(xendev, max_grants);
+    blkdev->sring = xen_be_map_grant_refs(xendev, blkdev->ring_ref,
+                                          blkdev->nr_ring_ref,
+                                          PROT_READ | PROT_WRITE);
+    if (!blkdev->sring) {
+        return -1;
+    }
+
+    switch (blkdev->protocol) {
+    case BLKIF_PROTOCOL_NATIVE:
+    {
+        blkif_sring_t *sring_native = blkdev->sring;
+        BACK_RING_INIT(&blkdev->rings.native, sring_native, ring_size);
+        break;
+    }
+    case BLKIF_PROTOCOL_X86_32:
+    {
+        blkif_x86_32_sring_t *sring_x86_32 = blkdev->sring;
+
+        BACK_RING_INIT(&blkdev->rings.x86_32_part, sring_x86_32, ring_size);
+        break;
+    }
+    case BLKIF_PROTOCOL_X86_64:
+    {
+        blkif_x86_64_sring_t *sring_x86_64 = blkdev->sring;
+
+        BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64, ring_size);
+        break;
+    }
+    }
+
+    blk_set_aio_context(blkdev->blk, blkdev->ctx);
+
+    xen_be_bind_evtchn(xendev);
+
+    xen_pv_printf(xendev, 1, "ok: proto %s, nr-ring-ref %u, "
+                  "remote port %d, local port %d\n",
+                  xendev->protocol, blkdev->nr_ring_ref,
+                  xendev->remote_port, xendev->local_port);
+    return 0;
+}
+
+static void blk_disconnect(struct XenLegacyDevice *xendev)
+{
+    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
+
+    trace_xen_disk_disconnect(xendev->name);
+
+    aio_context_acquire(blkdev->ctx);
+
+    if (blkdev->blk) {
+        blk_set_aio_context(blkdev->blk, qemu_get_aio_context());
+        blk_detach_dev(blkdev->blk, blkdev);
+        blk_unref(blkdev->blk);
+        blkdev->blk = NULL;
+    }
+    xen_pv_unbind_evtchn(xendev);
+
+    aio_context_release(blkdev->ctx);
+
+    if (blkdev->sring) {
+        xen_be_unmap_grant_refs(xendev, blkdev->sring,
+                                blkdev->nr_ring_ref);
+        blkdev->sring = NULL;
+    }
+}
+
+static int blk_free(struct XenLegacyDevice *xendev)
+{
+    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
+    struct ioreq *ioreq;
+
+    trace_xen_disk_free(xendev->name);
+
+    blk_disconnect(xendev);
+
+    while (!QLIST_EMPTY(&blkdev->freelist)) {
+        ioreq = QLIST_FIRST(&blkdev->freelist);
+        QLIST_REMOVE(ioreq, list);
+        qemu_iovec_destroy(&ioreq->v);
+        g_free(ioreq);
+    }
+
+    g_free(blkdev->params);
+    g_free(blkdev->mode);
+    g_free(blkdev->type);
+    g_free(blkdev->dev);
+    g_free(blkdev->devtype);
+    qemu_bh_delete(blkdev->bh);
+    iothread_destroy(blkdev->iothread);
+    return 0;
+}
+
+static void blk_event(struct XenLegacyDevice *xendev)
+{
+    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
+
+    qemu_bh_schedule(blkdev->bh);
+}
+
+struct XenDevOps xen_blkdev_ops = {
+    .flags      = DEVOPS_FLAG_NEED_GNTDEV,
+    .size       = sizeof(struct XenBlkDev),
+    .alloc      = blk_alloc,
+    .init       = blk_init,
+    .initialise = blk_connect,
+    .disconnect = blk_disconnect,
+    .event      = blk_event,
+    .free       = blk_free,
+};
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [Qemu-devel] [PATCH 09/18] xen: remove unnecessary code from dataplane/xen-qdisk.c
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
@ 2018-11-21 15:12   ` Paul Durrant
  2018-11-21 15:11 ` [Qemu-devel] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy Paul Durrant
                     ` (24 subsequent siblings)
  25 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Paul Durrant, Stefano Stabellini, Anthony Perard,
	Stefan Hajnoczi, Kevin Wolf, Max Reitz

Not all of the code duplicated from xen_disk.c is required as the basis for
the new dataplane implementation so this patch removes extraneous code,
along with the legacy #includes and calls to the legacy xen_pv_printf()
function. Error messages are changed to be reported using error_report().

NOTE: The code is still not yet built. Further transformations will be
      required to make it correctly interface to the new XenBus/XenDevice
      framework. They will be delivered in a subsequent patch.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
---
 hw/block/dataplane/xen-qdisk.c | 422 ++---------------------------------------
 1 file changed, 13 insertions(+), 409 deletions(-)

diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-qdisk.c
index 9fae50534e..8e4368e7af 100644
--- a/hw/block/dataplane/xen-qdisk.c
+++ b/hw/block/dataplane/xen-qdisk.c
@@ -1,45 +1,10 @@
 /*
- *  xen paravirt block device backend
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
  *
- *  (c) Gerd Hoffmann <kraxel@redhat.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; under version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- *  Contributions after 2012-01-13 are licensed under the terms of the
- *  GNU GPL, version 2 or (at your option) any later version.
+ * Based on original code (c) Gerd Hoffmann <kraxel@redhat.com>
  */
 
-#include "qemu/osdep.h"
-#include "qemu/units.h"
-#include <sys/ioctl.h>
-#include <sys/uio.h>
-
-#include "hw/hw.h"
-#include "hw/xen/xen_backend.h"
-#include "xen_blkif.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/iothread.h"
-#include "sysemu/block-backend.h"
-#include "qapi/error.h"
-#include "qapi/qmp/qdict.h"
-#include "qapi/qmp/qstring.h"
-#include "trace.h"
-
-/* ------------------------------------------------------------- */
-
-#define BLOCK_SIZE  512
-#define IOCB_COUNT  (BLKIF_MAX_SEGMENTS_PER_REQUEST + 2)
-
 struct ioreq {
     blkif_request_t     req;
     int16_t             status;
@@ -101,8 +66,6 @@ struct XenBlkDev {
     AioContext          *ctx;
 };
 
-/* ------------------------------------------------------------- */
-
 static void ioreq_reset(struct ioreq *ioreq)
 {
     memset(&ioreq->req, 0, sizeof(ioreq->req));
@@ -183,11 +146,6 @@ static int ioreq_parse(struct ioreq *ioreq)
     size_t len;
     int i;
 
-    xen_pv_printf(
-        xendev, 3,
-        "op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 "\n",
-        ioreq->req.operation, ioreq->req.nr_segments,
-        ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number);
     switch (ioreq->req.operation) {
     case BLKIF_OP_READ:
         break;
@@ -202,28 +160,27 @@ static int ioreq_parse(struct ioreq *ioreq)
     case BLKIF_OP_DISCARD:
         return 0;
     default:
-        xen_pv_printf(xendev, 0, "error: unknown operation (%d)\n",
-                      ioreq->req.operation);
+        error_report("error: unknown operation (%d)", ioreq->req.operation);
         goto err;
     };
 
     if (ioreq->req.operation != BLKIF_OP_READ && blkdev->mode[0] != 'w') {
-        xen_pv_printf(xendev, 0, "error: write req for ro device\n");
+        error_report("error: write req for ro device");
         goto err;
     }
 
     ioreq->start = ioreq->req.sector_number * blkdev->file_blk;
     for (i = 0; i < ioreq->req.nr_segments; i++) {
         if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
-            xen_pv_printf(xendev, 0, "error: nr_segments too big\n");
+            error_report("error: nr_segments too big");
             goto err;
         }
         if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) {
-            xen_pv_printf(xendev, 0, "error: first > last sector\n");
+            error_report("error: first > last sector");
             goto err;
         }
         if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >= XC_PAGE_SIZE) {
-            xen_pv_printf(xendev, 0, "error: page crossing\n");
+            error_report("error: page crossing");
             goto err;
         }
 
@@ -232,7 +189,7 @@ static int ioreq_parse(struct ioreq *ioreq)
         ioreq->size += len;
     }
     if (ioreq->start + ioreq->size > blkdev->file_size) {
-        xen_pv_printf(xendev, 0, "error: access beyond end of file\n");
+        error_report("error: access beyond end of file");
         goto err;
     }
     return 0;
@@ -278,8 +235,7 @@ static int ioreq_grant_copy(struct ioreq *ioreq)
     rc = xen_be_copy_grant_refs(xendev, to_domain, segs, count);
 
     if (rc) {
-        xen_pv_printf(xendev, 0,
-                      "failed to copy data %d\n", rc);
+        error_report("failed to copy data %d", rc);
         ioreq->aio_errors++;
         return -1;
     }
@@ -298,8 +254,9 @@ static void qemu_aio_complete(void *opaque, int ret)
     aio_context_acquire(blkdev->ctx);
 
     if (ret != 0) {
-        xen_pv_printf(xendev, 0, "%s I/O error\n",
-                      ioreq->req.operation == BLKIF_OP_READ ? "read" : "write");
+        error_report("%s I/O error",
+                     ioreq->req.operation == BLKIF_OP_READ ?
+                     "read" : "write");
         ioreq->aio_errors++;
     }
 
@@ -605,8 +562,6 @@ static void blk_handle_requests(struct XenBlkDev *blkdev)
     }
 }
 
-/* ------------------------------------------------------------- */
-
 static void blk_bh(void *opaque)
 {
     struct XenBlkDev *blkdev = opaque;
@@ -634,346 +589,6 @@ static void blk_alloc(struct XenLegacyDevice *xendev)
     blkdev->bh = aio_bh_new(blkdev->ctx, blk_bh, blkdev);
 }
 
-static void blk_parse_discard(struct XenBlkDev *blkdev)
-{
-    struct XenLegacyDevice *xendev = &blkdev->xendev;
-    int enable;
-
-    blkdev->feature_discard = true;
-
-    if (xenstore_read_be_int(xendev, "discard-enable", &enable) == 0) {
-        blkdev->feature_discard = !!enable;
-    }
-
-    if (blkdev->feature_discard) {
-        xenstore_write_be_int(xendev, "feature-discard", 1);
-    }
-}
-
-static int blk_init(struct XenLegacyDevice *xendev)
-{
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
-    int info = 0;
-    char *directiosafe = NULL;
-
-    trace_xen_disk_init(xendev->name);
-
-    /* read xenstore entries */
-    if (blkdev->params == NULL) {
-        char *h = NULL;
-        blkdev->params = xenstore_read_be_str(xendev, "params");
-        if (blkdev->params != NULL) {
-            h = strchr(blkdev->params, ':');
-        }
-        if (h != NULL) {
-            blkdev->fileproto = blkdev->params;
-            blkdev->filename  = h + 1;
-            *h = 0;
-        } else {
-            blkdev->fileproto = "<unset>";
-            blkdev->filename  = blkdev->params;
-        }
-    }
-    if (!strcmp("aio", blkdev->fileproto)) {
-        blkdev->fileproto = "raw";
-    }
-    if (!strcmp("vhd", blkdev->fileproto)) {
-        blkdev->fileproto = "vpc";
-    }
-    if (blkdev->mode == NULL) {
-        blkdev->mode = xenstore_read_be_str(xendev, "mode");
-    }
-    if (blkdev->type == NULL) {
-        blkdev->type = xenstore_read_be_str(xendev, "type");
-    }
-    if (blkdev->dev == NULL) {
-        blkdev->dev = xenstore_read_be_str(xendev, "dev");
-    }
-    if (blkdev->devtype == NULL) {
-        blkdev->devtype = xenstore_read_be_str(xendev, "device-type");
-    }
-    directiosafe = xenstore_read_be_str(xendev, "direct-io-safe");
-    blkdev->directiosafe = (directiosafe && atoi(directiosafe));
-
-    /* do we have all we need? */
-    if (blkdev->params == NULL ||
-        blkdev->mode == NULL   ||
-        blkdev->type == NULL   ||
-        blkdev->dev == NULL) {
-        goto out_error;
-    }
-
-    /* read-only ? */
-    if (strcmp(blkdev->mode, "w")) {
-        info  |= VDISK_READONLY;
-    }
-
-    /* cdrom ? */
-    if (blkdev->devtype && !strcmp(blkdev->devtype, "cdrom")) {
-        info  |= VDISK_CDROM;
-    }
-
-    blkdev->file_blk  = BLOCK_SIZE;
-
-    /* fill info
-     * blk_connect supplies sector-size and sectors
-     */
-    xenstore_write_be_int(xendev, "feature-flush-cache", 1);
-    xenstore_write_be_int(xendev, "info", info);
-
-    xenstore_write_be_int(xendev, "max-ring-page-order",
-                          MAX_RING_PAGE_ORDER);
-
-    blk_parse_discard(blkdev);
-
-    g_free(directiosafe);
-    return 0;
-
-out_error:
-    g_free(blkdev->params);
-    blkdev->params = NULL;
-    g_free(blkdev->mode);
-    blkdev->mode = NULL;
-    g_free(blkdev->type);
-    blkdev->type = NULL;
-    g_free(blkdev->dev);
-    blkdev->dev = NULL;
-    g_free(blkdev->devtype);
-    blkdev->devtype = NULL;
-    g_free(directiosafe);
-    blkdev->directiosafe = false;
-    return -1;
-}
-
-static int blk_connect(struct XenLegacyDevice *xendev)
-{
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
-    int index, qflags;
-    bool readonly = true;
-    bool writethrough = true;
-    int order, ring_ref;
-    unsigned int ring_size, max_grants;
-    unsigned int i;
-
-    trace_xen_disk_connect(xendev->name);
-
-    /* read-only ? */
-    if (blkdev->directiosafe) {
-        qflags = BDRV_O_NOCACHE | BDRV_O_NATIVE_AIO;
-    } else {
-        qflags = 0;
-        writethrough = false;
-    }
-    if (strcmp(blkdev->mode, "w") == 0) {
-        qflags |= BDRV_O_RDWR;
-        readonly = false;
-    }
-    if (blkdev->feature_discard) {
-        qflags |= BDRV_O_UNMAP;
-    }
-
-    /* init qemu block driver */
-    index = (xendev->dev - 202 * 256) / 16;
-    blkdev->dinfo = drive_get(IF_XEN, 0, index);
-    if (!blkdev->dinfo) {
-        Error *local_err = NULL;
-        QDict *options = NULL;
-
-        if (strcmp(blkdev->fileproto, "<unset>")) {
-            options = qdict_new();
-            qdict_put_str(options, "driver", blkdev->fileproto);
-        }
-
-        /* setup via xenbus -> create new block driver instance */
-        xen_pv_printf(xendev, 2, "create new bdrv (xenbus setup)\n");
-        blkdev->blk = blk_new_open(blkdev->filename, NULL, options,
-                                   qflags, &local_err);
-        if (!blkdev->blk) {
-            xen_pv_printf(xendev, 0, "error: %s\n",
-                          error_get_pretty(local_err));
-            error_free(local_err);
-            return -1;
-        }
-        blk_set_enable_write_cache(blkdev->blk, !writethrough);
-    } else {
-        /* setup via qemu cmdline -> already setup for us */
-        xen_pv_printf(xendev, 2,
-                      "get configured bdrv (cmdline setup)\n");
-        blkdev->blk = blk_by_legacy_dinfo(blkdev->dinfo);
-        if (blk_is_read_only(blkdev->blk) && !readonly) {
-            xen_pv_printf(xendev, 0, "Unexpected read-only drive");
-            blkdev->blk = NULL;
-            return -1;
-        }
-        /* blkdev->blk is not create by us, we get a reference
-         * so we can blk_unref() unconditionally */
-        blk_ref(blkdev->blk);
-    }
-    blk_attach_dev_legacy(blkdev->blk, blkdev);
-    blkdev->file_size = blk_getlength(blkdev->blk);
-    if (blkdev->file_size < 0) {
-        BlockDriverState *bs = blk_bs(blkdev->blk);
-        const char *drv_name = bs ? bdrv_get_format_name(bs) : NULL;
-        xen_pv_printf(xendev, 1, "blk_getlength: %d (%s) | drv %s\n",
-                      (int)blkdev->file_size, strerror(-blkdev->file_size),
-                      drv_name ?: "-");
-        blkdev->file_size = 0;
-    }
-
-    xen_pv_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\","
-                  " size %" PRId64 " (%" PRId64 " MB)\n",
-                  blkdev->type, blkdev->fileproto, blkdev->filename,
-                  blkdev->file_size, blkdev->file_size / MiB);
-
-    /* Fill in number of sector size and number of sectors */
-    xenstore_write_be_int(xendev, "sector-size", blkdev->file_blk);
-    xenstore_write_be_int64(xendev, "sectors",
-                            blkdev->file_size / blkdev->file_blk);
-
-    if (xenstore_read_fe_int(xendev, "ring-page-order",
-                             &order) == -1) {
-        blkdev->nr_ring_ref = 1;
-
-        if (xenstore_read_fe_int(xendev, "ring-ref",
-                                 &ring_ref) == -1) {
-            return -1;
-        }
-        blkdev->ring_ref[0] = ring_ref;
-
-    } else if (order >= 0 && order <= MAX_RING_PAGE_ORDER) {
-        blkdev->nr_ring_ref = 1 << order;
-
-        for (i = 0; i < blkdev->nr_ring_ref; i++) {
-            char *key;
-
-            key = g_strdup_printf("ring-ref%u", i);
-            if (!key) {
-                return -1;
-            }
-
-            if (xenstore_read_fe_int(xendev, key,
-                                     &ring_ref) == -1) {
-                g_free(key);
-                return -1;
-            }
-            blkdev->ring_ref[i] = ring_ref;
-
-            g_free(key);
-        }
-    } else {
-        xen_pv_printf(xendev, 0, "invalid ring-page-order: %d\n",
-                      order);
-        return -1;
-    }
-
-    if (xenstore_read_fe_int(xendev, "event-channel",
-                             &xendev->remote_port) == -1) {
-        return -1;
-    }
-
-    if (!xendev->protocol) {
-        blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
-    } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_NATIVE) == 0) {
-        blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
-    } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_X86_32) == 0) {
-        blkdev->protocol = BLKIF_PROTOCOL_X86_32;
-    } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_X86_64) == 0) {
-        blkdev->protocol = BLKIF_PROTOCOL_X86_64;
-    } else {
-        blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
-    }
-
-    ring_size = XC_PAGE_SIZE * blkdev->nr_ring_ref;
-    switch (blkdev->protocol) {
-    case BLKIF_PROTOCOL_NATIVE:
-    {
-        blkdev->max_requests = __CONST_RING_SIZE(blkif, ring_size);
-        break;
-    }
-    case BLKIF_PROTOCOL_X86_32:
-    {
-        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_32, ring_size);
-        break;
-    }
-    case BLKIF_PROTOCOL_X86_64:
-    {
-        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_64, ring_size);
-        break;
-    }
-    default:
-        return -1;
-    }
-
-    /* Add on the number needed for the ring pages */
-    max_grants = blkdev->nr_ring_ref;
-
-    xen_be_set_max_grant_refs(xendev, max_grants);
-    blkdev->sring = xen_be_map_grant_refs(xendev, blkdev->ring_ref,
-                                          blkdev->nr_ring_ref,
-                                          PROT_READ | PROT_WRITE);
-    if (!blkdev->sring) {
-        return -1;
-    }
-
-    switch (blkdev->protocol) {
-    case BLKIF_PROTOCOL_NATIVE:
-    {
-        blkif_sring_t *sring_native = blkdev->sring;
-        BACK_RING_INIT(&blkdev->rings.native, sring_native, ring_size);
-        break;
-    }
-    case BLKIF_PROTOCOL_X86_32:
-    {
-        blkif_x86_32_sring_t *sring_x86_32 = blkdev->sring;
-
-        BACK_RING_INIT(&blkdev->rings.x86_32_part, sring_x86_32, ring_size);
-        break;
-    }
-    case BLKIF_PROTOCOL_X86_64:
-    {
-        blkif_x86_64_sring_t *sring_x86_64 = blkdev->sring;
-
-        BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64, ring_size);
-        break;
-    }
-    }
-
-    blk_set_aio_context(blkdev->blk, blkdev->ctx);
-
-    xen_be_bind_evtchn(xendev);
-
-    xen_pv_printf(xendev, 1, "ok: proto %s, nr-ring-ref %u, "
-                  "remote port %d, local port %d\n",
-                  xendev->protocol, blkdev->nr_ring_ref,
-                  xendev->remote_port, xendev->local_port);
-    return 0;
-}
-
-static void blk_disconnect(struct XenLegacyDevice *xendev)
-{
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
-
-    trace_xen_disk_disconnect(xendev->name);
-
-    aio_context_acquire(blkdev->ctx);
-
-    if (blkdev->blk) {
-        blk_set_aio_context(blkdev->blk, qemu_get_aio_context());
-        blk_detach_dev(blkdev->blk, blkdev);
-        blk_unref(blkdev->blk);
-        blkdev->blk = NULL;
-    }
-    xen_pv_unbind_evtchn(xendev);
-
-    aio_context_release(blkdev->ctx);
-
-    if (blkdev->sring) {
-        xen_be_unmap_grant_refs(xendev, blkdev->sring,
-                                blkdev->nr_ring_ref);
-        blkdev->sring = NULL;
-    }
-}
-
 static int blk_free(struct XenLegacyDevice *xendev)
 {
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
@@ -1006,14 +621,3 @@ static void blk_event(struct XenLegacyDevice *xendev)
 
     qemu_bh_schedule(blkdev->bh);
 }
-
-struct XenDevOps xen_blkdev_ops = {
-    .flags      = DEVOPS_FLAG_NEED_GNTDEV,
-    .size       = sizeof(struct XenBlkDev),
-    .alloc      = blk_alloc,
-    .init       = blk_init,
-    .initialise = blk_connect,
-    .disconnect = blk_disconnect,
-    .event      = blk_event,
-    .free       = blk_free,
-};
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [PATCH 09/18] xen: remove unnecessary code from dataplane/xen-qdisk.c
@ 2018-11-21 15:12   ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Kevin Wolf, Stefano Stabellini, Max Reitz, Paul Durrant,
	Stefan Hajnoczi, Anthony Perard

Not all of the code duplicated from xen_disk.c is required as the basis for
the new dataplane implementation so this patch removes extraneous code,
along with the legacy #includes and calls to the legacy xen_pv_printf()
function. Error messages are changed to be reported using error_report().

NOTE: The code is still not yet built. Further transformations will be
      required to make it correctly interface to the new XenBus/XenDevice
      framework. They will be delivered in a subsequent patch.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
---
 hw/block/dataplane/xen-qdisk.c | 422 ++---------------------------------------
 1 file changed, 13 insertions(+), 409 deletions(-)

diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-qdisk.c
index 9fae50534e..8e4368e7af 100644
--- a/hw/block/dataplane/xen-qdisk.c
+++ b/hw/block/dataplane/xen-qdisk.c
@@ -1,45 +1,10 @@
 /*
- *  xen paravirt block device backend
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
  *
- *  (c) Gerd Hoffmann <kraxel@redhat.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; under version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- *  Contributions after 2012-01-13 are licensed under the terms of the
- *  GNU GPL, version 2 or (at your option) any later version.
+ * Based on original code (c) Gerd Hoffmann <kraxel@redhat.com>
  */
 
-#include "qemu/osdep.h"
-#include "qemu/units.h"
-#include <sys/ioctl.h>
-#include <sys/uio.h>
-
-#include "hw/hw.h"
-#include "hw/xen/xen_backend.h"
-#include "xen_blkif.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/iothread.h"
-#include "sysemu/block-backend.h"
-#include "qapi/error.h"
-#include "qapi/qmp/qdict.h"
-#include "qapi/qmp/qstring.h"
-#include "trace.h"
-
-/* ------------------------------------------------------------- */
-
-#define BLOCK_SIZE  512
-#define IOCB_COUNT  (BLKIF_MAX_SEGMENTS_PER_REQUEST + 2)
-
 struct ioreq {
     blkif_request_t     req;
     int16_t             status;
@@ -101,8 +66,6 @@ struct XenBlkDev {
     AioContext          *ctx;
 };
 
-/* ------------------------------------------------------------- */
-
 static void ioreq_reset(struct ioreq *ioreq)
 {
     memset(&ioreq->req, 0, sizeof(ioreq->req));
@@ -183,11 +146,6 @@ static int ioreq_parse(struct ioreq *ioreq)
     size_t len;
     int i;
 
-    xen_pv_printf(
-        xendev, 3,
-        "op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 "\n",
-        ioreq->req.operation, ioreq->req.nr_segments,
-        ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number);
     switch (ioreq->req.operation) {
     case BLKIF_OP_READ:
         break;
@@ -202,28 +160,27 @@ static int ioreq_parse(struct ioreq *ioreq)
     case BLKIF_OP_DISCARD:
         return 0;
     default:
-        xen_pv_printf(xendev, 0, "error: unknown operation (%d)\n",
-                      ioreq->req.operation);
+        error_report("error: unknown operation (%d)", ioreq->req.operation);
         goto err;
     };
 
     if (ioreq->req.operation != BLKIF_OP_READ && blkdev->mode[0] != 'w') {
-        xen_pv_printf(xendev, 0, "error: write req for ro device\n");
+        error_report("error: write req for ro device");
         goto err;
     }
 
     ioreq->start = ioreq->req.sector_number * blkdev->file_blk;
     for (i = 0; i < ioreq->req.nr_segments; i++) {
         if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
-            xen_pv_printf(xendev, 0, "error: nr_segments too big\n");
+            error_report("error: nr_segments too big");
             goto err;
         }
         if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) {
-            xen_pv_printf(xendev, 0, "error: first > last sector\n");
+            error_report("error: first > last sector");
             goto err;
         }
         if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >= XC_PAGE_SIZE) {
-            xen_pv_printf(xendev, 0, "error: page crossing\n");
+            error_report("error: page crossing");
             goto err;
         }
 
@@ -232,7 +189,7 @@ static int ioreq_parse(struct ioreq *ioreq)
         ioreq->size += len;
     }
     if (ioreq->start + ioreq->size > blkdev->file_size) {
-        xen_pv_printf(xendev, 0, "error: access beyond end of file\n");
+        error_report("error: access beyond end of file");
         goto err;
     }
     return 0;
@@ -278,8 +235,7 @@ static int ioreq_grant_copy(struct ioreq *ioreq)
     rc = xen_be_copy_grant_refs(xendev, to_domain, segs, count);
 
     if (rc) {
-        xen_pv_printf(xendev, 0,
-                      "failed to copy data %d\n", rc);
+        error_report("failed to copy data %d", rc);
         ioreq->aio_errors++;
         return -1;
     }
@@ -298,8 +254,9 @@ static void qemu_aio_complete(void *opaque, int ret)
     aio_context_acquire(blkdev->ctx);
 
     if (ret != 0) {
-        xen_pv_printf(xendev, 0, "%s I/O error\n",
-                      ioreq->req.operation == BLKIF_OP_READ ? "read" : "write");
+        error_report("%s I/O error",
+                     ioreq->req.operation == BLKIF_OP_READ ?
+                     "read" : "write");
         ioreq->aio_errors++;
     }
 
@@ -605,8 +562,6 @@ static void blk_handle_requests(struct XenBlkDev *blkdev)
     }
 }
 
-/* ------------------------------------------------------------- */
-
 static void blk_bh(void *opaque)
 {
     struct XenBlkDev *blkdev = opaque;
@@ -634,346 +589,6 @@ static void blk_alloc(struct XenLegacyDevice *xendev)
     blkdev->bh = aio_bh_new(blkdev->ctx, blk_bh, blkdev);
 }
 
-static void blk_parse_discard(struct XenBlkDev *blkdev)
-{
-    struct XenLegacyDevice *xendev = &blkdev->xendev;
-    int enable;
-
-    blkdev->feature_discard = true;
-
-    if (xenstore_read_be_int(xendev, "discard-enable", &enable) == 0) {
-        blkdev->feature_discard = !!enable;
-    }
-
-    if (blkdev->feature_discard) {
-        xenstore_write_be_int(xendev, "feature-discard", 1);
-    }
-}
-
-static int blk_init(struct XenLegacyDevice *xendev)
-{
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
-    int info = 0;
-    char *directiosafe = NULL;
-
-    trace_xen_disk_init(xendev->name);
-
-    /* read xenstore entries */
-    if (blkdev->params == NULL) {
-        char *h = NULL;
-        blkdev->params = xenstore_read_be_str(xendev, "params");
-        if (blkdev->params != NULL) {
-            h = strchr(blkdev->params, ':');
-        }
-        if (h != NULL) {
-            blkdev->fileproto = blkdev->params;
-            blkdev->filename  = h + 1;
-            *h = 0;
-        } else {
-            blkdev->fileproto = "<unset>";
-            blkdev->filename  = blkdev->params;
-        }
-    }
-    if (!strcmp("aio", blkdev->fileproto)) {
-        blkdev->fileproto = "raw";
-    }
-    if (!strcmp("vhd", blkdev->fileproto)) {
-        blkdev->fileproto = "vpc";
-    }
-    if (blkdev->mode == NULL) {
-        blkdev->mode = xenstore_read_be_str(xendev, "mode");
-    }
-    if (blkdev->type == NULL) {
-        blkdev->type = xenstore_read_be_str(xendev, "type");
-    }
-    if (blkdev->dev == NULL) {
-        blkdev->dev = xenstore_read_be_str(xendev, "dev");
-    }
-    if (blkdev->devtype == NULL) {
-        blkdev->devtype = xenstore_read_be_str(xendev, "device-type");
-    }
-    directiosafe = xenstore_read_be_str(xendev, "direct-io-safe");
-    blkdev->directiosafe = (directiosafe && atoi(directiosafe));
-
-    /* do we have all we need? */
-    if (blkdev->params == NULL ||
-        blkdev->mode == NULL   ||
-        blkdev->type == NULL   ||
-        blkdev->dev == NULL) {
-        goto out_error;
-    }
-
-    /* read-only ? */
-    if (strcmp(blkdev->mode, "w")) {
-        info  |= VDISK_READONLY;
-    }
-
-    /* cdrom ? */
-    if (blkdev->devtype && !strcmp(blkdev->devtype, "cdrom")) {
-        info  |= VDISK_CDROM;
-    }
-
-    blkdev->file_blk  = BLOCK_SIZE;
-
-    /* fill info
-     * blk_connect supplies sector-size and sectors
-     */
-    xenstore_write_be_int(xendev, "feature-flush-cache", 1);
-    xenstore_write_be_int(xendev, "info", info);
-
-    xenstore_write_be_int(xendev, "max-ring-page-order",
-                          MAX_RING_PAGE_ORDER);
-
-    blk_parse_discard(blkdev);
-
-    g_free(directiosafe);
-    return 0;
-
-out_error:
-    g_free(blkdev->params);
-    blkdev->params = NULL;
-    g_free(blkdev->mode);
-    blkdev->mode = NULL;
-    g_free(blkdev->type);
-    blkdev->type = NULL;
-    g_free(blkdev->dev);
-    blkdev->dev = NULL;
-    g_free(blkdev->devtype);
-    blkdev->devtype = NULL;
-    g_free(directiosafe);
-    blkdev->directiosafe = false;
-    return -1;
-}
-
-static int blk_connect(struct XenLegacyDevice *xendev)
-{
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
-    int index, qflags;
-    bool readonly = true;
-    bool writethrough = true;
-    int order, ring_ref;
-    unsigned int ring_size, max_grants;
-    unsigned int i;
-
-    trace_xen_disk_connect(xendev->name);
-
-    /* read-only ? */
-    if (blkdev->directiosafe) {
-        qflags = BDRV_O_NOCACHE | BDRV_O_NATIVE_AIO;
-    } else {
-        qflags = 0;
-        writethrough = false;
-    }
-    if (strcmp(blkdev->mode, "w") == 0) {
-        qflags |= BDRV_O_RDWR;
-        readonly = false;
-    }
-    if (blkdev->feature_discard) {
-        qflags |= BDRV_O_UNMAP;
-    }
-
-    /* init qemu block driver */
-    index = (xendev->dev - 202 * 256) / 16;
-    blkdev->dinfo = drive_get(IF_XEN, 0, index);
-    if (!blkdev->dinfo) {
-        Error *local_err = NULL;
-        QDict *options = NULL;
-
-        if (strcmp(blkdev->fileproto, "<unset>")) {
-            options = qdict_new();
-            qdict_put_str(options, "driver", blkdev->fileproto);
-        }
-
-        /* setup via xenbus -> create new block driver instance */
-        xen_pv_printf(xendev, 2, "create new bdrv (xenbus setup)\n");
-        blkdev->blk = blk_new_open(blkdev->filename, NULL, options,
-                                   qflags, &local_err);
-        if (!blkdev->blk) {
-            xen_pv_printf(xendev, 0, "error: %s\n",
-                          error_get_pretty(local_err));
-            error_free(local_err);
-            return -1;
-        }
-        blk_set_enable_write_cache(blkdev->blk, !writethrough);
-    } else {
-        /* setup via qemu cmdline -> already setup for us */
-        xen_pv_printf(xendev, 2,
-                      "get configured bdrv (cmdline setup)\n");
-        blkdev->blk = blk_by_legacy_dinfo(blkdev->dinfo);
-        if (blk_is_read_only(blkdev->blk) && !readonly) {
-            xen_pv_printf(xendev, 0, "Unexpected read-only drive");
-            blkdev->blk = NULL;
-            return -1;
-        }
-        /* blkdev->blk is not create by us, we get a reference
-         * so we can blk_unref() unconditionally */
-        blk_ref(blkdev->blk);
-    }
-    blk_attach_dev_legacy(blkdev->blk, blkdev);
-    blkdev->file_size = blk_getlength(blkdev->blk);
-    if (blkdev->file_size < 0) {
-        BlockDriverState *bs = blk_bs(blkdev->blk);
-        const char *drv_name = bs ? bdrv_get_format_name(bs) : NULL;
-        xen_pv_printf(xendev, 1, "blk_getlength: %d (%s) | drv %s\n",
-                      (int)blkdev->file_size, strerror(-blkdev->file_size),
-                      drv_name ?: "-");
-        blkdev->file_size = 0;
-    }
-
-    xen_pv_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\","
-                  " size %" PRId64 " (%" PRId64 " MB)\n",
-                  blkdev->type, blkdev->fileproto, blkdev->filename,
-                  blkdev->file_size, blkdev->file_size / MiB);
-
-    /* Fill in number of sector size and number of sectors */
-    xenstore_write_be_int(xendev, "sector-size", blkdev->file_blk);
-    xenstore_write_be_int64(xendev, "sectors",
-                            blkdev->file_size / blkdev->file_blk);
-
-    if (xenstore_read_fe_int(xendev, "ring-page-order",
-                             &order) == -1) {
-        blkdev->nr_ring_ref = 1;
-
-        if (xenstore_read_fe_int(xendev, "ring-ref",
-                                 &ring_ref) == -1) {
-            return -1;
-        }
-        blkdev->ring_ref[0] = ring_ref;
-
-    } else if (order >= 0 && order <= MAX_RING_PAGE_ORDER) {
-        blkdev->nr_ring_ref = 1 << order;
-
-        for (i = 0; i < blkdev->nr_ring_ref; i++) {
-            char *key;
-
-            key = g_strdup_printf("ring-ref%u", i);
-            if (!key) {
-                return -1;
-            }
-
-            if (xenstore_read_fe_int(xendev, key,
-                                     &ring_ref) == -1) {
-                g_free(key);
-                return -1;
-            }
-            blkdev->ring_ref[i] = ring_ref;
-
-            g_free(key);
-        }
-    } else {
-        xen_pv_printf(xendev, 0, "invalid ring-page-order: %d\n",
-                      order);
-        return -1;
-    }
-
-    if (xenstore_read_fe_int(xendev, "event-channel",
-                             &xendev->remote_port) == -1) {
-        return -1;
-    }
-
-    if (!xendev->protocol) {
-        blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
-    } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_NATIVE) == 0) {
-        blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
-    } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_X86_32) == 0) {
-        blkdev->protocol = BLKIF_PROTOCOL_X86_32;
-    } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_X86_64) == 0) {
-        blkdev->protocol = BLKIF_PROTOCOL_X86_64;
-    } else {
-        blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
-    }
-
-    ring_size = XC_PAGE_SIZE * blkdev->nr_ring_ref;
-    switch (blkdev->protocol) {
-    case BLKIF_PROTOCOL_NATIVE:
-    {
-        blkdev->max_requests = __CONST_RING_SIZE(blkif, ring_size);
-        break;
-    }
-    case BLKIF_PROTOCOL_X86_32:
-    {
-        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_32, ring_size);
-        break;
-    }
-    case BLKIF_PROTOCOL_X86_64:
-    {
-        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_64, ring_size);
-        break;
-    }
-    default:
-        return -1;
-    }
-
-    /* Add on the number needed for the ring pages */
-    max_grants = blkdev->nr_ring_ref;
-
-    xen_be_set_max_grant_refs(xendev, max_grants);
-    blkdev->sring = xen_be_map_grant_refs(xendev, blkdev->ring_ref,
-                                          blkdev->nr_ring_ref,
-                                          PROT_READ | PROT_WRITE);
-    if (!blkdev->sring) {
-        return -1;
-    }
-
-    switch (blkdev->protocol) {
-    case BLKIF_PROTOCOL_NATIVE:
-    {
-        blkif_sring_t *sring_native = blkdev->sring;
-        BACK_RING_INIT(&blkdev->rings.native, sring_native, ring_size);
-        break;
-    }
-    case BLKIF_PROTOCOL_X86_32:
-    {
-        blkif_x86_32_sring_t *sring_x86_32 = blkdev->sring;
-
-        BACK_RING_INIT(&blkdev->rings.x86_32_part, sring_x86_32, ring_size);
-        break;
-    }
-    case BLKIF_PROTOCOL_X86_64:
-    {
-        blkif_x86_64_sring_t *sring_x86_64 = blkdev->sring;
-
-        BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64, ring_size);
-        break;
-    }
-    }
-
-    blk_set_aio_context(blkdev->blk, blkdev->ctx);
-
-    xen_be_bind_evtchn(xendev);
-
-    xen_pv_printf(xendev, 1, "ok: proto %s, nr-ring-ref %u, "
-                  "remote port %d, local port %d\n",
-                  xendev->protocol, blkdev->nr_ring_ref,
-                  xendev->remote_port, xendev->local_port);
-    return 0;
-}
-
-static void blk_disconnect(struct XenLegacyDevice *xendev)
-{
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
-
-    trace_xen_disk_disconnect(xendev->name);
-
-    aio_context_acquire(blkdev->ctx);
-
-    if (blkdev->blk) {
-        blk_set_aio_context(blkdev->blk, qemu_get_aio_context());
-        blk_detach_dev(blkdev->blk, blkdev);
-        blk_unref(blkdev->blk);
-        blkdev->blk = NULL;
-    }
-    xen_pv_unbind_evtchn(xendev);
-
-    aio_context_release(blkdev->ctx);
-
-    if (blkdev->sring) {
-        xen_be_unmap_grant_refs(xendev, blkdev->sring,
-                                blkdev->nr_ring_ref);
-        blkdev->sring = NULL;
-    }
-}
-
 static int blk_free(struct XenLegacyDevice *xendev)
 {
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
@@ -1006,14 +621,3 @@ static void blk_event(struct XenLegacyDevice *xendev)
 
     qemu_bh_schedule(blkdev->bh);
 }
-
-struct XenDevOps xen_blkdev_ops = {
-    .flags      = DEVOPS_FLAG_NEED_GNTDEV,
-    .size       = sizeof(struct XenBlkDev),
-    .alloc      = blk_alloc,
-    .init       = blk_init,
-    .initialise = blk_connect,
-    .disconnect = blk_disconnect,
-    .event      = blk_event,
-    .free       = blk_free,
-};
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [Qemu-devel] [PATCH 10/18] xen: add header and build dataplane/xen-qdisk.c
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
@ 2018-11-21 15:12   ` Paul Durrant
  2018-11-21 15:11 ` [Qemu-devel] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy Paul Durrant
                     ` (24 subsequent siblings)
  25 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Paul Durrant, Stefan Hajnoczi, Kevin Wolf, Max Reitz,
	Stefano Stabellini, Anthony Perard

This patch adds the transformations necessary to get dataplane/xen-qdisk.c
to build against the new XenBus/XenDevice framework. MAINTAINERS is also
updated due to the introduction of dataplane/xen-qdisk.h.

NOTE: Existing data structure names are retained for the moment. These will
      be modified by subsequent patches. A typedef for XenQdiskDataPlane
      has been added to the header (based on the old struct XenBlkDev name
      for the moment) so that the old names don't need to leak out of the
      dataplane code.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
---
 MAINTAINERS                      |   1 +
 hw/block/dataplane/Makefile.objs |   1 +
 hw/block/dataplane/xen-qdisk.c   | 317 +++++++++++++++++++++++++++------------
 hw/block/dataplane/xen-qdisk.h   |  25 +++
 4 files changed, 244 insertions(+), 100 deletions(-)
 create mode 100644 hw/block/dataplane/xen-qdisk.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 4bfbfc9985..5871f035c3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -394,6 +394,7 @@ F: hw/block/dataplane/xen*
 F: hw/xen/
 F: hw/xenpv/
 F: hw/i386/xen/
+F: include/hw/block/dataplane/xen*
 F: include/hw/xen/
 F: include/sysemu/xen-mapcache.h
 
diff --git a/hw/block/dataplane/Makefile.objs b/hw/block/dataplane/Makefile.objs
index e786f66421..1c107052d1 100644
--- a/hw/block/dataplane/Makefile.objs
+++ b/hw/block/dataplane/Makefile.objs
@@ -1 +1,2 @@
 obj-y += virtio-blk.o
+obj-$(CONFIG_XEN) += xen-qdisk.o
diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-qdisk.c
index 8e4368e7af..b075aa975d 100644
--- a/hw/block/dataplane/xen-qdisk.c
+++ b/hw/block/dataplane/xen-qdisk.c
@@ -5,65 +5,56 @@
  * Based on original code (c) Gerd Hoffmann <kraxel@redhat.com>
  */
 
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+#include "hw/hw.h"
+#include "hw/xen/xen.h"
+#include "hw/xen/xen_common.h"
+#include "hw/block/block.h"
+#include "hw/block/xen_blkif.h"
+#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
+#include "sysemu/iothread.h"
+#include "xen-qdisk.h"
+
 struct ioreq {
-    blkif_request_t     req;
-    int16_t             status;
-
-    /* parsed request */
-    off_t               start;
-    QEMUIOVector        v;
-    void                *buf;
-    size_t              size;
-    int                 presync;
-
-    /* aio status */
-    int                 aio_inflight;
-    int                 aio_errors;
-
-    struct XenBlkDev    *blkdev;
-    QLIST_ENTRY(ioreq)   list;
-    BlockAcctCookie     acct;
+    blkif_request_t req;
+    int16_t status;
+    off_t start;
+    QEMUIOVector v;
+    void *buf;
+    size_t size;
+    int presync;
+    int aio_inflight;
+    int aio_errors;
+    struct XenBlkDev *blkdev;
+    QLIST_ENTRY(ioreq) list;
+    BlockAcctCookie acct;
 };
 
-#define MAX_RING_PAGE_ORDER 4
-
 struct XenBlkDev {
-    struct XenLegacyDevice    xendev;  /* must be first */
-    char                *params;
-    char                *mode;
-    char                *type;
-    char                *dev;
-    char                *devtype;
-    bool                directiosafe;
-    const char          *fileproto;
-    const char          *filename;
-    unsigned int        ring_ref[1 << MAX_RING_PAGE_ORDER];
-    unsigned int        nr_ring_ref;
-    void                *sring;
-    int64_t             file_blk;
-    int64_t             file_size;
-    int                 protocol;
-    blkif_back_rings_t  rings;
-    int                 more_work;
-
-    /* request lists */
+    XenDevice *xendev;
+    XenEventChannel *event_channel;
+    unsigned int *ring_ref;
+    unsigned int nr_ring_ref;
+    void *sring;
+    int64_t file_blk;
+    int64_t file_size;
+    int protocol;
+    blkif_back_rings_t rings;
+    int more_work;
     QLIST_HEAD(inflight_head, ioreq) inflight;
     QLIST_HEAD(finished_head, ioreq) finished;
     QLIST_HEAD(freelist_head, ioreq) freelist;
-    int                 requests_total;
-    int                 requests_inflight;
-    int                 requests_finished;
-    unsigned int        max_requests;
-
-    gboolean            feature_discard;
-
-    /* qemu block driver */
-    DriveInfo           *dinfo;
-    BlockBackend        *blk;
-    QEMUBH              *bh;
-
-    IOThread            *iothread;
-    AioContext          *ctx;
+    int requests_total;
+    int requests_inflight;
+    int requests_finished;
+    unsigned int max_requests;
+    BlockBackend *blk;
+    QEMUBH *bh;
+    IOThread *iothread;
+    AioContext *ctx;
 };
 
 static void ioreq_reset(struct ioreq *ioreq)
@@ -142,7 +133,6 @@ static void ioreq_release(struct ioreq *ioreq, bool finish)
 static int ioreq_parse(struct ioreq *ioreq)
 {
     struct XenBlkDev *blkdev = ioreq->blkdev;
-    struct XenLegacyDevice *xendev = &blkdev->xendev;
     size_t len;
     int i;
 
@@ -164,7 +154,8 @@ static int ioreq_parse(struct ioreq *ioreq)
         goto err;
     };
 
-    if (ioreq->req.operation != BLKIF_OP_READ && blkdev->mode[0] != 'w') {
+    if (ioreq->req.operation != BLKIF_OP_READ &&
+        blk_is_read_only(blkdev->blk)) {
         error_report("error: write req for ro device");
         goto err;
     }
@@ -179,7 +170,7 @@ static int ioreq_parse(struct ioreq *ioreq)
             error_report("error: first > last sector");
             goto err;
         }
-        if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >= XC_PAGE_SIZE) {
+        if (ioreq->req.seg[i].last_sect * blkdev->file_blk >= XC_PAGE_SIZE) {
             error_report("error: page crossing");
             goto err;
         }
@@ -202,12 +193,13 @@ err:
 static int ioreq_grant_copy(struct ioreq *ioreq)
 {
     struct XenBlkDev *blkdev = ioreq->blkdev;
-    struct XenLegacyDevice *xendev = &blkdev->xendev;
-    XenGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
-    int i, count, rc;
+    XenDevice *xendev = blkdev->xendev;
+    XenDeviceGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+    int i, count;
     int64_t file_blk = blkdev->file_blk;
     bool to_domain = (ioreq->req.operation == BLKIF_OP_READ);
     void *virt = ioreq->buf;
+    Error *local_err = NULL;
 
     if (ioreq->req.nr_segments == 0) {
         return 0;
@@ -227,20 +219,24 @@ static int ioreq_grant_copy(struct ioreq *ioreq)
                 file_blk;
             segs[i].dest.virt = virt;
         }
-        segs[i].len = (ioreq->req.seg[i].last_sect
-                       - ioreq->req.seg[i].first_sect + 1) * file_blk;
+        segs[i].len = (ioreq->req.seg[i].last_sect -
+                       ioreq->req.seg[i].first_sect + 1) * file_blk;
         virt += segs[i].len;
     }
 
-    rc = xen_be_copy_grant_refs(xendev, to_domain, segs, count);
+    xen_device_copy_grant_refs(xendev, to_domain, segs, count, &local_err);
+
+    if (local_err) {
+        const char *msg = error_get_pretty(local_err);
+
+        error_report("failed to copy data: %s", msg);
+        error_free(local_err);
 
-    if (rc) {
-        error_report("failed to copy data %d", rc);
         ioreq->aio_errors++;
         return -1;
     }
 
-    return rc;
+    return 0;
 }
 
 static int ioreq_runio_qemu_aio(struct ioreq *ioreq);
@@ -249,7 +245,6 @@ static void qemu_aio_complete(void *opaque, int ret)
 {
     struct ioreq *ioreq = opaque;
     struct XenBlkDev *blkdev = ioreq->blkdev;
-    struct XenLegacyDevice *xendev = &blkdev->xendev;
 
     aio_context_acquire(blkdev->ctx);
 
@@ -327,13 +322,13 @@ static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_number,
 
     /* Wrap around, or overflowing byte limit? */
     if (sec_start + sec_count < sec_count ||
-        sec_start + sec_count > INT64_MAX >> BDRV_SECTOR_BITS) {
+        sec_start + sec_count > INT64_MAX / blkdev->file_blk) {
         return false;
     }
 
-    limit = BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS;
-    byte_offset = sec_start << BDRV_SECTOR_BITS;
-    byte_remaining = sec_count << BDRV_SECTOR_BITS;
+    limit = BDRV_REQUEST_MAX_SECTORS * blkdev->file_blk;
+    byte_offset = sec_start * blkdev->file_blk;
+    byte_remaining = sec_count * blkdev->file_blk;
 
     do {
         byte_chunk = byte_remaining > limit ? limit : byte_remaining;
@@ -415,10 +410,10 @@ err:
 
 static int blk_send_response_one(struct ioreq *ioreq)
 {
-    struct XenBlkDev  *blkdev = ioreq->blkdev;
-    int               send_notify   = 0;
-    int               have_requests = 0;
-    blkif_response_t  *resp;
+    struct XenBlkDev *blkdev = ioreq->blkdev;
+    int send_notify = 0;
+    int have_requests = 0;
+    blkif_response_t *resp;
 
     /* Place on the response ring for the relevant domain. */
     switch (blkdev->protocol) {
@@ -441,9 +436,9 @@ static int blk_send_response_one(struct ioreq *ioreq)
         return 0;
     }
 
-    resp->id        = ioreq->req.id;
+    resp->id = ioreq->req.id;
     resp->operation = ioreq->req.operation;
-    resp->status    = ioreq->status;
+    resp->status = ioreq->status;
 
     blkdev->rings.common.rsp_prod_pvt++;
 
@@ -477,7 +472,7 @@ static void blk_send_response_all(struct XenBlkDev *blkdev)
         ioreq_release(ioreq, true);
     }
     if (send_notify) {
-        xen_pv_send_notify(&blkdev->xendev);
+        xen_device_notify_event_channel(blkdev->xendev, blkdev->event_channel);
     }
 }
 
@@ -548,7 +543,8 @@ static void blk_handle_requests(struct XenBlkDev *blkdev)
             };
 
             if (blk_send_response_one(ioreq)) {
-                xen_pv_send_notify(&blkdev->xendev);
+                xen_device_notify_event_channel(blkdev->xendev,
+                                                blkdev->event_channel);
             }
             ioreq_release(ioreq, false);
             continue;
@@ -571,32 +567,47 @@ static void blk_bh(void *opaque)
     aio_context_release(blkdev->ctx);
 }
 
-static void blk_alloc(struct XenLegacyDevice *xendev)
+static void blk_event(void *opaque)
 {
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
-    Error *err = NULL;
+    struct XenBlkDev *blkdev = opaque;
 
-    trace_xen_disk_alloc(xendev->name);
+    qemu_bh_schedule(blkdev->bh);
+}
+
+struct XenBlkDev *xen_qdisk_dataplane_create(XenDevice *xendev,
+                                             BlockConf *conf,
+                                             IOThread *iothread)
+{
+    struct XenBlkDev *blkdev = g_new0(struct XenBlkDev, 1);
+
+    blkdev->xendev = xendev;
+    blkdev->file_blk = conf->logical_block_size;
+    blkdev->blk = conf->blk;
+    blkdev->file_size = blk_getlength(blkdev->blk);
 
     QLIST_INIT(&blkdev->inflight);
     QLIST_INIT(&blkdev->finished);
     QLIST_INIT(&blkdev->freelist);
 
-    blkdev->iothread = iothread_create(xendev->name, &err);
-    assert(!err);
-
-    blkdev->ctx = iothread_get_aio_context(blkdev->iothread);
+    if (iothread) {
+        blkdev->iothread = iothread;
+        object_ref(OBJECT(blkdev->iothread));
+        blkdev->ctx = iothread_get_aio_context(blkdev->iothread);
+    } else {
+        blkdev->ctx = qemu_get_aio_context();
+    }
     blkdev->bh = aio_bh_new(blkdev->ctx, blk_bh, blkdev);
+
+    return blkdev;
 }
 
-static int blk_free(struct XenLegacyDevice *xendev)
+void xen_qdisk_dataplane_destroy(struct XenBlkDev *blkdev)
 {
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
     struct ioreq *ioreq;
 
-    trace_xen_disk_free(xendev->name);
-
-    blk_disconnect(xendev);
+    if (!blkdev) {
+        return;
+    }
 
     while (!QLIST_EMPTY(&blkdev->freelist)) {
         ioreq = QLIST_FIRST(&blkdev->freelist);
@@ -605,19 +616,125 @@ static int blk_free(struct XenLegacyDevice *xendev)
         g_free(ioreq);
     }
 
-    g_free(blkdev->params);
-    g_free(blkdev->mode);
-    g_free(blkdev->type);
-    g_free(blkdev->dev);
-    g_free(blkdev->devtype);
     qemu_bh_delete(blkdev->bh);
-    iothread_destroy(blkdev->iothread);
-    return 0;
+    if (blkdev->iothread) {
+        object_unref(OBJECT(blkdev->iothread));
+    }
+
+    g_free(blkdev);
 }
 
-static void blk_event(struct XenLegacyDevice *xendev)
+void xen_qdisk_dataplane_start(struct XenBlkDev *blkdev,
+                               const unsigned int ring_ref[],
+                               unsigned int nr_ring_ref,
+                               unsigned int event_channel,
+                               unsigned int protocol)
 {
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
+    XenDevice *xendev = blkdev->xendev;
+    unsigned int ring_size;
+    unsigned int i;
 
-    qemu_bh_schedule(blkdev->bh);
+    blkdev->nr_ring_ref = nr_ring_ref;
+    blkdev->ring_ref = g_new(unsigned int, nr_ring_ref);
+
+    for (i = 0; i < nr_ring_ref; i++) {
+        blkdev->ring_ref[i] = ring_ref[i];
+    }
+
+    blkdev->protocol = protocol;
+
+    ring_size = XC_PAGE_SIZE * blkdev->nr_ring_ref;
+    switch (blkdev->protocol) {
+    case BLKIF_PROTOCOL_NATIVE:
+    {
+        blkdev->max_requests = __CONST_RING_SIZE(blkif, ring_size);
+        break;
+    }
+    case BLKIF_PROTOCOL_X86_32:
+    {
+        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_32, ring_size);
+        break;
+    }
+    case BLKIF_PROTOCOL_X86_64:
+    {
+        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_64, ring_size);
+        break;
+    }
+    default:
+        assert(false);
+        break;
+    }
+
+    xen_device_set_max_grant_refs(xendev, blkdev->nr_ring_ref,
+                                  &error_fatal);
+
+    blkdev->sring = xen_device_map_grant_refs(xendev,
+                                              blkdev->ring_ref,
+                                              blkdev->nr_ring_ref,
+                                              PROT_READ | PROT_WRITE,
+                                              &error_fatal);
+
+    switch (blkdev->protocol) {
+    case BLKIF_PROTOCOL_NATIVE:
+    {
+        blkif_sring_t *sring_native = blkdev->sring;
+
+        BACK_RING_INIT(&blkdev->rings.native, sring_native, ring_size);
+        break;
+    }
+    case BLKIF_PROTOCOL_X86_32:
+    {
+        blkif_x86_32_sring_t *sring_x86_32 = blkdev->sring;
+
+        BACK_RING_INIT(&blkdev->rings.x86_32_part, sring_x86_32,
+                       ring_size);
+        break;
+    }
+    case BLKIF_PROTOCOL_X86_64:
+    {
+        blkif_x86_64_sring_t *sring_x86_64 = blkdev->sring;
+
+        BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64,
+                       ring_size);
+        break;
+    }
+    }
+
+    blkdev->event_channel =
+        xen_device_bind_event_channel(xendev, event_channel,
+                                      blk_event, blkdev,
+                                      &error_fatal);
+
+    aio_context_acquire(blkdev->ctx);
+    blk_set_aio_context(blkdev->blk, blkdev->ctx);
+    aio_context_release(blkdev->ctx);
+}
+
+void xen_qdisk_dataplane_stop(struct XenBlkDev *blkdev)
+{
+    XenDevice *xendev;
+
+    if (!blkdev) {
+        return;
+    }
+
+    aio_context_acquire(blkdev->ctx);
+    blk_set_aio_context(blkdev->blk, qemu_get_aio_context());
+    aio_context_release(blkdev->ctx);
+
+    xendev = blkdev->xendev;
+
+    if (blkdev->event_channel) {
+        xen_device_unbind_event_channel(xendev, blkdev->event_channel);
+        blkdev->event_channel = NULL;
+    }
+
+    if (blkdev->sring) {
+        xen_device_unmap_grant_refs(xendev, blkdev->sring,
+                                    blkdev->nr_ring_ref, &error_fatal);
+        blkdev->sring = NULL;
+    }
+
+    g_free(blkdev->ring_ref);
+    blkdev->ring_ref = NULL;
 }
diff --git a/hw/block/dataplane/xen-qdisk.h b/hw/block/dataplane/xen-qdisk.h
new file mode 100644
index 0000000000..16bcd500bf
--- /dev/null
+++ b/hw/block/dataplane/xen-qdisk.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ */
+
+#ifndef HW_BLOCK_DATAPLANE_QDISK_H
+#define HW_BLOCK_DATAPLANE_QDISK_H
+
+#include "hw/xen/xen-bus.h"
+#include "sysemu/iothread.h"
+
+typedef struct XenBlkDev XenQdiskDataPlane;
+
+XenQdiskDataPlane *xen_qdisk_dataplane_create(XenDevice *xendev,
+                                              BlockConf *conf,
+                                              IOThread *iothread);
+void xen_qdisk_dataplane_destroy(XenQdiskDataPlane *dataplane);
+void xen_qdisk_dataplane_start(XenQdiskDataPlane *dataplane,
+                               const unsigned int ring_ref[],
+                               unsigned int nr_ring_ref,
+                               unsigned int event_channel,
+                               unsigned int protocol);
+void xen_qdisk_dataplane_stop(XenQdiskDataPlane *dataplane);
+
+#endif /* HW_BLOCK_DATAPLANE_QDISK_H */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [PATCH 10/18] xen: add header and build dataplane/xen-qdisk.c
@ 2018-11-21 15:12   ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Kevin Wolf, Stefano Stabellini, Max Reitz, Paul Durrant,
	Stefan Hajnoczi, Anthony Perard

This patch adds the transformations necessary to get dataplane/xen-qdisk.c
to build against the new XenBus/XenDevice framework. MAINTAINERS is also
updated due to the introduction of dataplane/xen-qdisk.h.

NOTE: Existing data structure names are retained for the moment. These will
      be modified by subsequent patches. A typedef for XenQdiskDataPlane
      has been added to the header (based on the old struct XenBlkDev name
      for the moment) so that the old names don't need to leak out of the
      dataplane code.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
---
 MAINTAINERS                      |   1 +
 hw/block/dataplane/Makefile.objs |   1 +
 hw/block/dataplane/xen-qdisk.c   | 317 +++++++++++++++++++++++++++------------
 hw/block/dataplane/xen-qdisk.h   |  25 +++
 4 files changed, 244 insertions(+), 100 deletions(-)
 create mode 100644 hw/block/dataplane/xen-qdisk.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 4bfbfc9985..5871f035c3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -394,6 +394,7 @@ F: hw/block/dataplane/xen*
 F: hw/xen/
 F: hw/xenpv/
 F: hw/i386/xen/
+F: include/hw/block/dataplane/xen*
 F: include/hw/xen/
 F: include/sysemu/xen-mapcache.h
 
diff --git a/hw/block/dataplane/Makefile.objs b/hw/block/dataplane/Makefile.objs
index e786f66421..1c107052d1 100644
--- a/hw/block/dataplane/Makefile.objs
+++ b/hw/block/dataplane/Makefile.objs
@@ -1 +1,2 @@
 obj-y += virtio-blk.o
+obj-$(CONFIG_XEN) += xen-qdisk.o
diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-qdisk.c
index 8e4368e7af..b075aa975d 100644
--- a/hw/block/dataplane/xen-qdisk.c
+++ b/hw/block/dataplane/xen-qdisk.c
@@ -5,65 +5,56 @@
  * Based on original code (c) Gerd Hoffmann <kraxel@redhat.com>
  */
 
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+#include "hw/hw.h"
+#include "hw/xen/xen.h"
+#include "hw/xen/xen_common.h"
+#include "hw/block/block.h"
+#include "hw/block/xen_blkif.h"
+#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
+#include "sysemu/iothread.h"
+#include "xen-qdisk.h"
+
 struct ioreq {
-    blkif_request_t     req;
-    int16_t             status;
-
-    /* parsed request */
-    off_t               start;
-    QEMUIOVector        v;
-    void                *buf;
-    size_t              size;
-    int                 presync;
-
-    /* aio status */
-    int                 aio_inflight;
-    int                 aio_errors;
-
-    struct XenBlkDev    *blkdev;
-    QLIST_ENTRY(ioreq)   list;
-    BlockAcctCookie     acct;
+    blkif_request_t req;
+    int16_t status;
+    off_t start;
+    QEMUIOVector v;
+    void *buf;
+    size_t size;
+    int presync;
+    int aio_inflight;
+    int aio_errors;
+    struct XenBlkDev *blkdev;
+    QLIST_ENTRY(ioreq) list;
+    BlockAcctCookie acct;
 };
 
-#define MAX_RING_PAGE_ORDER 4
-
 struct XenBlkDev {
-    struct XenLegacyDevice    xendev;  /* must be first */
-    char                *params;
-    char                *mode;
-    char                *type;
-    char                *dev;
-    char                *devtype;
-    bool                directiosafe;
-    const char          *fileproto;
-    const char          *filename;
-    unsigned int        ring_ref[1 << MAX_RING_PAGE_ORDER];
-    unsigned int        nr_ring_ref;
-    void                *sring;
-    int64_t             file_blk;
-    int64_t             file_size;
-    int                 protocol;
-    blkif_back_rings_t  rings;
-    int                 more_work;
-
-    /* request lists */
+    XenDevice *xendev;
+    XenEventChannel *event_channel;
+    unsigned int *ring_ref;
+    unsigned int nr_ring_ref;
+    void *sring;
+    int64_t file_blk;
+    int64_t file_size;
+    int protocol;
+    blkif_back_rings_t rings;
+    int more_work;
     QLIST_HEAD(inflight_head, ioreq) inflight;
     QLIST_HEAD(finished_head, ioreq) finished;
     QLIST_HEAD(freelist_head, ioreq) freelist;
-    int                 requests_total;
-    int                 requests_inflight;
-    int                 requests_finished;
-    unsigned int        max_requests;
-
-    gboolean            feature_discard;
-
-    /* qemu block driver */
-    DriveInfo           *dinfo;
-    BlockBackend        *blk;
-    QEMUBH              *bh;
-
-    IOThread            *iothread;
-    AioContext          *ctx;
+    int requests_total;
+    int requests_inflight;
+    int requests_finished;
+    unsigned int max_requests;
+    BlockBackend *blk;
+    QEMUBH *bh;
+    IOThread *iothread;
+    AioContext *ctx;
 };
 
 static void ioreq_reset(struct ioreq *ioreq)
@@ -142,7 +133,6 @@ static void ioreq_release(struct ioreq *ioreq, bool finish)
 static int ioreq_parse(struct ioreq *ioreq)
 {
     struct XenBlkDev *blkdev = ioreq->blkdev;
-    struct XenLegacyDevice *xendev = &blkdev->xendev;
     size_t len;
     int i;
 
@@ -164,7 +154,8 @@ static int ioreq_parse(struct ioreq *ioreq)
         goto err;
     };
 
-    if (ioreq->req.operation != BLKIF_OP_READ && blkdev->mode[0] != 'w') {
+    if (ioreq->req.operation != BLKIF_OP_READ &&
+        blk_is_read_only(blkdev->blk)) {
         error_report("error: write req for ro device");
         goto err;
     }
@@ -179,7 +170,7 @@ static int ioreq_parse(struct ioreq *ioreq)
             error_report("error: first > last sector");
             goto err;
         }
-        if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >= XC_PAGE_SIZE) {
+        if (ioreq->req.seg[i].last_sect * blkdev->file_blk >= XC_PAGE_SIZE) {
             error_report("error: page crossing");
             goto err;
         }
@@ -202,12 +193,13 @@ err:
 static int ioreq_grant_copy(struct ioreq *ioreq)
 {
     struct XenBlkDev *blkdev = ioreq->blkdev;
-    struct XenLegacyDevice *xendev = &blkdev->xendev;
-    XenGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
-    int i, count, rc;
+    XenDevice *xendev = blkdev->xendev;
+    XenDeviceGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+    int i, count;
     int64_t file_blk = blkdev->file_blk;
     bool to_domain = (ioreq->req.operation == BLKIF_OP_READ);
     void *virt = ioreq->buf;
+    Error *local_err = NULL;
 
     if (ioreq->req.nr_segments == 0) {
         return 0;
@@ -227,20 +219,24 @@ static int ioreq_grant_copy(struct ioreq *ioreq)
                 file_blk;
             segs[i].dest.virt = virt;
         }
-        segs[i].len = (ioreq->req.seg[i].last_sect
-                       - ioreq->req.seg[i].first_sect + 1) * file_blk;
+        segs[i].len = (ioreq->req.seg[i].last_sect -
+                       ioreq->req.seg[i].first_sect + 1) * file_blk;
         virt += segs[i].len;
     }
 
-    rc = xen_be_copy_grant_refs(xendev, to_domain, segs, count);
+    xen_device_copy_grant_refs(xendev, to_domain, segs, count, &local_err);
+
+    if (local_err) {
+        const char *msg = error_get_pretty(local_err);
+
+        error_report("failed to copy data: %s", msg);
+        error_free(local_err);
 
-    if (rc) {
-        error_report("failed to copy data %d", rc);
         ioreq->aio_errors++;
         return -1;
     }
 
-    return rc;
+    return 0;
 }
 
 static int ioreq_runio_qemu_aio(struct ioreq *ioreq);
@@ -249,7 +245,6 @@ static void qemu_aio_complete(void *opaque, int ret)
 {
     struct ioreq *ioreq = opaque;
     struct XenBlkDev *blkdev = ioreq->blkdev;
-    struct XenLegacyDevice *xendev = &blkdev->xendev;
 
     aio_context_acquire(blkdev->ctx);
 
@@ -327,13 +322,13 @@ static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_number,
 
     /* Wrap around, or overflowing byte limit? */
     if (sec_start + sec_count < sec_count ||
-        sec_start + sec_count > INT64_MAX >> BDRV_SECTOR_BITS) {
+        sec_start + sec_count > INT64_MAX / blkdev->file_blk) {
         return false;
     }
 
-    limit = BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS;
-    byte_offset = sec_start << BDRV_SECTOR_BITS;
-    byte_remaining = sec_count << BDRV_SECTOR_BITS;
+    limit = BDRV_REQUEST_MAX_SECTORS * blkdev->file_blk;
+    byte_offset = sec_start * blkdev->file_blk;
+    byte_remaining = sec_count * blkdev->file_blk;
 
     do {
         byte_chunk = byte_remaining > limit ? limit : byte_remaining;
@@ -415,10 +410,10 @@ err:
 
 static int blk_send_response_one(struct ioreq *ioreq)
 {
-    struct XenBlkDev  *blkdev = ioreq->blkdev;
-    int               send_notify   = 0;
-    int               have_requests = 0;
-    blkif_response_t  *resp;
+    struct XenBlkDev *blkdev = ioreq->blkdev;
+    int send_notify = 0;
+    int have_requests = 0;
+    blkif_response_t *resp;
 
     /* Place on the response ring for the relevant domain. */
     switch (blkdev->protocol) {
@@ -441,9 +436,9 @@ static int blk_send_response_one(struct ioreq *ioreq)
         return 0;
     }
 
-    resp->id        = ioreq->req.id;
+    resp->id = ioreq->req.id;
     resp->operation = ioreq->req.operation;
-    resp->status    = ioreq->status;
+    resp->status = ioreq->status;
 
     blkdev->rings.common.rsp_prod_pvt++;
 
@@ -477,7 +472,7 @@ static void blk_send_response_all(struct XenBlkDev *blkdev)
         ioreq_release(ioreq, true);
     }
     if (send_notify) {
-        xen_pv_send_notify(&blkdev->xendev);
+        xen_device_notify_event_channel(blkdev->xendev, blkdev->event_channel);
     }
 }
 
@@ -548,7 +543,8 @@ static void blk_handle_requests(struct XenBlkDev *blkdev)
             };
 
             if (blk_send_response_one(ioreq)) {
-                xen_pv_send_notify(&blkdev->xendev);
+                xen_device_notify_event_channel(blkdev->xendev,
+                                                blkdev->event_channel);
             }
             ioreq_release(ioreq, false);
             continue;
@@ -571,32 +567,47 @@ static void blk_bh(void *opaque)
     aio_context_release(blkdev->ctx);
 }
 
-static void blk_alloc(struct XenLegacyDevice *xendev)
+static void blk_event(void *opaque)
 {
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
-    Error *err = NULL;
+    struct XenBlkDev *blkdev = opaque;
 
-    trace_xen_disk_alloc(xendev->name);
+    qemu_bh_schedule(blkdev->bh);
+}
+
+struct XenBlkDev *xen_qdisk_dataplane_create(XenDevice *xendev,
+                                             BlockConf *conf,
+                                             IOThread *iothread)
+{
+    struct XenBlkDev *blkdev = g_new0(struct XenBlkDev, 1);
+
+    blkdev->xendev = xendev;
+    blkdev->file_blk = conf->logical_block_size;
+    blkdev->blk = conf->blk;
+    blkdev->file_size = blk_getlength(blkdev->blk);
 
     QLIST_INIT(&blkdev->inflight);
     QLIST_INIT(&blkdev->finished);
     QLIST_INIT(&blkdev->freelist);
 
-    blkdev->iothread = iothread_create(xendev->name, &err);
-    assert(!err);
-
-    blkdev->ctx = iothread_get_aio_context(blkdev->iothread);
+    if (iothread) {
+        blkdev->iothread = iothread;
+        object_ref(OBJECT(blkdev->iothread));
+        blkdev->ctx = iothread_get_aio_context(blkdev->iothread);
+    } else {
+        blkdev->ctx = qemu_get_aio_context();
+    }
     blkdev->bh = aio_bh_new(blkdev->ctx, blk_bh, blkdev);
+
+    return blkdev;
 }
 
-static int blk_free(struct XenLegacyDevice *xendev)
+void xen_qdisk_dataplane_destroy(struct XenBlkDev *blkdev)
 {
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
     struct ioreq *ioreq;
 
-    trace_xen_disk_free(xendev->name);
-
-    blk_disconnect(xendev);
+    if (!blkdev) {
+        return;
+    }
 
     while (!QLIST_EMPTY(&blkdev->freelist)) {
         ioreq = QLIST_FIRST(&blkdev->freelist);
@@ -605,19 +616,125 @@ static int blk_free(struct XenLegacyDevice *xendev)
         g_free(ioreq);
     }
 
-    g_free(blkdev->params);
-    g_free(blkdev->mode);
-    g_free(blkdev->type);
-    g_free(blkdev->dev);
-    g_free(blkdev->devtype);
     qemu_bh_delete(blkdev->bh);
-    iothread_destroy(blkdev->iothread);
-    return 0;
+    if (blkdev->iothread) {
+        object_unref(OBJECT(blkdev->iothread));
+    }
+
+    g_free(blkdev);
 }
 
-static void blk_event(struct XenLegacyDevice *xendev)
+void xen_qdisk_dataplane_start(struct XenBlkDev *blkdev,
+                               const unsigned int ring_ref[],
+                               unsigned int nr_ring_ref,
+                               unsigned int event_channel,
+                               unsigned int protocol)
 {
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
+    XenDevice *xendev = blkdev->xendev;
+    unsigned int ring_size;
+    unsigned int i;
 
-    qemu_bh_schedule(blkdev->bh);
+    blkdev->nr_ring_ref = nr_ring_ref;
+    blkdev->ring_ref = g_new(unsigned int, nr_ring_ref);
+
+    for (i = 0; i < nr_ring_ref; i++) {
+        blkdev->ring_ref[i] = ring_ref[i];
+    }
+
+    blkdev->protocol = protocol;
+
+    ring_size = XC_PAGE_SIZE * blkdev->nr_ring_ref;
+    switch (blkdev->protocol) {
+    case BLKIF_PROTOCOL_NATIVE:
+    {
+        blkdev->max_requests = __CONST_RING_SIZE(blkif, ring_size);
+        break;
+    }
+    case BLKIF_PROTOCOL_X86_32:
+    {
+        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_32, ring_size);
+        break;
+    }
+    case BLKIF_PROTOCOL_X86_64:
+    {
+        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_64, ring_size);
+        break;
+    }
+    default:
+        assert(false);
+        break;
+    }
+
+    xen_device_set_max_grant_refs(xendev, blkdev->nr_ring_ref,
+                                  &error_fatal);
+
+    blkdev->sring = xen_device_map_grant_refs(xendev,
+                                              blkdev->ring_ref,
+                                              blkdev->nr_ring_ref,
+                                              PROT_READ | PROT_WRITE,
+                                              &error_fatal);
+
+    switch (blkdev->protocol) {
+    case BLKIF_PROTOCOL_NATIVE:
+    {
+        blkif_sring_t *sring_native = blkdev->sring;
+
+        BACK_RING_INIT(&blkdev->rings.native, sring_native, ring_size);
+        break;
+    }
+    case BLKIF_PROTOCOL_X86_32:
+    {
+        blkif_x86_32_sring_t *sring_x86_32 = blkdev->sring;
+
+        BACK_RING_INIT(&blkdev->rings.x86_32_part, sring_x86_32,
+                       ring_size);
+        break;
+    }
+    case BLKIF_PROTOCOL_X86_64:
+    {
+        blkif_x86_64_sring_t *sring_x86_64 = blkdev->sring;
+
+        BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64,
+                       ring_size);
+        break;
+    }
+    }
+
+    blkdev->event_channel =
+        xen_device_bind_event_channel(xendev, event_channel,
+                                      blk_event, blkdev,
+                                      &error_fatal);
+
+    aio_context_acquire(blkdev->ctx);
+    blk_set_aio_context(blkdev->blk, blkdev->ctx);
+    aio_context_release(blkdev->ctx);
+}
+
+void xen_qdisk_dataplane_stop(struct XenBlkDev *blkdev)
+{
+    XenDevice *xendev;
+
+    if (!blkdev) {
+        return;
+    }
+
+    aio_context_acquire(blkdev->ctx);
+    blk_set_aio_context(blkdev->blk, qemu_get_aio_context());
+    aio_context_release(blkdev->ctx);
+
+    xendev = blkdev->xendev;
+
+    if (blkdev->event_channel) {
+        xen_device_unbind_event_channel(xendev, blkdev->event_channel);
+        blkdev->event_channel = NULL;
+    }
+
+    if (blkdev->sring) {
+        xen_device_unmap_grant_refs(xendev, blkdev->sring,
+                                    blkdev->nr_ring_ref, &error_fatal);
+        blkdev->sring = NULL;
+    }
+
+    g_free(blkdev->ring_ref);
+    blkdev->ring_ref = NULL;
 }
diff --git a/hw/block/dataplane/xen-qdisk.h b/hw/block/dataplane/xen-qdisk.h
new file mode 100644
index 0000000000..16bcd500bf
--- /dev/null
+++ b/hw/block/dataplane/xen-qdisk.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ */
+
+#ifndef HW_BLOCK_DATAPLANE_QDISK_H
+#define HW_BLOCK_DATAPLANE_QDISK_H
+
+#include "hw/xen/xen-bus.h"
+#include "sysemu/iothread.h"
+
+typedef struct XenBlkDev XenQdiskDataPlane;
+
+XenQdiskDataPlane *xen_qdisk_dataplane_create(XenDevice *xendev,
+                                              BlockConf *conf,
+                                              IOThread *iothread);
+void xen_qdisk_dataplane_destroy(XenQdiskDataPlane *dataplane);
+void xen_qdisk_dataplane_start(XenQdiskDataPlane *dataplane,
+                               const unsigned int ring_ref[],
+                               unsigned int nr_ring_ref,
+                               unsigned int event_channel,
+                               unsigned int protocol);
+void xen_qdisk_dataplane_stop(XenQdiskDataPlane *dataplane);
+
+#endif /* HW_BLOCK_DATAPLANE_QDISK_H */
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [Qemu-devel] [PATCH 11/18] xen: remove 'XenBlkDev' and 'blkdev' names from dataplane/xen-qdisk
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
                   ` (15 preceding siblings ...)
  2018-11-21 15:12 ` [PATCH 11/18] xen: remove 'XenBlkDev' and 'blkdev' names from dataplane/xen-qdisk Paul Durrant
@ 2018-11-21 15:12 ` Paul Durrant
  2018-12-04 11:05   ` Anthony PERARD
  2018-12-04 11:05   ` [Qemu-devel] " Anthony PERARD
  2018-11-21 15:12   ` Paul Durrant
                   ` (8 subsequent siblings)
  25 siblings, 2 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Paul Durrant, Stefano Stabellini, Anthony Perard,
	Stefan Hajnoczi, Kevin Wolf, Max Reitz

This is a purely cosmetic patch that substitutes the old 'struct XenBlkDev'
name with 'XenQdiskDataPlane' and 'blkdev' field/variable names with
'dataplane', and then does necessary fix-up to adhere to coding style.

No functional change.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
---
 hw/block/dataplane/xen-qdisk.c | 342 +++++++++++++++++++++--------------------
 hw/block/dataplane/xen-qdisk.h |   2 +-
 2 files changed, 179 insertions(+), 165 deletions(-)

diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-qdisk.c
index b075aa975d..2214455ff9 100644
--- a/hw/block/dataplane/xen-qdisk.c
+++ b/hw/block/dataplane/xen-qdisk.c
@@ -28,12 +28,12 @@ struct ioreq {
     int presync;
     int aio_inflight;
     int aio_errors;
-    struct XenBlkDev *blkdev;
+    XenQdiskDataPlane *dataplane;
     QLIST_ENTRY(ioreq) list;
     BlockAcctCookie acct;
 };
 
-struct XenBlkDev {
+struct XenQdiskDataPlane {
     XenDevice *xendev;
     XenEventChannel *event_channel;
     unsigned int *ring_ref;
@@ -69,33 +69,33 @@ static void ioreq_reset(struct ioreq *ioreq)
     ioreq->aio_inflight = 0;
     ioreq->aio_errors = 0;
 
-    ioreq->blkdev = NULL;
+    ioreq->dataplane = NULL;
     memset(&ioreq->list, 0, sizeof(ioreq->list));
     memset(&ioreq->acct, 0, sizeof(ioreq->acct));
 
     qemu_iovec_reset(&ioreq->v);
 }
 
-static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
+static struct ioreq *ioreq_start(XenQdiskDataPlane *dataplane)
 {
     struct ioreq *ioreq = NULL;
 
-    if (QLIST_EMPTY(&blkdev->freelist)) {
-        if (blkdev->requests_total >= blkdev->max_requests) {
+    if (QLIST_EMPTY(&dataplane->freelist)) {
+        if (dataplane->requests_total >= dataplane->max_requests) {
             goto out;
         }
         /* allocate new struct */
         ioreq = g_malloc0(sizeof(*ioreq));
-        ioreq->blkdev = blkdev;
-        blkdev->requests_total++;
+        ioreq->dataplane = dataplane;
+        dataplane->requests_total++;
         qemu_iovec_init(&ioreq->v, 1);
     } else {
         /* get one from freelist */
-        ioreq = QLIST_FIRST(&blkdev->freelist);
+        ioreq = QLIST_FIRST(&dataplane->freelist);
         QLIST_REMOVE(ioreq, list);
     }
-    QLIST_INSERT_HEAD(&blkdev->inflight, ioreq, list);
-    blkdev->requests_inflight++;
+    QLIST_INSERT_HEAD(&dataplane->inflight, ioreq, list);
+    dataplane->requests_inflight++;
 
 out:
     return ioreq;
@@ -103,26 +103,26 @@ out:
 
 static void ioreq_finish(struct ioreq *ioreq)
 {
-    struct XenBlkDev *blkdev = ioreq->blkdev;
+    XenQdiskDataPlane *dataplane = ioreq->dataplane;
 
     QLIST_REMOVE(ioreq, list);
-    QLIST_INSERT_HEAD(&blkdev->finished, ioreq, list);
-    blkdev->requests_inflight--;
-    blkdev->requests_finished++;
+    QLIST_INSERT_HEAD(&dataplane->finished, ioreq, list);
+    dataplane->requests_inflight--;
+    dataplane->requests_finished++;
 }
 
 static void ioreq_release(struct ioreq *ioreq, bool finish)
 {
-    struct XenBlkDev *blkdev = ioreq->blkdev;
+    XenQdiskDataPlane *dataplane = ioreq->dataplane;
 
     QLIST_REMOVE(ioreq, list);
     ioreq_reset(ioreq);
-    ioreq->blkdev = blkdev;
-    QLIST_INSERT_HEAD(&blkdev->freelist, ioreq, list);
+    ioreq->dataplane = dataplane;
+    QLIST_INSERT_HEAD(&dataplane->freelist, ioreq, list);
     if (finish) {
-        blkdev->requests_finished--;
+        dataplane->requests_finished--;
     } else {
-        blkdev->requests_inflight--;
+        dataplane->requests_inflight--;
     }
 }
 
@@ -132,7 +132,7 @@ static void ioreq_release(struct ioreq *ioreq, bool finish)
  */
 static int ioreq_parse(struct ioreq *ioreq)
 {
-    struct XenBlkDev *blkdev = ioreq->blkdev;
+    XenQdiskDataPlane *dataplane = ioreq->dataplane;
     size_t len;
     int i;
 
@@ -155,12 +155,12 @@ static int ioreq_parse(struct ioreq *ioreq)
     };
 
     if (ioreq->req.operation != BLKIF_OP_READ &&
-        blk_is_read_only(blkdev->blk)) {
+        blk_is_read_only(dataplane->blk)) {
         error_report("error: write req for ro device");
         goto err;
     }
 
-    ioreq->start = ioreq->req.sector_number * blkdev->file_blk;
+    ioreq->start = ioreq->req.sector_number * dataplane->file_blk;
     for (i = 0; i < ioreq->req.nr_segments; i++) {
         if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
             error_report("error: nr_segments too big");
@@ -170,16 +170,16 @@ static int ioreq_parse(struct ioreq *ioreq)
             error_report("error: first > last sector");
             goto err;
         }
-        if (ioreq->req.seg[i].last_sect * blkdev->file_blk >= XC_PAGE_SIZE) {
+        if (ioreq->req.seg[i].last_sect * dataplane->file_blk >= XC_PAGE_SIZE) {
             error_report("error: page crossing");
             goto err;
         }
 
         len = (ioreq->req.seg[i].last_sect -
-               ioreq->req.seg[i].first_sect + 1) * blkdev->file_blk;
+               ioreq->req.seg[i].first_sect + 1) * dataplane->file_blk;
         ioreq->size += len;
     }
-    if (ioreq->start + ioreq->size > blkdev->file_size) {
+    if (ioreq->start + ioreq->size > dataplane->file_size) {
         error_report("error: access beyond end of file");
         goto err;
     }
@@ -192,11 +192,11 @@ err:
 
 static int ioreq_grant_copy(struct ioreq *ioreq)
 {
-    struct XenBlkDev *blkdev = ioreq->blkdev;
-    XenDevice *xendev = blkdev->xendev;
+    XenQdiskDataPlane *dataplane = ioreq->dataplane;
+    XenDevice *xendev = dataplane->xendev;
     XenDeviceGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
     int i, count;
-    int64_t file_blk = blkdev->file_blk;
+    int64_t file_blk = dataplane->file_blk;
     bool to_domain = (ioreq->req.operation == BLKIF_OP_READ);
     void *virt = ioreq->buf;
     Error *local_err = NULL;
@@ -244,9 +244,9 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq);
 static void qemu_aio_complete(void *opaque, int ret)
 {
     struct ioreq *ioreq = opaque;
-    struct XenBlkDev *blkdev = ioreq->blkdev;
+    XenQdiskDataPlane *dataplane = ioreq->dataplane;
 
-    aio_context_acquire(blkdev->ctx);
+    aio_context_acquire(dataplane->ctx);
 
     if (ret != 0) {
         error_report("%s I/O error",
@@ -295,25 +295,25 @@ static void qemu_aio_complete(void *opaque, int ret)
         }
     case BLKIF_OP_READ:
         if (ioreq->status == BLKIF_RSP_OKAY) {
-            block_acct_done(blk_get_stats(blkdev->blk), &ioreq->acct);
+            block_acct_done(blk_get_stats(dataplane->blk), &ioreq->acct);
         } else {
-            block_acct_failed(blk_get_stats(blkdev->blk), &ioreq->acct);
+            block_acct_failed(blk_get_stats(dataplane->blk), &ioreq->acct);
         }
         break;
     case BLKIF_OP_DISCARD:
     default:
         break;
     }
-    qemu_bh_schedule(blkdev->bh);
+    qemu_bh_schedule(dataplane->bh);
 
 done:
-    aio_context_release(blkdev->ctx);
+    aio_context_release(dataplane->ctx);
 }
 
 static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_number,
                               uint64_t nr_sectors)
 {
-    struct XenBlkDev *blkdev = ioreq->blkdev;
+    XenQdiskDataPlane *dataplane = ioreq->dataplane;
     int64_t byte_offset;
     int byte_chunk;
     uint64_t byte_remaining, limit;
@@ -322,18 +322,18 @@ static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_number,
 
     /* Wrap around, or overflowing byte limit? */
     if (sec_start + sec_count < sec_count ||
-        sec_start + sec_count > INT64_MAX / blkdev->file_blk) {
+        sec_start + sec_count > INT64_MAX / dataplane->file_blk) {
         return false;
     }
 
-    limit = BDRV_REQUEST_MAX_SECTORS * blkdev->file_blk;
-    byte_offset = sec_start * blkdev->file_blk;
-    byte_remaining = sec_count * blkdev->file_blk;
+    limit = BDRV_REQUEST_MAX_SECTORS * dataplane->file_blk;
+    byte_offset = sec_start * dataplane->file_blk;
+    byte_remaining = sec_count * dataplane->file_blk;
 
     do {
         byte_chunk = byte_remaining > limit ? limit : byte_remaining;
         ioreq->aio_inflight++;
-        blk_aio_pdiscard(blkdev->blk, byte_offset, byte_chunk,
+        blk_aio_pdiscard(dataplane->blk, byte_offset, byte_chunk,
                          qemu_aio_complete, ioreq);
         byte_remaining -= byte_chunk;
         byte_offset += byte_chunk;
@@ -344,7 +344,7 @@ static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_number,
 
 static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
 {
-    struct XenBlkDev *blkdev = ioreq->blkdev;
+    XenQdiskDataPlane *dataplane = ioreq->dataplane;
 
     ioreq->buf = qemu_memalign(XC_PAGE_SIZE, ioreq->size);
     if (ioreq->req.nr_segments &&
@@ -357,17 +357,17 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
 
     ioreq->aio_inflight++;
     if (ioreq->presync) {
-        blk_aio_flush(ioreq->blkdev->blk, qemu_aio_complete, ioreq);
+        blk_aio_flush(ioreq->dataplane->blk, qemu_aio_complete, ioreq);
         return 0;
     }
 
     switch (ioreq->req.operation) {
     case BLKIF_OP_READ:
         qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size);
-        block_acct_start(blk_get_stats(blkdev->blk), &ioreq->acct,
+        block_acct_start(blk_get_stats(dataplane->blk), &ioreq->acct,
                          ioreq->v.size, BLOCK_ACCT_READ);
         ioreq->aio_inflight++;
-        blk_aio_preadv(blkdev->blk, ioreq->start, &ioreq->v, 0,
+        blk_aio_preadv(dataplane->blk, ioreq->start, &ioreq->v, 0,
                        qemu_aio_complete, ioreq);
         break;
     case BLKIF_OP_WRITE:
@@ -377,12 +377,12 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
         }
 
         qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size);
-        block_acct_start(blk_get_stats(blkdev->blk), &ioreq->acct,
+        block_acct_start(blk_get_stats(dataplane->blk), &ioreq->acct,
                          ioreq->v.size,
                          ioreq->req.operation == BLKIF_OP_WRITE ?
                          BLOCK_ACCT_WRITE : BLOCK_ACCT_FLUSH);
         ioreq->aio_inflight++;
-        blk_aio_pwritev(blkdev->blk, ioreq->start, &ioreq->v, 0,
+        blk_aio_pwritev(dataplane->blk, ioreq->start, &ioreq->v, 0,
                         qemu_aio_complete, ioreq);
         break;
     case BLKIF_OP_DISCARD:
@@ -410,27 +410,27 @@ err:
 
 static int blk_send_response_one(struct ioreq *ioreq)
 {
-    struct XenBlkDev *blkdev = ioreq->blkdev;
+    XenQdiskDataPlane *dataplane = ioreq->dataplane;
     int send_notify = 0;
     int have_requests = 0;
     blkif_response_t *resp;
 
     /* Place on the response ring for the relevant domain. */
-    switch (blkdev->protocol) {
+    switch (dataplane->protocol) {
     case BLKIF_PROTOCOL_NATIVE:
         resp = (blkif_response_t *)RING_GET_RESPONSE(
-            &blkdev->rings.native,
-            blkdev->rings.native.rsp_prod_pvt);
+            &dataplane->rings.native,
+            dataplane->rings.native.rsp_prod_pvt);
         break;
     case BLKIF_PROTOCOL_X86_32:
         resp = (blkif_response_t *)RING_GET_RESPONSE(
-            &blkdev->rings.x86_32_part,
-            blkdev->rings.x86_32_part.rsp_prod_pvt);
+            &dataplane->rings.x86_32_part,
+            dataplane->rings.x86_32_part.rsp_prod_pvt);
         break;
     case BLKIF_PROTOCOL_X86_64:
         resp = (blkif_response_t *)RING_GET_RESPONSE(
-            &blkdev->rings.x86_64_part,
-            blkdev->rings.x86_64_part.rsp_prod_pvt);
+            &dataplane->rings.x86_64_part,
+            dataplane->rings.x86_64_part.rsp_prod_pvt);
         break;
     default:
         return 0;
@@ -440,111 +440,124 @@ static int blk_send_response_one(struct ioreq *ioreq)
     resp->operation = ioreq->req.operation;
     resp->status = ioreq->status;
 
-    blkdev->rings.common.rsp_prod_pvt++;
+    dataplane->rings.common.rsp_prod_pvt++;
 
-    RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blkdev->rings.common, send_notify);
-    if (blkdev->rings.common.rsp_prod_pvt == blkdev->rings.common.req_cons) {
+    RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&dataplane->rings.common,
+                                         send_notify);
+    if (dataplane->rings.common.rsp_prod_pvt ==
+        dataplane->rings.common.req_cons) {
         /*
          * Tail check for pending requests. Allows frontend to avoid
          * notifications if requests are already in flight (lower
          * overheads and promotes batching).
          */
-        RING_FINAL_CHECK_FOR_REQUESTS(&blkdev->rings.common, have_requests);
-    } else if (RING_HAS_UNCONSUMED_REQUESTS(&blkdev->rings.common)) {
+        RING_FINAL_CHECK_FOR_REQUESTS(&dataplane->rings.common,
+                                      have_requests);
+    } else if (RING_HAS_UNCONSUMED_REQUESTS(&dataplane->rings.common)) {
         have_requests = 1;
     }
 
     if (have_requests) {
-        blkdev->more_work++;
+        dataplane->more_work++;
     }
     return send_notify;
 }
 
 /* walk finished list, send outstanding responses, free requests */
-static void blk_send_response_all(struct XenBlkDev *blkdev)
+static void blk_send_response_all(XenQdiskDataPlane *dataplane)
 {
     struct ioreq *ioreq;
     int send_notify = 0;
 
-    while (!QLIST_EMPTY(&blkdev->finished)) {
-        ioreq = QLIST_FIRST(&blkdev->finished);
+    while (!QLIST_EMPTY(&dataplane->finished)) {
+        ioreq = QLIST_FIRST(&dataplane->finished);
         send_notify += blk_send_response_one(ioreq);
         ioreq_release(ioreq, true);
     }
     if (send_notify) {
-        xen_device_notify_event_channel(blkdev->xendev, blkdev->event_channel);
+        xen_device_notify_event_channel(dataplane->xendev,
+                                        dataplane->event_channel);
     }
 }
 
-static int blk_get_request(struct XenBlkDev *blkdev, struct ioreq *ioreq,
+static int blk_get_request(XenQdiskDataPlane *dataplane, struct ioreq *ioreq,
                            RING_IDX rc)
 {
-    switch (blkdev->protocol) {
-    case BLKIF_PROTOCOL_NATIVE:
-        memcpy(&ioreq->req, RING_GET_REQUEST(&blkdev->rings.native, rc),
-               sizeof(ioreq->req));
+    switch (dataplane->protocol) {
+    case BLKIF_PROTOCOL_NATIVE: {
+        blkif_request_t *req =
+            RING_GET_REQUEST(&dataplane->rings.native, rc);
+
+        memcpy(&ioreq->req, req, sizeof(ioreq->req));
         break;
-    case BLKIF_PROTOCOL_X86_32:
-        blkif_get_x86_32_req(&ioreq->req,
-                             RING_GET_REQUEST(&blkdev->rings.x86_32_part, rc));
+    }
+    case BLKIF_PROTOCOL_X86_32: {
+        blkif_x86_32_request_t *req =
+            RING_GET_REQUEST(&dataplane->rings.x86_32_part, rc);
+
+        blkif_get_x86_32_req(&ioreq->req, req);
         break;
-    case BLKIF_PROTOCOL_X86_64:
-        blkif_get_x86_64_req(&ioreq->req,
-                             RING_GET_REQUEST(&blkdev->rings.x86_64_part, rc));
+    }
+    case BLKIF_PROTOCOL_X86_64: {
+        blkif_x86_64_request_t *req =
+            RING_GET_REQUEST(&dataplane->rings.x86_64_part, rc);
+
+        blkif_get_x86_64_req(&ioreq->req, req);
         break;
     }
+    }
     /* Prevent the compiler from accessing the on-ring fields instead. */
     barrier();
     return 0;
 }
 
-static void blk_handle_requests(struct XenBlkDev *blkdev)
+static void blk_handle_requests(XenQdiskDataPlane *dataplane)
 {
     RING_IDX rc, rp;
     struct ioreq *ioreq;
 
-    blkdev->more_work = 0;
+    dataplane->more_work = 0;
 
-    rc = blkdev->rings.common.req_cons;
-    rp = blkdev->rings.common.sring->req_prod;
+    rc = dataplane->rings.common.req_cons;
+    rp = dataplane->rings.common.sring->req_prod;
     xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
 
-    blk_send_response_all(blkdev);
+    blk_send_response_all(dataplane);
     while (rc != rp) {
         /* pull request from ring */
-        if (RING_REQUEST_CONS_OVERFLOW(&blkdev->rings.common, rc)) {
+        if (RING_REQUEST_CONS_OVERFLOW(&dataplane->rings.common, rc)) {
             break;
         }
-        ioreq = ioreq_start(blkdev);
+        ioreq = ioreq_start(dataplane);
         if (ioreq == NULL) {
-            blkdev->more_work++;
+            dataplane->more_work++;
             break;
         }
-        blk_get_request(blkdev, ioreq, rc);
-        blkdev->rings.common.req_cons = ++rc;
+        blk_get_request(dataplane, ioreq, rc);
+        dataplane->rings.common.req_cons = ++rc;
 
         /* parse them */
         if (ioreq_parse(ioreq) != 0) {
 
             switch (ioreq->req.operation) {
             case BLKIF_OP_READ:
-                block_acct_invalid(blk_get_stats(blkdev->blk),
+                block_acct_invalid(blk_get_stats(dataplane->blk),
                                    BLOCK_ACCT_READ);
                 break;
             case BLKIF_OP_WRITE:
-                block_acct_invalid(blk_get_stats(blkdev->blk),
+                block_acct_invalid(blk_get_stats(dataplane->blk),
                                    BLOCK_ACCT_WRITE);
                 break;
             case BLKIF_OP_FLUSH_DISKCACHE:
-                block_acct_invalid(blk_get_stats(blkdev->blk),
+                block_acct_invalid(blk_get_stats(dataplane->blk),
                                    BLOCK_ACCT_FLUSH);
             default:
                 break;
             };
 
             if (blk_send_response_one(ioreq)) {
-                xen_device_notify_event_channel(blkdev->xendev,
-                                                blkdev->event_channel);
+                xen_device_notify_event_channel(dataplane->xendev,
+                                                dataplane->event_channel);
             }
             ioreq_release(ioreq, false);
             continue;
@@ -553,111 +566,112 @@ static void blk_handle_requests(struct XenBlkDev *blkdev)
         ioreq_runio_qemu_aio(ioreq);
     }
 
-    if (blkdev->more_work && blkdev->requests_inflight < blkdev->max_requests) {
-        qemu_bh_schedule(blkdev->bh);
+    if (dataplane->more_work &&
+        dataplane->requests_inflight < dataplane->max_requests) {
+        qemu_bh_schedule(dataplane->bh);
     }
 }
 
 static void blk_bh(void *opaque)
 {
-    struct XenBlkDev *blkdev = opaque;
+    XenQdiskDataPlane *dataplane = opaque;
 
-    aio_context_acquire(blkdev->ctx);
-    blk_handle_requests(blkdev);
-    aio_context_release(blkdev->ctx);
+    aio_context_acquire(dataplane->ctx);
+    blk_handle_requests(dataplane);
+    aio_context_release(dataplane->ctx);
 }
 
 static void blk_event(void *opaque)
 {
-    struct XenBlkDev *blkdev = opaque;
+    XenQdiskDataPlane *dataplane = opaque;
 
-    qemu_bh_schedule(blkdev->bh);
+    qemu_bh_schedule(dataplane->bh);
 }
 
-struct XenBlkDev *xen_qdisk_dataplane_create(XenDevice *xendev,
+XenQdiskDataPlane *xen_qdisk_dataplane_create(XenDevice *xendev,
                                              BlockConf *conf,
                                              IOThread *iothread)
 {
-    struct XenBlkDev *blkdev = g_new0(struct XenBlkDev, 1);
+    XenQdiskDataPlane *dataplane = g_new0(XenQdiskDataPlane, 1);
 
-    blkdev->xendev = xendev;
-    blkdev->file_blk = conf->logical_block_size;
-    blkdev->blk = conf->blk;
-    blkdev->file_size = blk_getlength(blkdev->blk);
+    dataplane->xendev = xendev;
+    dataplane->file_blk = conf->logical_block_size;
+    dataplane->blk = conf->blk;
+    dataplane->file_size = blk_getlength(dataplane->blk);
 
-    QLIST_INIT(&blkdev->inflight);
-    QLIST_INIT(&blkdev->finished);
-    QLIST_INIT(&blkdev->freelist);
+    QLIST_INIT(&dataplane->inflight);
+    QLIST_INIT(&dataplane->finished);
+    QLIST_INIT(&dataplane->freelist);
 
     if (iothread) {
-        blkdev->iothread = iothread;
-        object_ref(OBJECT(blkdev->iothread));
-        blkdev->ctx = iothread_get_aio_context(blkdev->iothread);
+        dataplane->iothread = iothread;
+        object_ref(OBJECT(dataplane->iothread));
+        dataplane->ctx = iothread_get_aio_context(dataplane->iothread);
     } else {
-        blkdev->ctx = qemu_get_aio_context();
+        dataplane->ctx = qemu_get_aio_context();
     }
-    blkdev->bh = aio_bh_new(blkdev->ctx, blk_bh, blkdev);
+    dataplane->bh = aio_bh_new(dataplane->ctx, blk_bh, dataplane);
 
-    return blkdev;
+    return dataplane;
 }
 
-void xen_qdisk_dataplane_destroy(struct XenBlkDev *blkdev)
+void xen_qdisk_dataplane_destroy(XenQdiskDataPlane *dataplane)
 {
     struct ioreq *ioreq;
 
-    if (!blkdev) {
+    if (!dataplane) {
         return;
     }
 
-    while (!QLIST_EMPTY(&blkdev->freelist)) {
-        ioreq = QLIST_FIRST(&blkdev->freelist);
+    while (!QLIST_EMPTY(&dataplane->freelist)) {
+        ioreq = QLIST_FIRST(&dataplane->freelist);
         QLIST_REMOVE(ioreq, list);
         qemu_iovec_destroy(&ioreq->v);
         g_free(ioreq);
     }
 
-    qemu_bh_delete(blkdev->bh);
-    if (blkdev->iothread) {
-        object_unref(OBJECT(blkdev->iothread));
+    qemu_bh_delete(dataplane->bh);
+    if (dataplane->iothread) {
+        object_unref(OBJECT(dataplane->iothread));
     }
 
-    g_free(blkdev);
+    g_free(dataplane);
 }
 
-void xen_qdisk_dataplane_start(struct XenBlkDev *blkdev,
+void xen_qdisk_dataplane_start(XenQdiskDataPlane *dataplane,
                                const unsigned int ring_ref[],
                                unsigned int nr_ring_ref,
                                unsigned int event_channel,
                                unsigned int protocol)
 {
-    XenDevice *xendev = blkdev->xendev;
+    XenDevice *xendev = dataplane->xendev;
     unsigned int ring_size;
     unsigned int i;
 
-    blkdev->nr_ring_ref = nr_ring_ref;
-    blkdev->ring_ref = g_new(unsigned int, nr_ring_ref);
+    dataplane->nr_ring_ref = nr_ring_ref;
+    dataplane->ring_ref = g_new(unsigned int, nr_ring_ref);
 
     for (i = 0; i < nr_ring_ref; i++) {
-        blkdev->ring_ref[i] = ring_ref[i];
+        dataplane->ring_ref[i] = ring_ref[i];
     }
 
-    blkdev->protocol = protocol;
+    dataplane->protocol = protocol;
 
-    ring_size = XC_PAGE_SIZE * blkdev->nr_ring_ref;
-    switch (blkdev->protocol) {
+    ring_size = XC_PAGE_SIZE * dataplane->nr_ring_ref;
+    switch (dataplane->protocol) {
     case BLKIF_PROTOCOL_NATIVE:
     {
-        blkdev->max_requests = __CONST_RING_SIZE(blkif, ring_size);
+        dataplane->max_requests = __CONST_RING_SIZE(blkif, ring_size);
         break;
     }
     case BLKIF_PROTOCOL_X86_32:
     {
-        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_32, ring_size);
+        dataplane->max_requests = __CONST_RING_SIZE(blkif_x86_32, ring_size);
         break;
     }
     case BLKIF_PROTOCOL_X86_64:
     {
-        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_64, ring_size);
+        dataplane->max_requests = __CONST_RING_SIZE(blkif_x86_64, ring_size);
         break;
     }
     default:
@@ -665,76 +679,76 @@ void xen_qdisk_dataplane_start(struct XenBlkDev *blkdev,
         break;
     }
 
-    xen_device_set_max_grant_refs(xendev, blkdev->nr_ring_ref,
+    xen_device_set_max_grant_refs(xendev, dataplane->nr_ring_ref,
                                   &error_fatal);
 
-    blkdev->sring = xen_device_map_grant_refs(xendev,
-                                              blkdev->ring_ref,
-                                              blkdev->nr_ring_ref,
+    dataplane->sring = xen_device_map_grant_refs(xendev,
+                                              dataplane->ring_ref,
+                                              dataplane->nr_ring_ref,
                                               PROT_READ | PROT_WRITE,
                                               &error_fatal);
 
-    switch (blkdev->protocol) {
+    switch (dataplane->protocol) {
     case BLKIF_PROTOCOL_NATIVE:
     {
-        blkif_sring_t *sring_native = blkdev->sring;
+        blkif_sring_t *sring_native = dataplane->sring;
 
-        BACK_RING_INIT(&blkdev->rings.native, sring_native, ring_size);
+        BACK_RING_INIT(&dataplane->rings.native, sring_native, ring_size);
         break;
     }
     case BLKIF_PROTOCOL_X86_32:
     {
-        blkif_x86_32_sring_t *sring_x86_32 = blkdev->sring;
+        blkif_x86_32_sring_t *sring_x86_32 = dataplane->sring;
 
-        BACK_RING_INIT(&blkdev->rings.x86_32_part, sring_x86_32,
+        BACK_RING_INIT(&dataplane->rings.x86_32_part, sring_x86_32,
                        ring_size);
         break;
     }
     case BLKIF_PROTOCOL_X86_64:
     {
-        blkif_x86_64_sring_t *sring_x86_64 = blkdev->sring;
+        blkif_x86_64_sring_t *sring_x86_64 = dataplane->sring;
 
-        BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64,
+        BACK_RING_INIT(&dataplane->rings.x86_64_part, sring_x86_64,
                        ring_size);
         break;
     }
     }
 
-    blkdev->event_channel =
+    dataplane->event_channel =
         xen_device_bind_event_channel(xendev, event_channel,
-                                      blk_event, blkdev,
+                                      blk_event, dataplane,
                                       &error_fatal);
 
-    aio_context_acquire(blkdev->ctx);
-    blk_set_aio_context(blkdev->blk, blkdev->ctx);
-    aio_context_release(blkdev->ctx);
+    aio_context_acquire(dataplane->ctx);
+    blk_set_aio_context(dataplane->blk, dataplane->ctx);
+    aio_context_release(dataplane->ctx);
 }
 
-void xen_qdisk_dataplane_stop(struct XenBlkDev *blkdev)
+void xen_qdisk_dataplane_stop(XenQdiskDataPlane *dataplane)
 {
     XenDevice *xendev;
 
-    if (!blkdev) {
+    if (!dataplane) {
         return;
     }
 
-    aio_context_acquire(blkdev->ctx);
-    blk_set_aio_context(blkdev->blk, qemu_get_aio_context());
-    aio_context_release(blkdev->ctx);
+    aio_context_acquire(dataplane->ctx);
+    blk_set_aio_context(dataplane->blk, qemu_get_aio_context());
+    aio_context_release(dataplane->ctx);
 
-    xendev = blkdev->xendev;
+    xendev = dataplane->xendev;
 
-    if (blkdev->event_channel) {
-        xen_device_unbind_event_channel(xendev, blkdev->event_channel);
-        blkdev->event_channel = NULL;
+    if (dataplane->event_channel) {
+        xen_device_unbind_event_channel(xendev, dataplane->event_channel);
+        dataplane->event_channel = NULL;
     }
 
-    if (blkdev->sring) {
-        xen_device_unmap_grant_refs(xendev, blkdev->sring,
-                                    blkdev->nr_ring_ref, &error_fatal);
-        blkdev->sring = NULL;
+    if (dataplane->sring) {
+        xen_device_unmap_grant_refs(xendev, dataplane->sring,
+                                    dataplane->nr_ring_ref, &error_fatal);
+        dataplane->sring = NULL;
     }
 
-    g_free(blkdev->ring_ref);
-    blkdev->ring_ref = NULL;
+    g_free(dataplane->ring_ref);
+    dataplane->ring_ref = NULL;
 }
diff --git a/hw/block/dataplane/xen-qdisk.h b/hw/block/dataplane/xen-qdisk.h
index 16bcd500bf..cfa555af61 100644
--- a/hw/block/dataplane/xen-qdisk.h
+++ b/hw/block/dataplane/xen-qdisk.h
@@ -9,7 +9,7 @@
 #include "hw/xen/xen-bus.h"
 #include "sysemu/iothread.h"
 
-typedef struct XenBlkDev XenQdiskDataPlane;
+typedef struct XenQdiskDataPlane XenQdiskDataPlane;
 
 XenQdiskDataPlane *xen_qdisk_dataplane_create(XenDevice *xendev,
                                               BlockConf *conf,
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [PATCH 11/18] xen: remove 'XenBlkDev' and 'blkdev' names from dataplane/xen-qdisk
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
                   ` (14 preceding siblings ...)
  2018-11-21 15:12   ` Paul Durrant
@ 2018-11-21 15:12 ` Paul Durrant
  2018-11-21 15:12 ` [Qemu-devel] " Paul Durrant
                   ` (9 subsequent siblings)
  25 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Kevin Wolf, Stefano Stabellini, Max Reitz, Paul Durrant,
	Stefan Hajnoczi, Anthony Perard

This is a purely cosmetic patch that substitutes the old 'struct XenBlkDev'
name with 'XenQdiskDataPlane' and 'blkdev' field/variable names with
'dataplane', and then does necessary fix-up to adhere to coding style.

No functional change.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
---
 hw/block/dataplane/xen-qdisk.c | 342 +++++++++++++++++++++--------------------
 hw/block/dataplane/xen-qdisk.h |   2 +-
 2 files changed, 179 insertions(+), 165 deletions(-)

diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-qdisk.c
index b075aa975d..2214455ff9 100644
--- a/hw/block/dataplane/xen-qdisk.c
+++ b/hw/block/dataplane/xen-qdisk.c
@@ -28,12 +28,12 @@ struct ioreq {
     int presync;
     int aio_inflight;
     int aio_errors;
-    struct XenBlkDev *blkdev;
+    XenQdiskDataPlane *dataplane;
     QLIST_ENTRY(ioreq) list;
     BlockAcctCookie acct;
 };
 
-struct XenBlkDev {
+struct XenQdiskDataPlane {
     XenDevice *xendev;
     XenEventChannel *event_channel;
     unsigned int *ring_ref;
@@ -69,33 +69,33 @@ static void ioreq_reset(struct ioreq *ioreq)
     ioreq->aio_inflight = 0;
     ioreq->aio_errors = 0;
 
-    ioreq->blkdev = NULL;
+    ioreq->dataplane = NULL;
     memset(&ioreq->list, 0, sizeof(ioreq->list));
     memset(&ioreq->acct, 0, sizeof(ioreq->acct));
 
     qemu_iovec_reset(&ioreq->v);
 }
 
-static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
+static struct ioreq *ioreq_start(XenQdiskDataPlane *dataplane)
 {
     struct ioreq *ioreq = NULL;
 
-    if (QLIST_EMPTY(&blkdev->freelist)) {
-        if (blkdev->requests_total >= blkdev->max_requests) {
+    if (QLIST_EMPTY(&dataplane->freelist)) {
+        if (dataplane->requests_total >= dataplane->max_requests) {
             goto out;
         }
         /* allocate new struct */
         ioreq = g_malloc0(sizeof(*ioreq));
-        ioreq->blkdev = blkdev;
-        blkdev->requests_total++;
+        ioreq->dataplane = dataplane;
+        dataplane->requests_total++;
         qemu_iovec_init(&ioreq->v, 1);
     } else {
         /* get one from freelist */
-        ioreq = QLIST_FIRST(&blkdev->freelist);
+        ioreq = QLIST_FIRST(&dataplane->freelist);
         QLIST_REMOVE(ioreq, list);
     }
-    QLIST_INSERT_HEAD(&blkdev->inflight, ioreq, list);
-    blkdev->requests_inflight++;
+    QLIST_INSERT_HEAD(&dataplane->inflight, ioreq, list);
+    dataplane->requests_inflight++;
 
 out:
     return ioreq;
@@ -103,26 +103,26 @@ out:
 
 static void ioreq_finish(struct ioreq *ioreq)
 {
-    struct XenBlkDev *blkdev = ioreq->blkdev;
+    XenQdiskDataPlane *dataplane = ioreq->dataplane;
 
     QLIST_REMOVE(ioreq, list);
-    QLIST_INSERT_HEAD(&blkdev->finished, ioreq, list);
-    blkdev->requests_inflight--;
-    blkdev->requests_finished++;
+    QLIST_INSERT_HEAD(&dataplane->finished, ioreq, list);
+    dataplane->requests_inflight--;
+    dataplane->requests_finished++;
 }
 
 static void ioreq_release(struct ioreq *ioreq, bool finish)
 {
-    struct XenBlkDev *blkdev = ioreq->blkdev;
+    XenQdiskDataPlane *dataplane = ioreq->dataplane;
 
     QLIST_REMOVE(ioreq, list);
     ioreq_reset(ioreq);
-    ioreq->blkdev = blkdev;
-    QLIST_INSERT_HEAD(&blkdev->freelist, ioreq, list);
+    ioreq->dataplane = dataplane;
+    QLIST_INSERT_HEAD(&dataplane->freelist, ioreq, list);
     if (finish) {
-        blkdev->requests_finished--;
+        dataplane->requests_finished--;
     } else {
-        blkdev->requests_inflight--;
+        dataplane->requests_inflight--;
     }
 }
 
@@ -132,7 +132,7 @@ static void ioreq_release(struct ioreq *ioreq, bool finish)
  */
 static int ioreq_parse(struct ioreq *ioreq)
 {
-    struct XenBlkDev *blkdev = ioreq->blkdev;
+    XenQdiskDataPlane *dataplane = ioreq->dataplane;
     size_t len;
     int i;
 
@@ -155,12 +155,12 @@ static int ioreq_parse(struct ioreq *ioreq)
     };
 
     if (ioreq->req.operation != BLKIF_OP_READ &&
-        blk_is_read_only(blkdev->blk)) {
+        blk_is_read_only(dataplane->blk)) {
         error_report("error: write req for ro device");
         goto err;
     }
 
-    ioreq->start = ioreq->req.sector_number * blkdev->file_blk;
+    ioreq->start = ioreq->req.sector_number * dataplane->file_blk;
     for (i = 0; i < ioreq->req.nr_segments; i++) {
         if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
             error_report("error: nr_segments too big");
@@ -170,16 +170,16 @@ static int ioreq_parse(struct ioreq *ioreq)
             error_report("error: first > last sector");
             goto err;
         }
-        if (ioreq->req.seg[i].last_sect * blkdev->file_blk >= XC_PAGE_SIZE) {
+        if (ioreq->req.seg[i].last_sect * dataplane->file_blk >= XC_PAGE_SIZE) {
             error_report("error: page crossing");
             goto err;
         }
 
         len = (ioreq->req.seg[i].last_sect -
-               ioreq->req.seg[i].first_sect + 1) * blkdev->file_blk;
+               ioreq->req.seg[i].first_sect + 1) * dataplane->file_blk;
         ioreq->size += len;
     }
-    if (ioreq->start + ioreq->size > blkdev->file_size) {
+    if (ioreq->start + ioreq->size > dataplane->file_size) {
         error_report("error: access beyond end of file");
         goto err;
     }
@@ -192,11 +192,11 @@ err:
 
 static int ioreq_grant_copy(struct ioreq *ioreq)
 {
-    struct XenBlkDev *blkdev = ioreq->blkdev;
-    XenDevice *xendev = blkdev->xendev;
+    XenQdiskDataPlane *dataplane = ioreq->dataplane;
+    XenDevice *xendev = dataplane->xendev;
     XenDeviceGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
     int i, count;
-    int64_t file_blk = blkdev->file_blk;
+    int64_t file_blk = dataplane->file_blk;
     bool to_domain = (ioreq->req.operation == BLKIF_OP_READ);
     void *virt = ioreq->buf;
     Error *local_err = NULL;
@@ -244,9 +244,9 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq);
 static void qemu_aio_complete(void *opaque, int ret)
 {
     struct ioreq *ioreq = opaque;
-    struct XenBlkDev *blkdev = ioreq->blkdev;
+    XenQdiskDataPlane *dataplane = ioreq->dataplane;
 
-    aio_context_acquire(blkdev->ctx);
+    aio_context_acquire(dataplane->ctx);
 
     if (ret != 0) {
         error_report("%s I/O error",
@@ -295,25 +295,25 @@ static void qemu_aio_complete(void *opaque, int ret)
         }
     case BLKIF_OP_READ:
         if (ioreq->status == BLKIF_RSP_OKAY) {
-            block_acct_done(blk_get_stats(blkdev->blk), &ioreq->acct);
+            block_acct_done(blk_get_stats(dataplane->blk), &ioreq->acct);
         } else {
-            block_acct_failed(blk_get_stats(blkdev->blk), &ioreq->acct);
+            block_acct_failed(blk_get_stats(dataplane->blk), &ioreq->acct);
         }
         break;
     case BLKIF_OP_DISCARD:
     default:
         break;
     }
-    qemu_bh_schedule(blkdev->bh);
+    qemu_bh_schedule(dataplane->bh);
 
 done:
-    aio_context_release(blkdev->ctx);
+    aio_context_release(dataplane->ctx);
 }
 
 static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_number,
                               uint64_t nr_sectors)
 {
-    struct XenBlkDev *blkdev = ioreq->blkdev;
+    XenQdiskDataPlane *dataplane = ioreq->dataplane;
     int64_t byte_offset;
     int byte_chunk;
     uint64_t byte_remaining, limit;
@@ -322,18 +322,18 @@ static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_number,
 
     /* Wrap around, or overflowing byte limit? */
     if (sec_start + sec_count < sec_count ||
-        sec_start + sec_count > INT64_MAX / blkdev->file_blk) {
+        sec_start + sec_count > INT64_MAX / dataplane->file_blk) {
         return false;
     }
 
-    limit = BDRV_REQUEST_MAX_SECTORS * blkdev->file_blk;
-    byte_offset = sec_start * blkdev->file_blk;
-    byte_remaining = sec_count * blkdev->file_blk;
+    limit = BDRV_REQUEST_MAX_SECTORS * dataplane->file_blk;
+    byte_offset = sec_start * dataplane->file_blk;
+    byte_remaining = sec_count * dataplane->file_blk;
 
     do {
         byte_chunk = byte_remaining > limit ? limit : byte_remaining;
         ioreq->aio_inflight++;
-        blk_aio_pdiscard(blkdev->blk, byte_offset, byte_chunk,
+        blk_aio_pdiscard(dataplane->blk, byte_offset, byte_chunk,
                          qemu_aio_complete, ioreq);
         byte_remaining -= byte_chunk;
         byte_offset += byte_chunk;
@@ -344,7 +344,7 @@ static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_number,
 
 static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
 {
-    struct XenBlkDev *blkdev = ioreq->blkdev;
+    XenQdiskDataPlane *dataplane = ioreq->dataplane;
 
     ioreq->buf = qemu_memalign(XC_PAGE_SIZE, ioreq->size);
     if (ioreq->req.nr_segments &&
@@ -357,17 +357,17 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
 
     ioreq->aio_inflight++;
     if (ioreq->presync) {
-        blk_aio_flush(ioreq->blkdev->blk, qemu_aio_complete, ioreq);
+        blk_aio_flush(ioreq->dataplane->blk, qemu_aio_complete, ioreq);
         return 0;
     }
 
     switch (ioreq->req.operation) {
     case BLKIF_OP_READ:
         qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size);
-        block_acct_start(blk_get_stats(blkdev->blk), &ioreq->acct,
+        block_acct_start(blk_get_stats(dataplane->blk), &ioreq->acct,
                          ioreq->v.size, BLOCK_ACCT_READ);
         ioreq->aio_inflight++;
-        blk_aio_preadv(blkdev->blk, ioreq->start, &ioreq->v, 0,
+        blk_aio_preadv(dataplane->blk, ioreq->start, &ioreq->v, 0,
                        qemu_aio_complete, ioreq);
         break;
     case BLKIF_OP_WRITE:
@@ -377,12 +377,12 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
         }
 
         qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size);
-        block_acct_start(blk_get_stats(blkdev->blk), &ioreq->acct,
+        block_acct_start(blk_get_stats(dataplane->blk), &ioreq->acct,
                          ioreq->v.size,
                          ioreq->req.operation == BLKIF_OP_WRITE ?
                          BLOCK_ACCT_WRITE : BLOCK_ACCT_FLUSH);
         ioreq->aio_inflight++;
-        blk_aio_pwritev(blkdev->blk, ioreq->start, &ioreq->v, 0,
+        blk_aio_pwritev(dataplane->blk, ioreq->start, &ioreq->v, 0,
                         qemu_aio_complete, ioreq);
         break;
     case BLKIF_OP_DISCARD:
@@ -410,27 +410,27 @@ err:
 
 static int blk_send_response_one(struct ioreq *ioreq)
 {
-    struct XenBlkDev *blkdev = ioreq->blkdev;
+    XenQdiskDataPlane *dataplane = ioreq->dataplane;
     int send_notify = 0;
     int have_requests = 0;
     blkif_response_t *resp;
 
     /* Place on the response ring for the relevant domain. */
-    switch (blkdev->protocol) {
+    switch (dataplane->protocol) {
     case BLKIF_PROTOCOL_NATIVE:
         resp = (blkif_response_t *)RING_GET_RESPONSE(
-            &blkdev->rings.native,
-            blkdev->rings.native.rsp_prod_pvt);
+            &dataplane->rings.native,
+            dataplane->rings.native.rsp_prod_pvt);
         break;
     case BLKIF_PROTOCOL_X86_32:
         resp = (blkif_response_t *)RING_GET_RESPONSE(
-            &blkdev->rings.x86_32_part,
-            blkdev->rings.x86_32_part.rsp_prod_pvt);
+            &dataplane->rings.x86_32_part,
+            dataplane->rings.x86_32_part.rsp_prod_pvt);
         break;
     case BLKIF_PROTOCOL_X86_64:
         resp = (blkif_response_t *)RING_GET_RESPONSE(
-            &blkdev->rings.x86_64_part,
-            blkdev->rings.x86_64_part.rsp_prod_pvt);
+            &dataplane->rings.x86_64_part,
+            dataplane->rings.x86_64_part.rsp_prod_pvt);
         break;
     default:
         return 0;
@@ -440,111 +440,124 @@ static int blk_send_response_one(struct ioreq *ioreq)
     resp->operation = ioreq->req.operation;
     resp->status = ioreq->status;
 
-    blkdev->rings.common.rsp_prod_pvt++;
+    dataplane->rings.common.rsp_prod_pvt++;
 
-    RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blkdev->rings.common, send_notify);
-    if (blkdev->rings.common.rsp_prod_pvt == blkdev->rings.common.req_cons) {
+    RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&dataplane->rings.common,
+                                         send_notify);
+    if (dataplane->rings.common.rsp_prod_pvt ==
+        dataplane->rings.common.req_cons) {
         /*
          * Tail check for pending requests. Allows frontend to avoid
          * notifications if requests are already in flight (lower
          * overheads and promotes batching).
          */
-        RING_FINAL_CHECK_FOR_REQUESTS(&blkdev->rings.common, have_requests);
-    } else if (RING_HAS_UNCONSUMED_REQUESTS(&blkdev->rings.common)) {
+        RING_FINAL_CHECK_FOR_REQUESTS(&dataplane->rings.common,
+                                      have_requests);
+    } else if (RING_HAS_UNCONSUMED_REQUESTS(&dataplane->rings.common)) {
         have_requests = 1;
     }
 
     if (have_requests) {
-        blkdev->more_work++;
+        dataplane->more_work++;
     }
     return send_notify;
 }
 
 /* walk finished list, send outstanding responses, free requests */
-static void blk_send_response_all(struct XenBlkDev *blkdev)
+static void blk_send_response_all(XenQdiskDataPlane *dataplane)
 {
     struct ioreq *ioreq;
     int send_notify = 0;
 
-    while (!QLIST_EMPTY(&blkdev->finished)) {
-        ioreq = QLIST_FIRST(&blkdev->finished);
+    while (!QLIST_EMPTY(&dataplane->finished)) {
+        ioreq = QLIST_FIRST(&dataplane->finished);
         send_notify += blk_send_response_one(ioreq);
         ioreq_release(ioreq, true);
     }
     if (send_notify) {
-        xen_device_notify_event_channel(blkdev->xendev, blkdev->event_channel);
+        xen_device_notify_event_channel(dataplane->xendev,
+                                        dataplane->event_channel);
     }
 }
 
-static int blk_get_request(struct XenBlkDev *blkdev, struct ioreq *ioreq,
+static int blk_get_request(XenQdiskDataPlane *dataplane, struct ioreq *ioreq,
                            RING_IDX rc)
 {
-    switch (blkdev->protocol) {
-    case BLKIF_PROTOCOL_NATIVE:
-        memcpy(&ioreq->req, RING_GET_REQUEST(&blkdev->rings.native, rc),
-               sizeof(ioreq->req));
+    switch (dataplane->protocol) {
+    case BLKIF_PROTOCOL_NATIVE: {
+        blkif_request_t *req =
+            RING_GET_REQUEST(&dataplane->rings.native, rc);
+
+        memcpy(&ioreq->req, req, sizeof(ioreq->req));
         break;
-    case BLKIF_PROTOCOL_X86_32:
-        blkif_get_x86_32_req(&ioreq->req,
-                             RING_GET_REQUEST(&blkdev->rings.x86_32_part, rc));
+    }
+    case BLKIF_PROTOCOL_X86_32: {
+        blkif_x86_32_request_t *req =
+            RING_GET_REQUEST(&dataplane->rings.x86_32_part, rc);
+
+        blkif_get_x86_32_req(&ioreq->req, req);
         break;
-    case BLKIF_PROTOCOL_X86_64:
-        blkif_get_x86_64_req(&ioreq->req,
-                             RING_GET_REQUEST(&blkdev->rings.x86_64_part, rc));
+    }
+    case BLKIF_PROTOCOL_X86_64: {
+        blkif_x86_64_request_t *req =
+            RING_GET_REQUEST(&dataplane->rings.x86_64_part, rc);
+
+        blkif_get_x86_64_req(&ioreq->req, req);
         break;
     }
+    }
     /* Prevent the compiler from accessing the on-ring fields instead. */
     barrier();
     return 0;
 }
 
-static void blk_handle_requests(struct XenBlkDev *blkdev)
+static void blk_handle_requests(XenQdiskDataPlane *dataplane)
 {
     RING_IDX rc, rp;
     struct ioreq *ioreq;
 
-    blkdev->more_work = 0;
+    dataplane->more_work = 0;
 
-    rc = blkdev->rings.common.req_cons;
-    rp = blkdev->rings.common.sring->req_prod;
+    rc = dataplane->rings.common.req_cons;
+    rp = dataplane->rings.common.sring->req_prod;
     xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
 
-    blk_send_response_all(blkdev);
+    blk_send_response_all(dataplane);
     while (rc != rp) {
         /* pull request from ring */
-        if (RING_REQUEST_CONS_OVERFLOW(&blkdev->rings.common, rc)) {
+        if (RING_REQUEST_CONS_OVERFLOW(&dataplane->rings.common, rc)) {
             break;
         }
-        ioreq = ioreq_start(blkdev);
+        ioreq = ioreq_start(dataplane);
         if (ioreq == NULL) {
-            blkdev->more_work++;
+            dataplane->more_work++;
             break;
         }
-        blk_get_request(blkdev, ioreq, rc);
-        blkdev->rings.common.req_cons = ++rc;
+        blk_get_request(dataplane, ioreq, rc);
+        dataplane->rings.common.req_cons = ++rc;
 
         /* parse them */
         if (ioreq_parse(ioreq) != 0) {
 
             switch (ioreq->req.operation) {
             case BLKIF_OP_READ:
-                block_acct_invalid(blk_get_stats(blkdev->blk),
+                block_acct_invalid(blk_get_stats(dataplane->blk),
                                    BLOCK_ACCT_READ);
                 break;
             case BLKIF_OP_WRITE:
-                block_acct_invalid(blk_get_stats(blkdev->blk),
+                block_acct_invalid(blk_get_stats(dataplane->blk),
                                    BLOCK_ACCT_WRITE);
                 break;
             case BLKIF_OP_FLUSH_DISKCACHE:
-                block_acct_invalid(blk_get_stats(blkdev->blk),
+                block_acct_invalid(blk_get_stats(dataplane->blk),
                                    BLOCK_ACCT_FLUSH);
             default:
                 break;
             };
 
             if (blk_send_response_one(ioreq)) {
-                xen_device_notify_event_channel(blkdev->xendev,
-                                                blkdev->event_channel);
+                xen_device_notify_event_channel(dataplane->xendev,
+                                                dataplane->event_channel);
             }
             ioreq_release(ioreq, false);
             continue;
@@ -553,111 +566,112 @@ static void blk_handle_requests(struct XenBlkDev *blkdev)
         ioreq_runio_qemu_aio(ioreq);
     }
 
-    if (blkdev->more_work && blkdev->requests_inflight < blkdev->max_requests) {
-        qemu_bh_schedule(blkdev->bh);
+    if (dataplane->more_work &&
+        dataplane->requests_inflight < dataplane->max_requests) {
+        qemu_bh_schedule(dataplane->bh);
     }
 }
 
 static void blk_bh(void *opaque)
 {
-    struct XenBlkDev *blkdev = opaque;
+    XenQdiskDataPlane *dataplane = opaque;
 
-    aio_context_acquire(blkdev->ctx);
-    blk_handle_requests(blkdev);
-    aio_context_release(blkdev->ctx);
+    aio_context_acquire(dataplane->ctx);
+    blk_handle_requests(dataplane);
+    aio_context_release(dataplane->ctx);
 }
 
 static void blk_event(void *opaque)
 {
-    struct XenBlkDev *blkdev = opaque;
+    XenQdiskDataPlane *dataplane = opaque;
 
-    qemu_bh_schedule(blkdev->bh);
+    qemu_bh_schedule(dataplane->bh);
 }
 
-struct XenBlkDev *xen_qdisk_dataplane_create(XenDevice *xendev,
+XenQdiskDataPlane *xen_qdisk_dataplane_create(XenDevice *xendev,
                                              BlockConf *conf,
                                              IOThread *iothread)
 {
-    struct XenBlkDev *blkdev = g_new0(struct XenBlkDev, 1);
+    XenQdiskDataPlane *dataplane = g_new0(XenQdiskDataPlane, 1);
 
-    blkdev->xendev = xendev;
-    blkdev->file_blk = conf->logical_block_size;
-    blkdev->blk = conf->blk;
-    blkdev->file_size = blk_getlength(blkdev->blk);
+    dataplane->xendev = xendev;
+    dataplane->file_blk = conf->logical_block_size;
+    dataplane->blk = conf->blk;
+    dataplane->file_size = blk_getlength(dataplane->blk);
 
-    QLIST_INIT(&blkdev->inflight);
-    QLIST_INIT(&blkdev->finished);
-    QLIST_INIT(&blkdev->freelist);
+    QLIST_INIT(&dataplane->inflight);
+    QLIST_INIT(&dataplane->finished);
+    QLIST_INIT(&dataplane->freelist);
 
     if (iothread) {
-        blkdev->iothread = iothread;
-        object_ref(OBJECT(blkdev->iothread));
-        blkdev->ctx = iothread_get_aio_context(blkdev->iothread);
+        dataplane->iothread = iothread;
+        object_ref(OBJECT(dataplane->iothread));
+        dataplane->ctx = iothread_get_aio_context(dataplane->iothread);
     } else {
-        blkdev->ctx = qemu_get_aio_context();
+        dataplane->ctx = qemu_get_aio_context();
     }
-    blkdev->bh = aio_bh_new(blkdev->ctx, blk_bh, blkdev);
+    dataplane->bh = aio_bh_new(dataplane->ctx, blk_bh, dataplane);
 
-    return blkdev;
+    return dataplane;
 }
 
-void xen_qdisk_dataplane_destroy(struct XenBlkDev *blkdev)
+void xen_qdisk_dataplane_destroy(XenQdiskDataPlane *dataplane)
 {
     struct ioreq *ioreq;
 
-    if (!blkdev) {
+    if (!dataplane) {
         return;
     }
 
-    while (!QLIST_EMPTY(&blkdev->freelist)) {
-        ioreq = QLIST_FIRST(&blkdev->freelist);
+    while (!QLIST_EMPTY(&dataplane->freelist)) {
+        ioreq = QLIST_FIRST(&dataplane->freelist);
         QLIST_REMOVE(ioreq, list);
         qemu_iovec_destroy(&ioreq->v);
         g_free(ioreq);
     }
 
-    qemu_bh_delete(blkdev->bh);
-    if (blkdev->iothread) {
-        object_unref(OBJECT(blkdev->iothread));
+    qemu_bh_delete(dataplane->bh);
+    if (dataplane->iothread) {
+        object_unref(OBJECT(dataplane->iothread));
     }
 
-    g_free(blkdev);
+    g_free(dataplane);
 }
 
-void xen_qdisk_dataplane_start(struct XenBlkDev *blkdev,
+void xen_qdisk_dataplane_start(XenQdiskDataPlane *dataplane,
                                const unsigned int ring_ref[],
                                unsigned int nr_ring_ref,
                                unsigned int event_channel,
                                unsigned int protocol)
 {
-    XenDevice *xendev = blkdev->xendev;
+    XenDevice *xendev = dataplane->xendev;
     unsigned int ring_size;
     unsigned int i;
 
-    blkdev->nr_ring_ref = nr_ring_ref;
-    blkdev->ring_ref = g_new(unsigned int, nr_ring_ref);
+    dataplane->nr_ring_ref = nr_ring_ref;
+    dataplane->ring_ref = g_new(unsigned int, nr_ring_ref);
 
     for (i = 0; i < nr_ring_ref; i++) {
-        blkdev->ring_ref[i] = ring_ref[i];
+        dataplane->ring_ref[i] = ring_ref[i];
     }
 
-    blkdev->protocol = protocol;
+    dataplane->protocol = protocol;
 
-    ring_size = XC_PAGE_SIZE * blkdev->nr_ring_ref;
-    switch (blkdev->protocol) {
+    ring_size = XC_PAGE_SIZE * dataplane->nr_ring_ref;
+    switch (dataplane->protocol) {
     case BLKIF_PROTOCOL_NATIVE:
     {
-        blkdev->max_requests = __CONST_RING_SIZE(blkif, ring_size);
+        dataplane->max_requests = __CONST_RING_SIZE(blkif, ring_size);
         break;
     }
     case BLKIF_PROTOCOL_X86_32:
     {
-        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_32, ring_size);
+        dataplane->max_requests = __CONST_RING_SIZE(blkif_x86_32, ring_size);
         break;
     }
     case BLKIF_PROTOCOL_X86_64:
     {
-        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_64, ring_size);
+        dataplane->max_requests = __CONST_RING_SIZE(blkif_x86_64, ring_size);
         break;
     }
     default:
@@ -665,76 +679,76 @@ void xen_qdisk_dataplane_start(struct XenBlkDev *blkdev,
         break;
     }
 
-    xen_device_set_max_grant_refs(xendev, blkdev->nr_ring_ref,
+    xen_device_set_max_grant_refs(xendev, dataplane->nr_ring_ref,
                                   &error_fatal);
 
-    blkdev->sring = xen_device_map_grant_refs(xendev,
-                                              blkdev->ring_ref,
-                                              blkdev->nr_ring_ref,
+    dataplane->sring = xen_device_map_grant_refs(xendev,
+                                              dataplane->ring_ref,
+                                              dataplane->nr_ring_ref,
                                               PROT_READ | PROT_WRITE,
                                               &error_fatal);
 
-    switch (blkdev->protocol) {
+    switch (dataplane->protocol) {
     case BLKIF_PROTOCOL_NATIVE:
     {
-        blkif_sring_t *sring_native = blkdev->sring;
+        blkif_sring_t *sring_native = dataplane->sring;
 
-        BACK_RING_INIT(&blkdev->rings.native, sring_native, ring_size);
+        BACK_RING_INIT(&dataplane->rings.native, sring_native, ring_size);
         break;
     }
     case BLKIF_PROTOCOL_X86_32:
     {
-        blkif_x86_32_sring_t *sring_x86_32 = blkdev->sring;
+        blkif_x86_32_sring_t *sring_x86_32 = dataplane->sring;
 
-        BACK_RING_INIT(&blkdev->rings.x86_32_part, sring_x86_32,
+        BACK_RING_INIT(&dataplane->rings.x86_32_part, sring_x86_32,
                        ring_size);
         break;
     }
     case BLKIF_PROTOCOL_X86_64:
     {
-        blkif_x86_64_sring_t *sring_x86_64 = blkdev->sring;
+        blkif_x86_64_sring_t *sring_x86_64 = dataplane->sring;
 
-        BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64,
+        BACK_RING_INIT(&dataplane->rings.x86_64_part, sring_x86_64,
                        ring_size);
         break;
     }
     }
 
-    blkdev->event_channel =
+    dataplane->event_channel =
         xen_device_bind_event_channel(xendev, event_channel,
-                                      blk_event, blkdev,
+                                      blk_event, dataplane,
                                       &error_fatal);
 
-    aio_context_acquire(blkdev->ctx);
-    blk_set_aio_context(blkdev->blk, blkdev->ctx);
-    aio_context_release(blkdev->ctx);
+    aio_context_acquire(dataplane->ctx);
+    blk_set_aio_context(dataplane->blk, dataplane->ctx);
+    aio_context_release(dataplane->ctx);
 }
 
-void xen_qdisk_dataplane_stop(struct XenBlkDev *blkdev)
+void xen_qdisk_dataplane_stop(XenQdiskDataPlane *dataplane)
 {
     XenDevice *xendev;
 
-    if (!blkdev) {
+    if (!dataplane) {
         return;
     }
 
-    aio_context_acquire(blkdev->ctx);
-    blk_set_aio_context(blkdev->blk, qemu_get_aio_context());
-    aio_context_release(blkdev->ctx);
+    aio_context_acquire(dataplane->ctx);
+    blk_set_aio_context(dataplane->blk, qemu_get_aio_context());
+    aio_context_release(dataplane->ctx);
 
-    xendev = blkdev->xendev;
+    xendev = dataplane->xendev;
 
-    if (blkdev->event_channel) {
-        xen_device_unbind_event_channel(xendev, blkdev->event_channel);
-        blkdev->event_channel = NULL;
+    if (dataplane->event_channel) {
+        xen_device_unbind_event_channel(xendev, dataplane->event_channel);
+        dataplane->event_channel = NULL;
     }
 
-    if (blkdev->sring) {
-        xen_device_unmap_grant_refs(xendev, blkdev->sring,
-                                    blkdev->nr_ring_ref, &error_fatal);
-        blkdev->sring = NULL;
+    if (dataplane->sring) {
+        xen_device_unmap_grant_refs(xendev, dataplane->sring,
+                                    dataplane->nr_ring_ref, &error_fatal);
+        dataplane->sring = NULL;
     }
 
-    g_free(blkdev->ring_ref);
-    blkdev->ring_ref = NULL;
+    g_free(dataplane->ring_ref);
+    dataplane->ring_ref = NULL;
 }
diff --git a/hw/block/dataplane/xen-qdisk.h b/hw/block/dataplane/xen-qdisk.h
index 16bcd500bf..cfa555af61 100644
--- a/hw/block/dataplane/xen-qdisk.h
+++ b/hw/block/dataplane/xen-qdisk.h
@@ -9,7 +9,7 @@
 #include "hw/xen/xen-bus.h"
 #include "sysemu/iothread.h"
 
-typedef struct XenBlkDev XenQdiskDataPlane;
+typedef struct XenQdiskDataPlane XenQdiskDataPlane;
 
 XenQdiskDataPlane *xen_qdisk_dataplane_create(XenDevice *xendev,
                                               BlockConf *conf,
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [Qemu-devel] [PATCH 12/18] xen: remove 'ioreq' struct/varable/field names from dataplane/xen-qdisk.c
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
@ 2018-11-21 15:12   ` Paul Durrant
  2018-11-21 15:11 ` [Qemu-devel] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy Paul Durrant
                     ` (24 subsequent siblings)
  25 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Paul Durrant, Stefan Hajnoczi, Stefano Stabellini,
	Anthony Perard, Kevin Wolf, Max Reitz

This is a purely cosmetic patch that purges the name 'ioreq' from struct,
variable and field names. (This name has been problematic for a long time
as 'ioreq' is the name used for generic I/O requests coming from Xen).
The patch replaces 'struct ioreq' with a new 'XenQdiskRequest' type and
'ioreq' field/variable names with 'request', and then does necessary
fix-up to adhere to coding style.

Function names are not modified by this patch. Yhey will be dealt with in
a subsequent patch.

No functional change.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
---
 hw/block/dataplane/xen-qdisk.c | 310 +++++++++++++++++++++--------------------
 1 file changed, 156 insertions(+), 154 deletions(-)

diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-qdisk.c
index 2214455ff9..50a48b6f5f 100644
--- a/hw/block/dataplane/xen-qdisk.c
+++ b/hw/block/dataplane/xen-qdisk.c
@@ -18,7 +18,7 @@
 #include "sysemu/iothread.h"
 #include "xen-qdisk.h"
 
-struct ioreq {
+typedef struct XenQdiskRequest {
     blkif_request_t req;
     int16_t status;
     off_t start;
@@ -29,9 +29,9 @@ struct ioreq {
     int aio_inflight;
     int aio_errors;
     XenQdiskDataPlane *dataplane;
-    QLIST_ENTRY(ioreq) list;
+    QLIST_ENTRY(XenQdiskRequest) list;
     BlockAcctCookie acct;
-};
+} XenQdiskRequest;
 
 struct XenQdiskDataPlane {
     XenDevice *xendev;
@@ -44,9 +44,9 @@ struct XenQdiskDataPlane {
     int protocol;
     blkif_back_rings_t rings;
     int more_work;
-    QLIST_HEAD(inflight_head, ioreq) inflight;
-    QLIST_HEAD(finished_head, ioreq) finished;
-    QLIST_HEAD(freelist_head, ioreq) freelist;
+    QLIST_HEAD(inflight_head, XenQdiskRequest) inflight;
+    QLIST_HEAD(finished_head, XenQdiskRequest) finished;
+    QLIST_HEAD(freelist_head, XenQdiskRequest) freelist;
     int requests_total;
     int requests_inflight;
     int requests_finished;
@@ -57,68 +57,68 @@ struct XenQdiskDataPlane {
     AioContext *ctx;
 };
 
-static void ioreq_reset(struct ioreq *ioreq)
+static void ioreq_reset(XenQdiskRequest *request)
 {
-    memset(&ioreq->req, 0, sizeof(ioreq->req));
-    ioreq->status = 0;
-    ioreq->start = 0;
-    ioreq->buf = NULL;
-    ioreq->size = 0;
-    ioreq->presync = 0;
+    memset(&request->req, 0, sizeof(request->req));
+    request->status = 0;
+    request->start = 0;
+    request->buf = NULL;
+    request->size = 0;
+    request->presync = 0;
 
-    ioreq->aio_inflight = 0;
-    ioreq->aio_errors = 0;
+    request->aio_inflight = 0;
+    request->aio_errors = 0;
 
-    ioreq->dataplane = NULL;
-    memset(&ioreq->list, 0, sizeof(ioreq->list));
-    memset(&ioreq->acct, 0, sizeof(ioreq->acct));
+    request->dataplane = NULL;
+    memset(&request->list, 0, sizeof(request->list));
+    memset(&request->acct, 0, sizeof(request->acct));
 
-    qemu_iovec_reset(&ioreq->v);
+    qemu_iovec_reset(&request->v);
 }
 
-static struct ioreq *ioreq_start(XenQdiskDataPlane *dataplane)
+static XenQdiskRequest *ioreq_start(XenQdiskDataPlane *dataplane)
 {
-    struct ioreq *ioreq = NULL;
+    XenQdiskRequest *request = NULL;
 
     if (QLIST_EMPTY(&dataplane->freelist)) {
         if (dataplane->requests_total >= dataplane->max_requests) {
             goto out;
         }
         /* allocate new struct */
-        ioreq = g_malloc0(sizeof(*ioreq));
-        ioreq->dataplane = dataplane;
+        request = g_malloc0(sizeof(*request));
+        request->dataplane = dataplane;
         dataplane->requests_total++;
-        qemu_iovec_init(&ioreq->v, 1);
+        qemu_iovec_init(&request->v, 1);
     } else {
         /* get one from freelist */
-        ioreq = QLIST_FIRST(&dataplane->freelist);
-        QLIST_REMOVE(ioreq, list);
+        request = QLIST_FIRST(&dataplane->freelist);
+        QLIST_REMOVE(request, list);
     }
-    QLIST_INSERT_HEAD(&dataplane->inflight, ioreq, list);
+    QLIST_INSERT_HEAD(&dataplane->inflight, request, list);
     dataplane->requests_inflight++;
 
 out:
-    return ioreq;
+    return request;
 }
 
-static void ioreq_finish(struct ioreq *ioreq)
+static void ioreq_finish(XenQdiskRequest *request)
 {
-    XenQdiskDataPlane *dataplane = ioreq->dataplane;
+    XenQdiskDataPlane *dataplane = request->dataplane;
 
-    QLIST_REMOVE(ioreq, list);
-    QLIST_INSERT_HEAD(&dataplane->finished, ioreq, list);
+    QLIST_REMOVE(request, list);
+    QLIST_INSERT_HEAD(&dataplane->finished, request, list);
     dataplane->requests_inflight--;
     dataplane->requests_finished++;
 }
 
-static void ioreq_release(struct ioreq *ioreq, bool finish)
+static void ioreq_release(XenQdiskRequest *request, bool finish)
 {
-    XenQdiskDataPlane *dataplane = ioreq->dataplane;
+    XenQdiskDataPlane *dataplane = request->dataplane;
 
-    QLIST_REMOVE(ioreq, list);
-    ioreq_reset(ioreq);
-    ioreq->dataplane = dataplane;
-    QLIST_INSERT_HEAD(&dataplane->freelist, ioreq, list);
+    QLIST_REMOVE(request, list);
+    ioreq_reset(request);
+    request->dataplane = dataplane;
+    QLIST_INSERT_HEAD(&dataplane->freelist, request, list);
     if (finish) {
         dataplane->requests_finished--;
     } else {
@@ -130,18 +130,18 @@ static void ioreq_release(struct ioreq *ioreq, bool finish)
  * translate request into iovec + start offset
  * do sanity checks along the way
  */
-static int ioreq_parse(struct ioreq *ioreq)
+static int ioreq_parse(XenQdiskRequest *request)
 {
-    XenQdiskDataPlane *dataplane = ioreq->dataplane;
+    XenQdiskDataPlane *dataplane = request->dataplane;
     size_t len;
     int i;
 
-    switch (ioreq->req.operation) {
+    switch (request->req.operation) {
     case BLKIF_OP_READ:
         break;
     case BLKIF_OP_FLUSH_DISKCACHE:
-        ioreq->presync = 1;
-        if (!ioreq->req.nr_segments) {
+        request->presync = 1;
+        if (!request->req.nr_segments) {
             return 0;
         }
         /* fall through */
@@ -150,77 +150,78 @@ static int ioreq_parse(struct ioreq *ioreq)
     case BLKIF_OP_DISCARD:
         return 0;
     default:
-        error_report("error: unknown operation (%d)", ioreq->req.operation);
+        error_report("error: unknown operation (%d)", request->req.operation);
         goto err;
     };
 
-    if (ioreq->req.operation != BLKIF_OP_READ &&
+    if (request->req.operation != BLKIF_OP_READ &&
         blk_is_read_only(dataplane->blk)) {
         error_report("error: write req for ro device");
         goto err;
     }
 
-    ioreq->start = ioreq->req.sector_number * dataplane->file_blk;
-    for (i = 0; i < ioreq->req.nr_segments; i++) {
+    request->start = request->req.sector_number * dataplane->file_blk;
+    for (i = 0; i < request->req.nr_segments; i++) {
         if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
             error_report("error: nr_segments too big");
             goto err;
         }
-        if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) {
+        if (request->req.seg[i].first_sect > request->req.seg[i].last_sect) {
             error_report("error: first > last sector");
             goto err;
         }
-        if (ioreq->req.seg[i].last_sect * dataplane->file_blk >= XC_PAGE_SIZE) {
+        if (request->req.seg[i].last_sect * dataplane->file_blk >=
+            XC_PAGE_SIZE) {
             error_report("error: page crossing");
             goto err;
         }
 
-        len = (ioreq->req.seg[i].last_sect -
-               ioreq->req.seg[i].first_sect + 1) * dataplane->file_blk;
-        ioreq->size += len;
+        len = (request->req.seg[i].last_sect -
+               request->req.seg[i].first_sect + 1) * dataplane->file_blk;
+        request->size += len;
     }
-    if (ioreq->start + ioreq->size > dataplane->file_size) {
+    if (request->start + request->size > dataplane->file_size) {
         error_report("error: access beyond end of file");
         goto err;
     }
     return 0;
 
 err:
-    ioreq->status = BLKIF_RSP_ERROR;
+    request->status = BLKIF_RSP_ERROR;
     return -1;
 }
 
-static int ioreq_grant_copy(struct ioreq *ioreq)
+static int ioreq_grant_copy(XenQdiskRequest *request)
 {
-    XenQdiskDataPlane *dataplane = ioreq->dataplane;
+    XenQdiskDataPlane *dataplane = request->dataplane;
     XenDevice *xendev = dataplane->xendev;
     XenDeviceGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
     int i, count;
     int64_t file_blk = dataplane->file_blk;
-    bool to_domain = (ioreq->req.operation == BLKIF_OP_READ);
-    void *virt = ioreq->buf;
+    bool to_domain = (request->req.operation == BLKIF_OP_READ);
+    void *virt = request->buf;
     Error *local_err = NULL;
 
-    if (ioreq->req.nr_segments == 0) {
+    if (request->req.nr_segments == 0) {
         return 0;
     }
 
-    count = ioreq->req.nr_segments;
+    count = request->req.nr_segments;
 
     for (i = 0; i < count; i++) {
         if (to_domain) {
-            segs[i].dest.foreign.ref = ioreq->req.seg[i].gref;
-            segs[i].dest.foreign.offset = ioreq->req.seg[i].first_sect *
+            segs[i].dest.foreign.ref = request->req.seg[i].gref;
+            segs[i].dest.foreign.offset = request->req.seg[i].first_sect *
                 file_blk;
             segs[i].source.virt = virt;
         } else {
-            segs[i].source.foreign.ref = ioreq->req.seg[i].gref;
-            segs[i].source.foreign.offset = ioreq->req.seg[i].first_sect *
+            segs[i].source.foreign.ref = request->req.seg[i].gref;
+            segs[i].source.foreign.offset = request->req.seg[i].first_sect *
                 file_blk;
             segs[i].dest.virt = virt;
         }
-        segs[i].len = (ioreq->req.seg[i].last_sect -
-                       ioreq->req.seg[i].first_sect + 1) * file_blk;
+        segs[i].len = (request->req.seg[i].last_sect -
+                       request->req.seg[i].first_sect + 1) * file_blk;
         virt += segs[i].len;
     }
 
@@ -232,72 +233,72 @@ static int ioreq_grant_copy(struct ioreq *ioreq)
         error_report("failed to copy data: %s", msg);
         error_free(local_err);
 
-        ioreq->aio_errors++;
+        request->aio_errors++;
         return -1;
     }
 
     return 0;
 }
 
-static int ioreq_runio_qemu_aio(struct ioreq *ioreq);
+static int ioreq_runio_qemu_aio(XenQdiskRequest *request);
 
 static void qemu_aio_complete(void *opaque, int ret)
 {
-    struct ioreq *ioreq = opaque;
-    XenQdiskDataPlane *dataplane = ioreq->dataplane;
+    XenQdiskRequest *request = opaque;
+    XenQdiskDataPlane *dataplane = request->dataplane;
 
     aio_context_acquire(dataplane->ctx);
 
     if (ret != 0) {
         error_report("%s I/O error",
-                     ioreq->req.operation == BLKIF_OP_READ ?
+                     request->req.operation == BLKIF_OP_READ ?
                      "read" : "write");
-        ioreq->aio_errors++;
+        request->aio_errors++;
     }
 
-    ioreq->aio_inflight--;
-    if (ioreq->presync) {
-        ioreq->presync = 0;
-        ioreq_runio_qemu_aio(ioreq);
+    request->aio_inflight--;
+    if (request->presync) {
+        request->presync = 0;
+        ioreq_runio_qemu_aio(request);
         goto done;
     }
-    if (ioreq->aio_inflight > 0) {
+    if (request->aio_inflight > 0) {
         goto done;
     }
 
-    switch (ioreq->req.operation) {
+    switch (request->req.operation) {
     case BLKIF_OP_READ:
-        /* in case of failure ioreq->aio_errors is increased */
+        /* in case of failure request->aio_errors is increased */
         if (ret == 0) {
-            ioreq_grant_copy(ioreq);
+            ioreq_grant_copy(request);
         }
-        qemu_vfree(ioreq->buf);
+        qemu_vfree(request->buf);
         break;
     case BLKIF_OP_WRITE:
     case BLKIF_OP_FLUSH_DISKCACHE:
-        if (!ioreq->req.nr_segments) {
+        if (!request->req.nr_segments) {
             break;
         }
-        qemu_vfree(ioreq->buf);
+        qemu_vfree(request->buf);
         break;
     default:
         break;
     }
 
-    ioreq->status = ioreq->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY;
-    ioreq_finish(ioreq);
+    request->status = request->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY;
+    ioreq_finish(request);
 
-    switch (ioreq->req.operation) {
+    switch (request->req.operation) {
     case BLKIF_OP_WRITE:
     case BLKIF_OP_FLUSH_DISKCACHE:
-        if (!ioreq->req.nr_segments) {
+        if (!request->req.nr_segments) {
             break;
         }
     case BLKIF_OP_READ:
-        if (ioreq->status == BLKIF_RSP_OKAY) {
-            block_acct_done(blk_get_stats(dataplane->blk), &ioreq->acct);
+        if (request->status == BLKIF_RSP_OKAY) {
+            block_acct_done(blk_get_stats(dataplane->blk), &request->acct);
         } else {
-            block_acct_failed(blk_get_stats(dataplane->blk), &ioreq->acct);
+            block_acct_failed(blk_get_stats(dataplane->blk), &request->acct);
         }
         break;
     case BLKIF_OP_DISCARD:
@@ -310,10 +311,11 @@ done:
     aio_context_release(dataplane->ctx);
 }
 
-static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_number,
+static bool blk_split_discard(XenQdiskRequest *request,
+                              blkif_sector_t sector_number,
                               uint64_t nr_sectors)
 {
-    XenQdiskDataPlane *dataplane = ioreq->dataplane;
+    XenQdiskDataPlane *dataplane = request->dataplane;
     int64_t byte_offset;
     int byte_chunk;
     uint64_t byte_remaining, limit;
@@ -332,9 +334,9 @@ static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_number,
 
     do {
         byte_chunk = byte_remaining > limit ? limit : byte_remaining;
-        ioreq->aio_inflight++;
+        request->aio_inflight++;
         blk_aio_pdiscard(dataplane->blk, byte_offset, byte_chunk,
-                         qemu_aio_complete, ioreq);
+                         qemu_aio_complete, request);
         byte_remaining -= byte_chunk;
         byte_offset += byte_chunk;
     } while (byte_remaining > 0);
@@ -342,53 +344,53 @@ static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_number,
     return true;
 }
 
-static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
+static int ioreq_runio_qemu_aio(XenQdiskRequest *request)
 {
-    XenQdiskDataPlane *dataplane = ioreq->dataplane;
-
-    ioreq->buf = qemu_memalign(XC_PAGE_SIZE, ioreq->size);
-    if (ioreq->req.nr_segments &&
-        (ioreq->req.operation == BLKIF_OP_WRITE ||
-         ioreq->req.operation == BLKIF_OP_FLUSH_DISKCACHE) &&
-        ioreq_grant_copy(ioreq)) {
-        qemu_vfree(ioreq->buf);
+    XenQdiskDataPlane *dataplane = request->dataplane;
+
+    request->buf = qemu_memalign(XC_PAGE_SIZE, request->size);
+    if (request->req.nr_segments &&
+        (request->req.operation == BLKIF_OP_WRITE ||
+         request->req.operation == BLKIF_OP_FLUSH_DISKCACHE) &&
+        ioreq_grant_copy(request)) {
+        qemu_vfree(request->buf);
         goto err;
     }
 
-    ioreq->aio_inflight++;
-    if (ioreq->presync) {
-        blk_aio_flush(ioreq->dataplane->blk, qemu_aio_complete, ioreq);
+    request->aio_inflight++;
+    if (request->presync) {
+        blk_aio_flush(request->dataplane->blk, qemu_aio_complete, request);
         return 0;
     }
 
-    switch (ioreq->req.operation) {
+    switch (request->req.operation) {
     case BLKIF_OP_READ:
-        qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size);
-        block_acct_start(blk_get_stats(dataplane->blk), &ioreq->acct,
-                         ioreq->v.size, BLOCK_ACCT_READ);
-        ioreq->aio_inflight++;
-        blk_aio_preadv(dataplane->blk, ioreq->start, &ioreq->v, 0,
-                       qemu_aio_complete, ioreq);
+        qemu_iovec_add(&request->v, request->buf, request->size);
+        block_acct_start(blk_get_stats(dataplane->blk), &request->acct,
+                         request->v.size, BLOCK_ACCT_READ);
+        request->aio_inflight++;
+        blk_aio_preadv(dataplane->blk, request->start, &request->v, 0,
+                       qemu_aio_complete, request);
         break;
     case BLKIF_OP_WRITE:
     case BLKIF_OP_FLUSH_DISKCACHE:
-        if (!ioreq->req.nr_segments) {
+        if (!request->req.nr_segments) {
             break;
         }
 
-        qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size);
-        block_acct_start(blk_get_stats(dataplane->blk), &ioreq->acct,
-                         ioreq->v.size,
-                         ioreq->req.operation == BLKIF_OP_WRITE ?
+        qemu_iovec_add(&request->v, request->buf, request->size);
+        block_acct_start(blk_get_stats(dataplane->blk), &request->acct,
+                         request->v.size,
+                         request->req.operation == BLKIF_OP_WRITE ?
                          BLOCK_ACCT_WRITE : BLOCK_ACCT_FLUSH);
-        ioreq->aio_inflight++;
-        blk_aio_pwritev(dataplane->blk, ioreq->start, &ioreq->v, 0,
-                        qemu_aio_complete, ioreq);
+        request->aio_inflight++;
+        blk_aio_pwritev(dataplane->blk, request->start, &request->v, 0,
+                        qemu_aio_complete, request);
         break;
     case BLKIF_OP_DISCARD:
     {
-        struct blkif_request_discard *req = (void *)&ioreq->req;
-        if (!blk_split_discard(ioreq, req->sector_number, req->nr_sectors)) {
+        struct blkif_request_discard *req = (void *)&request->req;
+        if (!blk_split_discard(request, req->sector_number, req->nr_sectors)) {
             goto err;
         }
         break;
@@ -398,19 +400,19 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
         goto err;
     }
 
-    qemu_aio_complete(ioreq, 0);
+    qemu_aio_complete(request, 0);
 
     return 0;
 
 err:
-    ioreq_finish(ioreq);
-    ioreq->status = BLKIF_RSP_ERROR;
+    ioreq_finish(request);
+    request->status = BLKIF_RSP_ERROR;
     return -1;
 }
 
-static int blk_send_response_one(struct ioreq *ioreq)
+static int blk_send_response_one(XenQdiskRequest *request)
 {
-    XenQdiskDataPlane *dataplane = ioreq->dataplane;
+    XenQdiskDataPlane *dataplane = request->dataplane;
     int send_notify = 0;
     int have_requests = 0;
     blkif_response_t *resp;
@@ -436,9 +438,9 @@ static int blk_send_response_one(struct ioreq *ioreq)
         return 0;
     }
 
-    resp->id = ioreq->req.id;
-    resp->operation = ioreq->req.operation;
-    resp->status = ioreq->status;
+    resp->id = request->req.id;
+    resp->operation = request->req.operation;
+    resp->status = request->status;
 
     dataplane->rings.common.rsp_prod_pvt++;
 
@@ -466,13 +468,13 @@ static int blk_send_response_one(struct ioreq *ioreq)
 /* walk finished list, send outstanding responses, free requests */
 static void blk_send_response_all(XenQdiskDataPlane *dataplane)
 {
-    struct ioreq *ioreq;
+    XenQdiskRequest *request;
     int send_notify = 0;
 
     while (!QLIST_EMPTY(&dataplane->finished)) {
-        ioreq = QLIST_FIRST(&dataplane->finished);
-        send_notify += blk_send_response_one(ioreq);
-        ioreq_release(ioreq, true);
+        request = QLIST_FIRST(&dataplane->finished);
+        send_notify += blk_send_response_one(request);
+        ioreq_release(request, true);
     }
     if (send_notify) {
         xen_device_notify_event_channel(dataplane->xendev,
@@ -480,29 +482,29 @@ static void blk_send_response_all(XenQdiskDataPlane *dataplane)
     }
 }
 
-static int blk_get_request(XenQdiskDataPlane *dataplane, struct ioreq *ioreq,
-                           RING_IDX rc)
+static int blk_get_request(XenQdiskDataPlane *dataplane,
+                           XenQdiskRequest *request, RING_IDX rc)
 {
     switch (dataplane->protocol) {
     case BLKIF_PROTOCOL_NATIVE: {
         blkif_request_t *req =
             RING_GET_REQUEST(&dataplane->rings.native, rc);
 
-        memcpy(&ioreq->req, req, sizeof(ioreq->req));
+        memcpy(&request->req, req, sizeof(request->req));
         break;
     }
     case BLKIF_PROTOCOL_X86_32: {
         blkif_x86_32_request_t *req =
             RING_GET_REQUEST(&dataplane->rings.x86_32_part, rc);
 
-        blkif_get_x86_32_req(&ioreq->req, req);
+        blkif_get_x86_32_req(&request->req, req);
         break;
     }
     case BLKIF_PROTOCOL_X86_64: {
         blkif_x86_64_request_t *req =
             RING_GET_REQUEST(&dataplane->rings.x86_64_part, rc);
 
-        blkif_get_x86_64_req(&ioreq->req, req);
+        blkif_get_x86_64_req(&request->req, req);
         break;
     }
     }
@@ -514,7 +516,7 @@ static int blk_get_request(XenQdiskDataPlane *dataplane, struct ioreq *ioreq,
 static void blk_handle_requests(XenQdiskDataPlane *dataplane)
 {
     RING_IDX rc, rp;
-    struct ioreq *ioreq;
+    XenQdiskRequest *request;
 
     dataplane->more_work = 0;
 
@@ -528,18 +530,18 @@ static void blk_handle_requests(XenQdiskDataPlane *dataplane)
         if (RING_REQUEST_CONS_OVERFLOW(&dataplane->rings.common, rc)) {
             break;
         }
-        ioreq = ioreq_start(dataplane);
-        if (ioreq == NULL) {
+        request = ioreq_start(dataplane);
+        if (request == NULL) {
             dataplane->more_work++;
             break;
         }
-        blk_get_request(dataplane, ioreq, rc);
+        blk_get_request(dataplane, request, rc);
         dataplane->rings.common.req_cons = ++rc;
 
         /* parse them */
-        if (ioreq_parse(ioreq) != 0) {
+        if (ioreq_parse(request) != 0) {
 
-            switch (ioreq->req.operation) {
+            switch (request->req.operation) {
             case BLKIF_OP_READ:
                 block_acct_invalid(blk_get_stats(dataplane->blk),
                                    BLOCK_ACCT_READ);
@@ -555,15 +557,15 @@ static void blk_handle_requests(XenQdiskDataPlane *dataplane)
                 break;
             };
 
-            if (blk_send_response_one(ioreq)) {
+            if (blk_send_response_one(request)) {
                 xen_device_notify_event_channel(dataplane->xendev,
                                                 dataplane->event_channel);
             }
-            ioreq_release(ioreq, false);
+            ioreq_release(request, false);
             continue;
         }
 
-        ioreq_runio_qemu_aio(ioreq);
+        ioreq_runio_qemu_aio(request);
     }
 
     if (dataplane->more_work &&
@@ -617,17 +619,17 @@ XenQdiskDataPlane *xen_qdisk_dataplane_create(XenDevice *xendev,
 
 void xen_qdisk_dataplane_destroy(XenQdiskDataPlane *dataplane)
 {
-    struct ioreq *ioreq;
+    XenQdiskRequest *request;
 
     if (!dataplane) {
         return;
     }
 
     while (!QLIST_EMPTY(&dataplane->freelist)) {
-        ioreq = QLIST_FIRST(&dataplane->freelist);
-        QLIST_REMOVE(ioreq, list);
-        qemu_iovec_destroy(&ioreq->v);
-        g_free(ioreq);
+        request = QLIST_FIRST(&dataplane->freelist);
+        QLIST_REMOVE(request, list);
+        qemu_iovec_destroy(&request->v);
+        g_free(request);
     }
 
     qemu_bh_delete(dataplane->bh);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [PATCH 12/18] xen: remove 'ioreq' struct/varable/field names from dataplane/xen-qdisk.c
@ 2018-11-21 15:12   ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Kevin Wolf, Stefano Stabellini, Max Reitz, Paul Durrant,
	Stefan Hajnoczi, Anthony Perard

This is a purely cosmetic patch that purges the name 'ioreq' from struct,
variable and field names. (This name has been problematic for a long time
as 'ioreq' is the name used for generic I/O requests coming from Xen).
The patch replaces 'struct ioreq' with a new 'XenQdiskRequest' type and
'ioreq' field/variable names with 'request', and then does necessary
fix-up to adhere to coding style.

Function names are not modified by this patch. Yhey will be dealt with in
a subsequent patch.

No functional change.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
---
 hw/block/dataplane/xen-qdisk.c | 310 +++++++++++++++++++++--------------------
 1 file changed, 156 insertions(+), 154 deletions(-)

diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-qdisk.c
index 2214455ff9..50a48b6f5f 100644
--- a/hw/block/dataplane/xen-qdisk.c
+++ b/hw/block/dataplane/xen-qdisk.c
@@ -18,7 +18,7 @@
 #include "sysemu/iothread.h"
 #include "xen-qdisk.h"
 
-struct ioreq {
+typedef struct XenQdiskRequest {
     blkif_request_t req;
     int16_t status;
     off_t start;
@@ -29,9 +29,9 @@ struct ioreq {
     int aio_inflight;
     int aio_errors;
     XenQdiskDataPlane *dataplane;
-    QLIST_ENTRY(ioreq) list;
+    QLIST_ENTRY(XenQdiskRequest) list;
     BlockAcctCookie acct;
-};
+} XenQdiskRequest;
 
 struct XenQdiskDataPlane {
     XenDevice *xendev;
@@ -44,9 +44,9 @@ struct XenQdiskDataPlane {
     int protocol;
     blkif_back_rings_t rings;
     int more_work;
-    QLIST_HEAD(inflight_head, ioreq) inflight;
-    QLIST_HEAD(finished_head, ioreq) finished;
-    QLIST_HEAD(freelist_head, ioreq) freelist;
+    QLIST_HEAD(inflight_head, XenQdiskRequest) inflight;
+    QLIST_HEAD(finished_head, XenQdiskRequest) finished;
+    QLIST_HEAD(freelist_head, XenQdiskRequest) freelist;
     int requests_total;
     int requests_inflight;
     int requests_finished;
@@ -57,68 +57,68 @@ struct XenQdiskDataPlane {
     AioContext *ctx;
 };
 
-static void ioreq_reset(struct ioreq *ioreq)
+static void ioreq_reset(XenQdiskRequest *request)
 {
-    memset(&ioreq->req, 0, sizeof(ioreq->req));
-    ioreq->status = 0;
-    ioreq->start = 0;
-    ioreq->buf = NULL;
-    ioreq->size = 0;
-    ioreq->presync = 0;
+    memset(&request->req, 0, sizeof(request->req));
+    request->status = 0;
+    request->start = 0;
+    request->buf = NULL;
+    request->size = 0;
+    request->presync = 0;
 
-    ioreq->aio_inflight = 0;
-    ioreq->aio_errors = 0;
+    request->aio_inflight = 0;
+    request->aio_errors = 0;
 
-    ioreq->dataplane = NULL;
-    memset(&ioreq->list, 0, sizeof(ioreq->list));
-    memset(&ioreq->acct, 0, sizeof(ioreq->acct));
+    request->dataplane = NULL;
+    memset(&request->list, 0, sizeof(request->list));
+    memset(&request->acct, 0, sizeof(request->acct));
 
-    qemu_iovec_reset(&ioreq->v);
+    qemu_iovec_reset(&request->v);
 }
 
-static struct ioreq *ioreq_start(XenQdiskDataPlane *dataplane)
+static XenQdiskRequest *ioreq_start(XenQdiskDataPlane *dataplane)
 {
-    struct ioreq *ioreq = NULL;
+    XenQdiskRequest *request = NULL;
 
     if (QLIST_EMPTY(&dataplane->freelist)) {
         if (dataplane->requests_total >= dataplane->max_requests) {
             goto out;
         }
         /* allocate new struct */
-        ioreq = g_malloc0(sizeof(*ioreq));
-        ioreq->dataplane = dataplane;
+        request = g_malloc0(sizeof(*request));
+        request->dataplane = dataplane;
         dataplane->requests_total++;
-        qemu_iovec_init(&ioreq->v, 1);
+        qemu_iovec_init(&request->v, 1);
     } else {
         /* get one from freelist */
-        ioreq = QLIST_FIRST(&dataplane->freelist);
-        QLIST_REMOVE(ioreq, list);
+        request = QLIST_FIRST(&dataplane->freelist);
+        QLIST_REMOVE(request, list);
     }
-    QLIST_INSERT_HEAD(&dataplane->inflight, ioreq, list);
+    QLIST_INSERT_HEAD(&dataplane->inflight, request, list);
     dataplane->requests_inflight++;
 
 out:
-    return ioreq;
+    return request;
 }
 
-static void ioreq_finish(struct ioreq *ioreq)
+static void ioreq_finish(XenQdiskRequest *request)
 {
-    XenQdiskDataPlane *dataplane = ioreq->dataplane;
+    XenQdiskDataPlane *dataplane = request->dataplane;
 
-    QLIST_REMOVE(ioreq, list);
-    QLIST_INSERT_HEAD(&dataplane->finished, ioreq, list);
+    QLIST_REMOVE(request, list);
+    QLIST_INSERT_HEAD(&dataplane->finished, request, list);
     dataplane->requests_inflight--;
     dataplane->requests_finished++;
 }
 
-static void ioreq_release(struct ioreq *ioreq, bool finish)
+static void ioreq_release(XenQdiskRequest *request, bool finish)
 {
-    XenQdiskDataPlane *dataplane = ioreq->dataplane;
+    XenQdiskDataPlane *dataplane = request->dataplane;
 
-    QLIST_REMOVE(ioreq, list);
-    ioreq_reset(ioreq);
-    ioreq->dataplane = dataplane;
-    QLIST_INSERT_HEAD(&dataplane->freelist, ioreq, list);
+    QLIST_REMOVE(request, list);
+    ioreq_reset(request);
+    request->dataplane = dataplane;
+    QLIST_INSERT_HEAD(&dataplane->freelist, request, list);
     if (finish) {
         dataplane->requests_finished--;
     } else {
@@ -130,18 +130,18 @@ static void ioreq_release(struct ioreq *ioreq, bool finish)
  * translate request into iovec + start offset
  * do sanity checks along the way
  */
-static int ioreq_parse(struct ioreq *ioreq)
+static int ioreq_parse(XenQdiskRequest *request)
 {
-    XenQdiskDataPlane *dataplane = ioreq->dataplane;
+    XenQdiskDataPlane *dataplane = request->dataplane;
     size_t len;
     int i;
 
-    switch (ioreq->req.operation) {
+    switch (request->req.operation) {
     case BLKIF_OP_READ:
         break;
     case BLKIF_OP_FLUSH_DISKCACHE:
-        ioreq->presync = 1;
-        if (!ioreq->req.nr_segments) {
+        request->presync = 1;
+        if (!request->req.nr_segments) {
             return 0;
         }
         /* fall through */
@@ -150,77 +150,78 @@ static int ioreq_parse(struct ioreq *ioreq)
     case BLKIF_OP_DISCARD:
         return 0;
     default:
-        error_report("error: unknown operation (%d)", ioreq->req.operation);
+        error_report("error: unknown operation (%d)", request->req.operation);
         goto err;
     };
 
-    if (ioreq->req.operation != BLKIF_OP_READ &&
+    if (request->req.operation != BLKIF_OP_READ &&
         blk_is_read_only(dataplane->blk)) {
         error_report("error: write req for ro device");
         goto err;
     }
 
-    ioreq->start = ioreq->req.sector_number * dataplane->file_blk;
-    for (i = 0; i < ioreq->req.nr_segments; i++) {
+    request->start = request->req.sector_number * dataplane->file_blk;
+    for (i = 0; i < request->req.nr_segments; i++) {
         if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
             error_report("error: nr_segments too big");
             goto err;
         }
-        if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) {
+        if (request->req.seg[i].first_sect > request->req.seg[i].last_sect) {
             error_report("error: first > last sector");
             goto err;
         }
-        if (ioreq->req.seg[i].last_sect * dataplane->file_blk >= XC_PAGE_SIZE) {
+        if (request->req.seg[i].last_sect * dataplane->file_blk >=
+            XC_PAGE_SIZE) {
             error_report("error: page crossing");
             goto err;
         }
 
-        len = (ioreq->req.seg[i].last_sect -
-               ioreq->req.seg[i].first_sect + 1) * dataplane->file_blk;
-        ioreq->size += len;
+        len = (request->req.seg[i].last_sect -
+               request->req.seg[i].first_sect + 1) * dataplane->file_blk;
+        request->size += len;
     }
-    if (ioreq->start + ioreq->size > dataplane->file_size) {
+    if (request->start + request->size > dataplane->file_size) {
         error_report("error: access beyond end of file");
         goto err;
     }
     return 0;
 
 err:
-    ioreq->status = BLKIF_RSP_ERROR;
+    request->status = BLKIF_RSP_ERROR;
     return -1;
 }
 
-static int ioreq_grant_copy(struct ioreq *ioreq)
+static int ioreq_grant_copy(XenQdiskRequest *request)
 {
-    XenQdiskDataPlane *dataplane = ioreq->dataplane;
+    XenQdiskDataPlane *dataplane = request->dataplane;
     XenDevice *xendev = dataplane->xendev;
     XenDeviceGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
     int i, count;
     int64_t file_blk = dataplane->file_blk;
-    bool to_domain = (ioreq->req.operation == BLKIF_OP_READ);
-    void *virt = ioreq->buf;
+    bool to_domain = (request->req.operation == BLKIF_OP_READ);
+    void *virt = request->buf;
     Error *local_err = NULL;
 
-    if (ioreq->req.nr_segments == 0) {
+    if (request->req.nr_segments == 0) {
         return 0;
     }
 
-    count = ioreq->req.nr_segments;
+    count = request->req.nr_segments;
 
     for (i = 0; i < count; i++) {
         if (to_domain) {
-            segs[i].dest.foreign.ref = ioreq->req.seg[i].gref;
-            segs[i].dest.foreign.offset = ioreq->req.seg[i].first_sect *
+            segs[i].dest.foreign.ref = request->req.seg[i].gref;
+            segs[i].dest.foreign.offset = request->req.seg[i].first_sect *
                 file_blk;
             segs[i].source.virt = virt;
         } else {
-            segs[i].source.foreign.ref = ioreq->req.seg[i].gref;
-            segs[i].source.foreign.offset = ioreq->req.seg[i].first_sect *
+            segs[i].source.foreign.ref = request->req.seg[i].gref;
+            segs[i].source.foreign.offset = request->req.seg[i].first_sect *
                 file_blk;
             segs[i].dest.virt = virt;
         }
-        segs[i].len = (ioreq->req.seg[i].last_sect -
-                       ioreq->req.seg[i].first_sect + 1) * file_blk;
+        segs[i].len = (request->req.seg[i].last_sect -
+                       request->req.seg[i].first_sect + 1) * file_blk;
         virt += segs[i].len;
     }
 
@@ -232,72 +233,72 @@ static int ioreq_grant_copy(struct ioreq *ioreq)
         error_report("failed to copy data: %s", msg);
         error_free(local_err);
 
-        ioreq->aio_errors++;
+        request->aio_errors++;
         return -1;
     }
 
     return 0;
 }
 
-static int ioreq_runio_qemu_aio(struct ioreq *ioreq);
+static int ioreq_runio_qemu_aio(XenQdiskRequest *request);
 
 static void qemu_aio_complete(void *opaque, int ret)
 {
-    struct ioreq *ioreq = opaque;
-    XenQdiskDataPlane *dataplane = ioreq->dataplane;
+    XenQdiskRequest *request = opaque;
+    XenQdiskDataPlane *dataplane = request->dataplane;
 
     aio_context_acquire(dataplane->ctx);
 
     if (ret != 0) {
         error_report("%s I/O error",
-                     ioreq->req.operation == BLKIF_OP_READ ?
+                     request->req.operation == BLKIF_OP_READ ?
                      "read" : "write");
-        ioreq->aio_errors++;
+        request->aio_errors++;
     }
 
-    ioreq->aio_inflight--;
-    if (ioreq->presync) {
-        ioreq->presync = 0;
-        ioreq_runio_qemu_aio(ioreq);
+    request->aio_inflight--;
+    if (request->presync) {
+        request->presync = 0;
+        ioreq_runio_qemu_aio(request);
         goto done;
     }
-    if (ioreq->aio_inflight > 0) {
+    if (request->aio_inflight > 0) {
         goto done;
     }
 
-    switch (ioreq->req.operation) {
+    switch (request->req.operation) {
     case BLKIF_OP_READ:
-        /* in case of failure ioreq->aio_errors is increased */
+        /* in case of failure request->aio_errors is increased */
         if (ret == 0) {
-            ioreq_grant_copy(ioreq);
+            ioreq_grant_copy(request);
         }
-        qemu_vfree(ioreq->buf);
+        qemu_vfree(request->buf);
         break;
     case BLKIF_OP_WRITE:
     case BLKIF_OP_FLUSH_DISKCACHE:
-        if (!ioreq->req.nr_segments) {
+        if (!request->req.nr_segments) {
             break;
         }
-        qemu_vfree(ioreq->buf);
+        qemu_vfree(request->buf);
         break;
     default:
         break;
     }
 
-    ioreq->status = ioreq->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY;
-    ioreq_finish(ioreq);
+    request->status = request->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY;
+    ioreq_finish(request);
 
-    switch (ioreq->req.operation) {
+    switch (request->req.operation) {
     case BLKIF_OP_WRITE:
     case BLKIF_OP_FLUSH_DISKCACHE:
-        if (!ioreq->req.nr_segments) {
+        if (!request->req.nr_segments) {
             break;
         }
     case BLKIF_OP_READ:
-        if (ioreq->status == BLKIF_RSP_OKAY) {
-            block_acct_done(blk_get_stats(dataplane->blk), &ioreq->acct);
+        if (request->status == BLKIF_RSP_OKAY) {
+            block_acct_done(blk_get_stats(dataplane->blk), &request->acct);
         } else {
-            block_acct_failed(blk_get_stats(dataplane->blk), &ioreq->acct);
+            block_acct_failed(blk_get_stats(dataplane->blk), &request->acct);
         }
         break;
     case BLKIF_OP_DISCARD:
@@ -310,10 +311,11 @@ done:
     aio_context_release(dataplane->ctx);
 }
 
-static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_number,
+static bool blk_split_discard(XenQdiskRequest *request,
+                              blkif_sector_t sector_number,
                               uint64_t nr_sectors)
 {
-    XenQdiskDataPlane *dataplane = ioreq->dataplane;
+    XenQdiskDataPlane *dataplane = request->dataplane;
     int64_t byte_offset;
     int byte_chunk;
     uint64_t byte_remaining, limit;
@@ -332,9 +334,9 @@ static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_number,
 
     do {
         byte_chunk = byte_remaining > limit ? limit : byte_remaining;
-        ioreq->aio_inflight++;
+        request->aio_inflight++;
         blk_aio_pdiscard(dataplane->blk, byte_offset, byte_chunk,
-                         qemu_aio_complete, ioreq);
+                         qemu_aio_complete, request);
         byte_remaining -= byte_chunk;
         byte_offset += byte_chunk;
     } while (byte_remaining > 0);
@@ -342,53 +344,53 @@ static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_number,
     return true;
 }
 
-static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
+static int ioreq_runio_qemu_aio(XenQdiskRequest *request)
 {
-    XenQdiskDataPlane *dataplane = ioreq->dataplane;
-
-    ioreq->buf = qemu_memalign(XC_PAGE_SIZE, ioreq->size);
-    if (ioreq->req.nr_segments &&
-        (ioreq->req.operation == BLKIF_OP_WRITE ||
-         ioreq->req.operation == BLKIF_OP_FLUSH_DISKCACHE) &&
-        ioreq_grant_copy(ioreq)) {
-        qemu_vfree(ioreq->buf);
+    XenQdiskDataPlane *dataplane = request->dataplane;
+
+    request->buf = qemu_memalign(XC_PAGE_SIZE, request->size);
+    if (request->req.nr_segments &&
+        (request->req.operation == BLKIF_OP_WRITE ||
+         request->req.operation == BLKIF_OP_FLUSH_DISKCACHE) &&
+        ioreq_grant_copy(request)) {
+        qemu_vfree(request->buf);
         goto err;
     }
 
-    ioreq->aio_inflight++;
-    if (ioreq->presync) {
-        blk_aio_flush(ioreq->dataplane->blk, qemu_aio_complete, ioreq);
+    request->aio_inflight++;
+    if (request->presync) {
+        blk_aio_flush(request->dataplane->blk, qemu_aio_complete, request);
         return 0;
     }
 
-    switch (ioreq->req.operation) {
+    switch (request->req.operation) {
     case BLKIF_OP_READ:
-        qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size);
-        block_acct_start(blk_get_stats(dataplane->blk), &ioreq->acct,
-                         ioreq->v.size, BLOCK_ACCT_READ);
-        ioreq->aio_inflight++;
-        blk_aio_preadv(dataplane->blk, ioreq->start, &ioreq->v, 0,
-                       qemu_aio_complete, ioreq);
+        qemu_iovec_add(&request->v, request->buf, request->size);
+        block_acct_start(blk_get_stats(dataplane->blk), &request->acct,
+                         request->v.size, BLOCK_ACCT_READ);
+        request->aio_inflight++;
+        blk_aio_preadv(dataplane->blk, request->start, &request->v, 0,
+                       qemu_aio_complete, request);
         break;
     case BLKIF_OP_WRITE:
     case BLKIF_OP_FLUSH_DISKCACHE:
-        if (!ioreq->req.nr_segments) {
+        if (!request->req.nr_segments) {
             break;
         }
 
-        qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size);
-        block_acct_start(blk_get_stats(dataplane->blk), &ioreq->acct,
-                         ioreq->v.size,
-                         ioreq->req.operation == BLKIF_OP_WRITE ?
+        qemu_iovec_add(&request->v, request->buf, request->size);
+        block_acct_start(blk_get_stats(dataplane->blk), &request->acct,
+                         request->v.size,
+                         request->req.operation == BLKIF_OP_WRITE ?
                          BLOCK_ACCT_WRITE : BLOCK_ACCT_FLUSH);
-        ioreq->aio_inflight++;
-        blk_aio_pwritev(dataplane->blk, ioreq->start, &ioreq->v, 0,
-                        qemu_aio_complete, ioreq);
+        request->aio_inflight++;
+        blk_aio_pwritev(dataplane->blk, request->start, &request->v, 0,
+                        qemu_aio_complete, request);
         break;
     case BLKIF_OP_DISCARD:
     {
-        struct blkif_request_discard *req = (void *)&ioreq->req;
-        if (!blk_split_discard(ioreq, req->sector_number, req->nr_sectors)) {
+        struct blkif_request_discard *req = (void *)&request->req;
+        if (!blk_split_discard(request, req->sector_number, req->nr_sectors)) {
             goto err;
         }
         break;
@@ -398,19 +400,19 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
         goto err;
     }
 
-    qemu_aio_complete(ioreq, 0);
+    qemu_aio_complete(request, 0);
 
     return 0;
 
 err:
-    ioreq_finish(ioreq);
-    ioreq->status = BLKIF_RSP_ERROR;
+    ioreq_finish(request);
+    request->status = BLKIF_RSP_ERROR;
     return -1;
 }
 
-static int blk_send_response_one(struct ioreq *ioreq)
+static int blk_send_response_one(XenQdiskRequest *request)
 {
-    XenQdiskDataPlane *dataplane = ioreq->dataplane;
+    XenQdiskDataPlane *dataplane = request->dataplane;
     int send_notify = 0;
     int have_requests = 0;
     blkif_response_t *resp;
@@ -436,9 +438,9 @@ static int blk_send_response_one(struct ioreq *ioreq)
         return 0;
     }
 
-    resp->id = ioreq->req.id;
-    resp->operation = ioreq->req.operation;
-    resp->status = ioreq->status;
+    resp->id = request->req.id;
+    resp->operation = request->req.operation;
+    resp->status = request->status;
 
     dataplane->rings.common.rsp_prod_pvt++;
 
@@ -466,13 +468,13 @@ static int blk_send_response_one(struct ioreq *ioreq)
 /* walk finished list, send outstanding responses, free requests */
 static void blk_send_response_all(XenQdiskDataPlane *dataplane)
 {
-    struct ioreq *ioreq;
+    XenQdiskRequest *request;
     int send_notify = 0;
 
     while (!QLIST_EMPTY(&dataplane->finished)) {
-        ioreq = QLIST_FIRST(&dataplane->finished);
-        send_notify += blk_send_response_one(ioreq);
-        ioreq_release(ioreq, true);
+        request = QLIST_FIRST(&dataplane->finished);
+        send_notify += blk_send_response_one(request);
+        ioreq_release(request, true);
     }
     if (send_notify) {
         xen_device_notify_event_channel(dataplane->xendev,
@@ -480,29 +482,29 @@ static void blk_send_response_all(XenQdiskDataPlane *dataplane)
     }
 }
 
-static int blk_get_request(XenQdiskDataPlane *dataplane, struct ioreq *ioreq,
-                           RING_IDX rc)
+static int blk_get_request(XenQdiskDataPlane *dataplane,
+                           XenQdiskRequest *request, RING_IDX rc)
 {
     switch (dataplane->protocol) {
     case BLKIF_PROTOCOL_NATIVE: {
         blkif_request_t *req =
             RING_GET_REQUEST(&dataplane->rings.native, rc);
 
-        memcpy(&ioreq->req, req, sizeof(ioreq->req));
+        memcpy(&request->req, req, sizeof(request->req));
         break;
     }
     case BLKIF_PROTOCOL_X86_32: {
         blkif_x86_32_request_t *req =
             RING_GET_REQUEST(&dataplane->rings.x86_32_part, rc);
 
-        blkif_get_x86_32_req(&ioreq->req, req);
+        blkif_get_x86_32_req(&request->req, req);
         break;
     }
     case BLKIF_PROTOCOL_X86_64: {
         blkif_x86_64_request_t *req =
             RING_GET_REQUEST(&dataplane->rings.x86_64_part, rc);
 
-        blkif_get_x86_64_req(&ioreq->req, req);
+        blkif_get_x86_64_req(&request->req, req);
         break;
     }
     }
@@ -514,7 +516,7 @@ static int blk_get_request(XenQdiskDataPlane *dataplane, struct ioreq *ioreq,
 static void blk_handle_requests(XenQdiskDataPlane *dataplane)
 {
     RING_IDX rc, rp;
-    struct ioreq *ioreq;
+    XenQdiskRequest *request;
 
     dataplane->more_work = 0;
 
@@ -528,18 +530,18 @@ static void blk_handle_requests(XenQdiskDataPlane *dataplane)
         if (RING_REQUEST_CONS_OVERFLOW(&dataplane->rings.common, rc)) {
             break;
         }
-        ioreq = ioreq_start(dataplane);
-        if (ioreq == NULL) {
+        request = ioreq_start(dataplane);
+        if (request == NULL) {
             dataplane->more_work++;
             break;
         }
-        blk_get_request(dataplane, ioreq, rc);
+        blk_get_request(dataplane, request, rc);
         dataplane->rings.common.req_cons = ++rc;
 
         /* parse them */
-        if (ioreq_parse(ioreq) != 0) {
+        if (ioreq_parse(request) != 0) {
 
-            switch (ioreq->req.operation) {
+            switch (request->req.operation) {
             case BLKIF_OP_READ:
                 block_acct_invalid(blk_get_stats(dataplane->blk),
                                    BLOCK_ACCT_READ);
@@ -555,15 +557,15 @@ static void blk_handle_requests(XenQdiskDataPlane *dataplane)
                 break;
             };
 
-            if (blk_send_response_one(ioreq)) {
+            if (blk_send_response_one(request)) {
                 xen_device_notify_event_channel(dataplane->xendev,
                                                 dataplane->event_channel);
             }
-            ioreq_release(ioreq, false);
+            ioreq_release(request, false);
             continue;
         }
 
-        ioreq_runio_qemu_aio(ioreq);
+        ioreq_runio_qemu_aio(request);
     }
 
     if (dataplane->more_work &&
@@ -617,17 +619,17 @@ XenQdiskDataPlane *xen_qdisk_dataplane_create(XenDevice *xendev,
 
 void xen_qdisk_dataplane_destroy(XenQdiskDataPlane *dataplane)
 {
-    struct ioreq *ioreq;
+    XenQdiskRequest *request;
 
     if (!dataplane) {
         return;
     }
 
     while (!QLIST_EMPTY(&dataplane->freelist)) {
-        ioreq = QLIST_FIRST(&dataplane->freelist);
-        QLIST_REMOVE(ioreq, list);
-        qemu_iovec_destroy(&ioreq->v);
-        g_free(ioreq);
+        request = QLIST_FIRST(&dataplane->freelist);
+        QLIST_REMOVE(request, list);
+        qemu_iovec_destroy(&request->v);
+        g_free(request);
     }
 
     qemu_bh_delete(dataplane->bh);
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [Qemu-devel] [PATCH 13/18] xen: purge 'blk' and 'ioreq' from function names in dataplane/xen-qdisk.c
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
@ 2018-11-21 15:12   ` Paul Durrant
  2018-11-21 15:11 ` [Qemu-devel] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy Paul Durrant
                     ` (24 subsequent siblings)
  25 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Paul Durrant, Stefano Stabellini, Anthony Perard,
	Stefan Hajnoczi, Kevin Wolf, Max Reitz

This is a purely cosmetic patch that purges remaining use of 'blk' and
'ioreq' in local function names.

No functional change.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
---
 hw/block/dataplane/xen-qdisk.c | 86 +++++++++++++++++++++---------------------
 1 file changed, 43 insertions(+), 43 deletions(-)

diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-qdisk.c
index 50a48b6f5f..94785eeff3 100644
--- a/hw/block/dataplane/xen-qdisk.c
+++ b/hw/block/dataplane/xen-qdisk.c
@@ -57,7 +57,7 @@ struct XenQdiskDataPlane {
     AioContext *ctx;
 };
 
-static void ioreq_reset(XenQdiskRequest *request)
+static void reset_request(XenQdiskRequest *request)
 {
     memset(&request->req, 0, sizeof(request->req));
     request->status = 0;
@@ -76,7 +76,7 @@ static void ioreq_reset(XenQdiskRequest *request)
     qemu_iovec_reset(&request->v);
 }
 
-static XenQdiskRequest *ioreq_start(XenQdiskDataPlane *dataplane)
+static XenQdiskRequest *start_request(XenQdiskDataPlane *dataplane)
 {
     XenQdiskRequest *request = NULL;
 
@@ -101,7 +101,7 @@ out:
     return request;
 }
 
-static void ioreq_finish(XenQdiskRequest *request)
+static void finish_request(XenQdiskRequest *request)
 {
     XenQdiskDataPlane *dataplane = request->dataplane;
 
@@ -111,12 +111,12 @@ static void ioreq_finish(XenQdiskRequest *request)
     dataplane->requests_finished++;
 }
 
-static void ioreq_release(XenQdiskRequest *request, bool finish)
+static void release_request(XenQdiskRequest *request, bool finish)
 {
     XenQdiskDataPlane *dataplane = request->dataplane;
 
     QLIST_REMOVE(request, list);
-    ioreq_reset(request);
+    reset_request(request);
     request->dataplane = dataplane;
     QLIST_INSERT_HEAD(&dataplane->freelist, request, list);
     if (finish) {
@@ -130,7 +130,7 @@ static void ioreq_release(XenQdiskRequest *request, bool finish)
  * translate request into iovec + start offset
  * do sanity checks along the way
  */
-static int ioreq_parse(XenQdiskRequest *request)
+static int parse_request(XenQdiskRequest *request)
 {
     XenQdiskDataPlane *dataplane = request->dataplane;
     size_t len;
@@ -191,7 +191,7 @@ err:
     return -1;
 }
 
-static int ioreq_grant_copy(XenQdiskRequest *request)
+static int copy_request(XenQdiskRequest *request)
 {
     XenQdiskDataPlane *dataplane = request->dataplane;
     XenDevice *xendev = dataplane->xendev;
@@ -240,9 +240,9 @@ static int ioreq_grant_copy(XenQdiskRequest *request)
     return 0;
 }
 
-static int ioreq_runio_qemu_aio(XenQdiskRequest *request);
+static int do_aio(XenQdiskRequest *request);
 
-static void qemu_aio_complete(void *opaque, int ret)
+static void complete_aio(void *opaque, int ret)
 {
     XenQdiskRequest *request = opaque;
     XenQdiskDataPlane *dataplane = request->dataplane;
@@ -259,7 +259,7 @@ static void qemu_aio_complete(void *opaque, int ret)
     request->aio_inflight--;
     if (request->presync) {
         request->presync = 0;
-        ioreq_runio_qemu_aio(request);
+        do_aio(request);
         goto done;
     }
     if (request->aio_inflight > 0) {
@@ -270,7 +270,7 @@ static void qemu_aio_complete(void *opaque, int ret)
     case BLKIF_OP_READ:
         /* in case of failure request->aio_errors is increased */
         if (ret == 0) {
-            ioreq_grant_copy(request);
+            copy_request(request);
         }
         qemu_vfree(request->buf);
         break;
@@ -286,7 +286,7 @@ static void qemu_aio_complete(void *opaque, int ret)
     }
 
     request->status = request->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY;
-    ioreq_finish(request);
+    finish_request(request);
 
     switch (request->req.operation) {
     case BLKIF_OP_WRITE:
@@ -311,9 +311,8 @@ done:
     aio_context_release(dataplane->ctx);
 }
 
-static bool blk_split_discard(XenQdiskRequest *request,
-                              blkif_sector_t sector_number,
-                              uint64_t nr_sectors)
+static bool split_discard(XenQdiskRequest *request,
+                          blkif_sector_t sector_number, uint64_t nr_sectors)
 {
     XenQdiskDataPlane *dataplane = request->dataplane;
     int64_t byte_offset;
@@ -336,7 +335,7 @@ static bool blk_split_discard(XenQdiskRequest *request,
         byte_chunk = byte_remaining > limit ? limit : byte_remaining;
         request->aio_inflight++;
         blk_aio_pdiscard(dataplane->blk, byte_offset, byte_chunk,
-                         qemu_aio_complete, request);
+                         complete_aio, request);
         byte_remaining -= byte_chunk;
         byte_offset += byte_chunk;
     } while (byte_remaining > 0);
@@ -344,7 +343,7 @@ static bool blk_split_discard(XenQdiskRequest *request,
     return true;
 }
 
-static int ioreq_runio_qemu_aio(XenQdiskRequest *request)
+static int do_aio(XenQdiskRequest *request)
 {
     XenQdiskDataPlane *dataplane = request->dataplane;
 
@@ -352,14 +351,14 @@ static int ioreq_runio_qemu_aio(XenQdiskRequest *request)
     if (request->req.nr_segments &&
         (request->req.operation == BLKIF_OP_WRITE ||
          request->req.operation == BLKIF_OP_FLUSH_DISKCACHE) &&
-        ioreq_grant_copy(request)) {
+        copy_request(request)) {
         qemu_vfree(request->buf);
         goto err;
     }
 
     request->aio_inflight++;
     if (request->presync) {
-        blk_aio_flush(request->dataplane->blk, qemu_aio_complete, request);
+        blk_aio_flush(request->dataplane->blk, complete_aio, request);
         return 0;
     }
 
@@ -370,7 +369,7 @@ static int ioreq_runio_qemu_aio(XenQdiskRequest *request)
                          request->v.size, BLOCK_ACCT_READ);
         request->aio_inflight++;
         blk_aio_preadv(dataplane->blk, request->start, &request->v, 0,
-                       qemu_aio_complete, request);
+                       complete_aio, request);
         break;
     case BLKIF_OP_WRITE:
     case BLKIF_OP_FLUSH_DISKCACHE:
@@ -385,12 +384,12 @@ static int ioreq_runio_qemu_aio(XenQdiskRequest *request)
                          BLOCK_ACCT_WRITE : BLOCK_ACCT_FLUSH);
         request->aio_inflight++;
         blk_aio_pwritev(dataplane->blk, request->start, &request->v, 0,
-                        qemu_aio_complete, request);
+                        complete_aio, request);
         break;
     case BLKIF_OP_DISCARD:
     {
         struct blkif_request_discard *req = (void *)&request->req;
-        if (!blk_split_discard(request, req->sector_number, req->nr_sectors)) {
+        if (!split_discard(request, req->sector_number, req->nr_sectors)) {
             goto err;
         }
         break;
@@ -400,17 +399,17 @@ static int ioreq_runio_qemu_aio(XenQdiskRequest *request)
         goto err;
     }
 
-    qemu_aio_complete(request, 0);
+    complete_aio(request, 0);
 
     return 0;
 
 err:
-    ioreq_finish(request);
+    finish_request(request);
     request->status = BLKIF_RSP_ERROR;
     return -1;
 }
 
-static int blk_send_response_one(XenQdiskRequest *request)
+static int send_response_one(XenQdiskRequest *request)
 {
     XenQdiskDataPlane *dataplane = request->dataplane;
     int send_notify = 0;
@@ -466,15 +465,15 @@ static int blk_send_response_one(XenQdiskRequest *request)
 }
 
 /* walk finished list, send outstanding responses, free requests */
-static void blk_send_response_all(XenQdiskDataPlane *dataplane)
+static void send_response_all(XenQdiskDataPlane *dataplane)
 {
     XenQdiskRequest *request;
     int send_notify = 0;
 
     while (!QLIST_EMPTY(&dataplane->finished)) {
         request = QLIST_FIRST(&dataplane->finished);
-        send_notify += blk_send_response_one(request);
-        ioreq_release(request, true);
+        send_notify += send_response_one(request);
+        release_request(request, true);
     }
     if (send_notify) {
         xen_device_notify_event_channel(dataplane->xendev,
@@ -482,8 +481,8 @@ static void blk_send_response_all(XenQdiskDataPlane *dataplane)
     }
 }
 
-static int blk_get_request(XenQdiskDataPlane *dataplane,
-                           XenQdiskRequest *request, RING_IDX rc)
+static int get_request(XenQdiskDataPlane *dataplane,
+                       XenQdiskRequest *request, RING_IDX rc)
 {
     switch (dataplane->protocol) {
     case BLKIF_PROTOCOL_NATIVE: {
@@ -513,7 +512,7 @@ static int blk_get_request(XenQdiskDataPlane *dataplane,
     return 0;
 }
 
-static void blk_handle_requests(XenQdiskDataPlane *dataplane)
+static void handle_requests(XenQdiskDataPlane *dataplane)
 {
     RING_IDX rc, rp;
     XenQdiskRequest *request;
@@ -524,22 +523,22 @@ static void blk_handle_requests(XenQdiskDataPlane *dataplane)
     rp = dataplane->rings.common.sring->req_prod;
     xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
 
-    blk_send_response_all(dataplane);
+    send_response_all(dataplane);
     while (rc != rp) {
         /* pull request from ring */
         if (RING_REQUEST_CONS_OVERFLOW(&dataplane->rings.common, rc)) {
             break;
         }
-        request = ioreq_start(dataplane);
+        request = start_request(dataplane);
         if (request == NULL) {
             dataplane->more_work++;
             break;
         }
-        blk_get_request(dataplane, request, rc);
+        get_request(dataplane, request, rc);
         dataplane->rings.common.req_cons = ++rc;
 
         /* parse them */
-        if (ioreq_parse(request) != 0) {
+        if (parse_request(request) != 0) {
 
             switch (request->req.operation) {
             case BLKIF_OP_READ:
@@ -557,15 +556,15 @@ static void blk_handle_requests(XenQdiskDataPlane *dataplane)
                 break;
             };
 
-            if (blk_send_response_one(request)) {
+            if (send_response_one(request)) {
                 xen_device_notify_event_channel(dataplane->xendev,
                                                 dataplane->event_channel);
             }
-            ioreq_release(request, false);
+            release_request(request, false);
             continue;
         }
 
-        ioreq_runio_qemu_aio(request);
+        do_aio(request);
     }
 
     if (dataplane->more_work &&
@@ -574,16 +573,16 @@ static void blk_handle_requests(XenQdiskDataPlane *dataplane)
     }
 }
 
-static void blk_bh(void *opaque)
+static void xen_qdisk_dataplane_bh(void *opaque)
 {
     XenQdiskDataPlane *dataplane = opaque;
 
     aio_context_acquire(dataplane->ctx);
-    blk_handle_requests(dataplane);
+    handle_requests(dataplane);
     aio_context_release(dataplane->ctx);
 }
 
-static void blk_event(void *opaque)
+static void xen_qdisk_dataplane_event(void *opaque)
 {
     XenQdiskDataPlane *dataplane = opaque;
 
@@ -612,7 +611,8 @@ XenQdiskDataPlane *xen_qdisk_dataplane_create(XenDevice *xendev,
     } else {
         dataplane->ctx = qemu_get_aio_context();
     }
-    dataplane->bh = aio_bh_new(dataplane->ctx, blk_bh, dataplane);
+    dataplane->bh = aio_bh_new(dataplane->ctx, xen_qdisk_dataplane_bh,
+                               dataplane);
 
     return dataplane;
 }
@@ -718,7 +718,7 @@ void xen_qdisk_dataplane_start(XenQdiskDataPlane *dataplane,
 
     dataplane->event_channel =
         xen_device_bind_event_channel(xendev, event_channel,
-                                      blk_event, dataplane,
+                                      xen_qdisk_dataplane_event, dataplane,
                                       &error_fatal);
 
     aio_context_acquire(dataplane->ctx);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [PATCH 13/18] xen: purge 'blk' and 'ioreq' from function names in dataplane/xen-qdisk.c
@ 2018-11-21 15:12   ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Kevin Wolf, Stefano Stabellini, Max Reitz, Paul Durrant,
	Stefan Hajnoczi, Anthony Perard

This is a purely cosmetic patch that purges remaining use of 'blk' and
'ioreq' in local function names.

No functional change.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
---
 hw/block/dataplane/xen-qdisk.c | 86 +++++++++++++++++++++---------------------
 1 file changed, 43 insertions(+), 43 deletions(-)

diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-qdisk.c
index 50a48b6f5f..94785eeff3 100644
--- a/hw/block/dataplane/xen-qdisk.c
+++ b/hw/block/dataplane/xen-qdisk.c
@@ -57,7 +57,7 @@ struct XenQdiskDataPlane {
     AioContext *ctx;
 };
 
-static void ioreq_reset(XenQdiskRequest *request)
+static void reset_request(XenQdiskRequest *request)
 {
     memset(&request->req, 0, sizeof(request->req));
     request->status = 0;
@@ -76,7 +76,7 @@ static void ioreq_reset(XenQdiskRequest *request)
     qemu_iovec_reset(&request->v);
 }
 
-static XenQdiskRequest *ioreq_start(XenQdiskDataPlane *dataplane)
+static XenQdiskRequest *start_request(XenQdiskDataPlane *dataplane)
 {
     XenQdiskRequest *request = NULL;
 
@@ -101,7 +101,7 @@ out:
     return request;
 }
 
-static void ioreq_finish(XenQdiskRequest *request)
+static void finish_request(XenQdiskRequest *request)
 {
     XenQdiskDataPlane *dataplane = request->dataplane;
 
@@ -111,12 +111,12 @@ static void ioreq_finish(XenQdiskRequest *request)
     dataplane->requests_finished++;
 }
 
-static void ioreq_release(XenQdiskRequest *request, bool finish)
+static void release_request(XenQdiskRequest *request, bool finish)
 {
     XenQdiskDataPlane *dataplane = request->dataplane;
 
     QLIST_REMOVE(request, list);
-    ioreq_reset(request);
+    reset_request(request);
     request->dataplane = dataplane;
     QLIST_INSERT_HEAD(&dataplane->freelist, request, list);
     if (finish) {
@@ -130,7 +130,7 @@ static void ioreq_release(XenQdiskRequest *request, bool finish)
  * translate request into iovec + start offset
  * do sanity checks along the way
  */
-static int ioreq_parse(XenQdiskRequest *request)
+static int parse_request(XenQdiskRequest *request)
 {
     XenQdiskDataPlane *dataplane = request->dataplane;
     size_t len;
@@ -191,7 +191,7 @@ err:
     return -1;
 }
 
-static int ioreq_grant_copy(XenQdiskRequest *request)
+static int copy_request(XenQdiskRequest *request)
 {
     XenQdiskDataPlane *dataplane = request->dataplane;
     XenDevice *xendev = dataplane->xendev;
@@ -240,9 +240,9 @@ static int ioreq_grant_copy(XenQdiskRequest *request)
     return 0;
 }
 
-static int ioreq_runio_qemu_aio(XenQdiskRequest *request);
+static int do_aio(XenQdiskRequest *request);
 
-static void qemu_aio_complete(void *opaque, int ret)
+static void complete_aio(void *opaque, int ret)
 {
     XenQdiskRequest *request = opaque;
     XenQdiskDataPlane *dataplane = request->dataplane;
@@ -259,7 +259,7 @@ static void qemu_aio_complete(void *opaque, int ret)
     request->aio_inflight--;
     if (request->presync) {
         request->presync = 0;
-        ioreq_runio_qemu_aio(request);
+        do_aio(request);
         goto done;
     }
     if (request->aio_inflight > 0) {
@@ -270,7 +270,7 @@ static void qemu_aio_complete(void *opaque, int ret)
     case BLKIF_OP_READ:
         /* in case of failure request->aio_errors is increased */
         if (ret == 0) {
-            ioreq_grant_copy(request);
+            copy_request(request);
         }
         qemu_vfree(request->buf);
         break;
@@ -286,7 +286,7 @@ static void qemu_aio_complete(void *opaque, int ret)
     }
 
     request->status = request->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY;
-    ioreq_finish(request);
+    finish_request(request);
 
     switch (request->req.operation) {
     case BLKIF_OP_WRITE:
@@ -311,9 +311,8 @@ done:
     aio_context_release(dataplane->ctx);
 }
 
-static bool blk_split_discard(XenQdiskRequest *request,
-                              blkif_sector_t sector_number,
-                              uint64_t nr_sectors)
+static bool split_discard(XenQdiskRequest *request,
+                          blkif_sector_t sector_number, uint64_t nr_sectors)
 {
     XenQdiskDataPlane *dataplane = request->dataplane;
     int64_t byte_offset;
@@ -336,7 +335,7 @@ static bool blk_split_discard(XenQdiskRequest *request,
         byte_chunk = byte_remaining > limit ? limit : byte_remaining;
         request->aio_inflight++;
         blk_aio_pdiscard(dataplane->blk, byte_offset, byte_chunk,
-                         qemu_aio_complete, request);
+                         complete_aio, request);
         byte_remaining -= byte_chunk;
         byte_offset += byte_chunk;
     } while (byte_remaining > 0);
@@ -344,7 +343,7 @@ static bool blk_split_discard(XenQdiskRequest *request,
     return true;
 }
 
-static int ioreq_runio_qemu_aio(XenQdiskRequest *request)
+static int do_aio(XenQdiskRequest *request)
 {
     XenQdiskDataPlane *dataplane = request->dataplane;
 
@@ -352,14 +351,14 @@ static int ioreq_runio_qemu_aio(XenQdiskRequest *request)
     if (request->req.nr_segments &&
         (request->req.operation == BLKIF_OP_WRITE ||
          request->req.operation == BLKIF_OP_FLUSH_DISKCACHE) &&
-        ioreq_grant_copy(request)) {
+        copy_request(request)) {
         qemu_vfree(request->buf);
         goto err;
     }
 
     request->aio_inflight++;
     if (request->presync) {
-        blk_aio_flush(request->dataplane->blk, qemu_aio_complete, request);
+        blk_aio_flush(request->dataplane->blk, complete_aio, request);
         return 0;
     }
 
@@ -370,7 +369,7 @@ static int ioreq_runio_qemu_aio(XenQdiskRequest *request)
                          request->v.size, BLOCK_ACCT_READ);
         request->aio_inflight++;
         blk_aio_preadv(dataplane->blk, request->start, &request->v, 0,
-                       qemu_aio_complete, request);
+                       complete_aio, request);
         break;
     case BLKIF_OP_WRITE:
     case BLKIF_OP_FLUSH_DISKCACHE:
@@ -385,12 +384,12 @@ static int ioreq_runio_qemu_aio(XenQdiskRequest *request)
                          BLOCK_ACCT_WRITE : BLOCK_ACCT_FLUSH);
         request->aio_inflight++;
         blk_aio_pwritev(dataplane->blk, request->start, &request->v, 0,
-                        qemu_aio_complete, request);
+                        complete_aio, request);
         break;
     case BLKIF_OP_DISCARD:
     {
         struct blkif_request_discard *req = (void *)&request->req;
-        if (!blk_split_discard(request, req->sector_number, req->nr_sectors)) {
+        if (!split_discard(request, req->sector_number, req->nr_sectors)) {
             goto err;
         }
         break;
@@ -400,17 +399,17 @@ static int ioreq_runio_qemu_aio(XenQdiskRequest *request)
         goto err;
     }
 
-    qemu_aio_complete(request, 0);
+    complete_aio(request, 0);
 
     return 0;
 
 err:
-    ioreq_finish(request);
+    finish_request(request);
     request->status = BLKIF_RSP_ERROR;
     return -1;
 }
 
-static int blk_send_response_one(XenQdiskRequest *request)
+static int send_response_one(XenQdiskRequest *request)
 {
     XenQdiskDataPlane *dataplane = request->dataplane;
     int send_notify = 0;
@@ -466,15 +465,15 @@ static int blk_send_response_one(XenQdiskRequest *request)
 }
 
 /* walk finished list, send outstanding responses, free requests */
-static void blk_send_response_all(XenQdiskDataPlane *dataplane)
+static void send_response_all(XenQdiskDataPlane *dataplane)
 {
     XenQdiskRequest *request;
     int send_notify = 0;
 
     while (!QLIST_EMPTY(&dataplane->finished)) {
         request = QLIST_FIRST(&dataplane->finished);
-        send_notify += blk_send_response_one(request);
-        ioreq_release(request, true);
+        send_notify += send_response_one(request);
+        release_request(request, true);
     }
     if (send_notify) {
         xen_device_notify_event_channel(dataplane->xendev,
@@ -482,8 +481,8 @@ static void blk_send_response_all(XenQdiskDataPlane *dataplane)
     }
 }
 
-static int blk_get_request(XenQdiskDataPlane *dataplane,
-                           XenQdiskRequest *request, RING_IDX rc)
+static int get_request(XenQdiskDataPlane *dataplane,
+                       XenQdiskRequest *request, RING_IDX rc)
 {
     switch (dataplane->protocol) {
     case BLKIF_PROTOCOL_NATIVE: {
@@ -513,7 +512,7 @@ static int blk_get_request(XenQdiskDataPlane *dataplane,
     return 0;
 }
 
-static void blk_handle_requests(XenQdiskDataPlane *dataplane)
+static void handle_requests(XenQdiskDataPlane *dataplane)
 {
     RING_IDX rc, rp;
     XenQdiskRequest *request;
@@ -524,22 +523,22 @@ static void blk_handle_requests(XenQdiskDataPlane *dataplane)
     rp = dataplane->rings.common.sring->req_prod;
     xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
 
-    blk_send_response_all(dataplane);
+    send_response_all(dataplane);
     while (rc != rp) {
         /* pull request from ring */
         if (RING_REQUEST_CONS_OVERFLOW(&dataplane->rings.common, rc)) {
             break;
         }
-        request = ioreq_start(dataplane);
+        request = start_request(dataplane);
         if (request == NULL) {
             dataplane->more_work++;
             break;
         }
-        blk_get_request(dataplane, request, rc);
+        get_request(dataplane, request, rc);
         dataplane->rings.common.req_cons = ++rc;
 
         /* parse them */
-        if (ioreq_parse(request) != 0) {
+        if (parse_request(request) != 0) {
 
             switch (request->req.operation) {
             case BLKIF_OP_READ:
@@ -557,15 +556,15 @@ static void blk_handle_requests(XenQdiskDataPlane *dataplane)
                 break;
             };
 
-            if (blk_send_response_one(request)) {
+            if (send_response_one(request)) {
                 xen_device_notify_event_channel(dataplane->xendev,
                                                 dataplane->event_channel);
             }
-            ioreq_release(request, false);
+            release_request(request, false);
             continue;
         }
 
-        ioreq_runio_qemu_aio(request);
+        do_aio(request);
     }
 
     if (dataplane->more_work &&
@@ -574,16 +573,16 @@ static void blk_handle_requests(XenQdiskDataPlane *dataplane)
     }
 }
 
-static void blk_bh(void *opaque)
+static void xen_qdisk_dataplane_bh(void *opaque)
 {
     XenQdiskDataPlane *dataplane = opaque;
 
     aio_context_acquire(dataplane->ctx);
-    blk_handle_requests(dataplane);
+    handle_requests(dataplane);
     aio_context_release(dataplane->ctx);
 }
 
-static void blk_event(void *opaque)
+static void xen_qdisk_dataplane_event(void *opaque)
 {
     XenQdiskDataPlane *dataplane = opaque;
 
@@ -612,7 +611,8 @@ XenQdiskDataPlane *xen_qdisk_dataplane_create(XenDevice *xendev,
     } else {
         dataplane->ctx = qemu_get_aio_context();
     }
-    dataplane->bh = aio_bh_new(dataplane->ctx, blk_bh, dataplane);
+    dataplane->bh = aio_bh_new(dataplane->ctx, xen_qdisk_dataplane_bh,
+                               dataplane);
 
     return dataplane;
 }
@@ -718,7 +718,7 @@ void xen_qdisk_dataplane_start(XenQdiskDataPlane *dataplane,
 
     dataplane->event_channel =
         xen_device_bind_event_channel(xendev, event_channel,
-                                      blk_event, dataplane,
+                                      xen_qdisk_dataplane_event, dataplane,
                                       &error_fatal);
 
     aio_context_acquire(dataplane->ctx);
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [Qemu-devel] [PATCH 14/18] xen: add implementations of xen-qdisk connect and disconnect functions...
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
                   ` (19 preceding siblings ...)
  2018-11-21 15:12 ` [PATCH 14/18] xen: add implementations of xen-qdisk connect and disconnect functions Paul Durrant
@ 2018-11-21 15:12 ` Paul Durrant
  2018-11-28 16:34     ` Kevin Wolf
                     ` (2 more replies)
  2018-11-21 15:12   ` Paul Durrant
                   ` (4 subsequent siblings)
  25 siblings, 3 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Paul Durrant, Stefano Stabellini, Anthony Perard, Kevin Wolf, Max Reitz

...and wire in the dataplane.

This patch adds the remaining code to make the xen-qdisk XenDevice
functional. The parameters that a block frontend expects to find are
populated in the backend xenstore area, and the 'ring-ref' and
'event-channel' values specified in the frontend xenstore area are
mapped/bound and used to set up the dataplane.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
---
 hw/block/xen-qdisk.c       | 140 +++++++++++++++++++++++++++++++++++++++++++++
 hw/xen/xen-bus.c           |  12 ++--
 include/hw/xen/xen-bus.h   |   8 +++
 include/hw/xen/xen-qdisk.h |  12 ++++
 4 files changed, 166 insertions(+), 6 deletions(-)

diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
index 35f7b70480..8c88393832 100644
--- a/hw/block/xen-qdisk.c
+++ b/hw/block/xen-qdisk.c
@@ -9,6 +9,10 @@
 #include "qapi/visitor.h"
 #include "hw/hw.h"
 #include "hw/xen/xen-qdisk.h"
+#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
+#include "sysemu/iothread.h"
+#include "dataplane/xen-qdisk.h"
 #include "trace.h"
 
 static char *xen_qdisk_get_name(XenDevice *xendev, Error **errp)
@@ -23,6 +27,11 @@ static void xen_qdisk_realize(XenDevice *xendev, Error **errp)
 {
     XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
     XenQdiskVdev *vdev = &qdiskdev->vdev;
+    BlockConf *conf = &qdiskdev->conf;
+    DriveInfo *dinfo;
+    bool is_cdrom;
+    unsigned int info;
+    int64_t size;
 
     if (!vdev->valid) {
         error_setg(errp, "vdev property not set");
@@ -30,13 +39,134 @@ static void xen_qdisk_realize(XenDevice *xendev, Error **errp)
     }
 
     trace_xen_qdisk_realize(vdev->disk, vdev->partition);
+
+    if (!conf->blk) {
+        error_setg(errp, "drive property not set");
+        return;
+    }
+
+    if (!blk_is_inserted(conf->blk)) {
+        error_setg(errp, "device needs media, but drive is empty");
+        return;
+    }
+
+    if (!blkconf_apply_backend_options(conf, blk_is_read_only(conf->blk),
+                                       false, errp)) {
+        return;
+    }
+
+    if (!blkconf_geometry(conf, NULL, 65535, 255, 255, errp)) {
+        return;
+    }
+
+    dinfo = blk_legacy_dinfo(conf->blk);
+    is_cdrom = (dinfo && dinfo->media_cd);
+
+    blkconf_blocksizes(conf);
+
+    if (conf->logical_block_size > conf->physical_block_size) {
+        error_setg(
+            errp, "logical_block_size > physical_block_size not supported");
+        return;
+    }
+
+    blk_set_guest_block_size(conf->blk, conf->logical_block_size);
+
+    if (conf->discard_granularity > 0) {
+        xen_device_backend_printf(xendev, "feature-discard", "%u", 1);
+    }
+
+    xen_device_backend_printf(xendev, "feature-flush-cache", "%u", 1);
+    xen_device_backend_printf(xendev, "max-ring-page-order", "%u",
+                              qdiskdev->max_ring_page_order);
+
+    info = blk_is_read_only(conf->blk) ? VDISK_READONLY : 0;
+    info |= is_cdrom ? VDISK_CDROM : 0;
+
+    xen_device_backend_printf(xendev, "info", "%u", info);
+
+    xen_device_frontend_printf(xendev, "virtual-device", "%u",
+                               vdev->number);
+    xen_device_frontend_printf(xendev, "device-type", "%s",
+                               is_cdrom ? "cdrom" : "disk");
+
+    size = blk_getlength(conf->blk);
+    xen_device_backend_printf(xendev, "sector-size", "%u",
+                              conf->logical_block_size);
+    xen_device_backend_printf(xendev, "sectors", "%lu",
+                              size / conf->logical_block_size);
+
+    qdiskdev->dataplane = xen_qdisk_dataplane_create(xendev, conf,
+                                                     qdiskdev->iothread);
 }
 
 static void xen_qdisk_connect(XenQdiskDevice *qdiskdev, Error **errp)
 {
     XenQdiskVdev *vdev = &qdiskdev->vdev;
+    XenDevice *xendev = XEN_DEVICE(qdiskdev);
+    unsigned int order, nr_ring_ref, *ring_ref, event_channel, protocol;
+    char *str;
 
     trace_xen_qdisk_connect(vdev->disk, vdev->partition);
+
+    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");
+            return;
+        }
+    } else if (order <= qdiskdev->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);
+                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");
+        return;
+    }
+
+    if (xen_device_frontend_scanf(xendev, "protocol", "%ms",
+                                  &str) != 1) {
+        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_qdisk_dataplane_start(qdiskdev->dataplane, ring_ref, nr_ring_ref,
+                              event_channel, protocol);
+
+    g_free(ring_ref);
 }
 
 static void xen_qdisk_disconnect(XenQdiskDevice *qdiskdev, Error **errp)
@@ -44,6 +174,8 @@ static void xen_qdisk_disconnect(XenQdiskDevice *qdiskdev, Error **errp)
     XenQdiskVdev *vdev = &qdiskdev->vdev;
 
     trace_xen_qdisk_disconnect(vdev->disk, vdev->partition);
+
+    xen_qdisk_dataplane_stop(qdiskdev->dataplane);
 }
 
 static void xen_qdisk_frontend_changed(XenDevice *xendev,
@@ -93,6 +225,9 @@ static void xen_qdisk_unrealize(XenDevice *xendev, Error **errp)
     trace_xen_qdisk_unrealize(vdev->disk, vdev->partition);
 
     xen_qdisk_disconnect(qdiskdev, &error_fatal);
+
+    xen_qdisk_dataplane_destroy(qdiskdev->dataplane);
+    qdiskdev->dataplane = NULL;
 }
 
 static char *disk_to_vbd_name(unsigned int disk)
@@ -289,6 +424,11 @@ const PropertyInfo xen_qdisk_prop_vdev = {
 static Property xen_qdisk_props[] = {
     DEFINE_PROP("vdev", XenQdiskDevice, vdev,
                 xen_qdisk_prop_vdev, XenQdiskVdev),
+    DEFINE_BLOCK_PROPERTIES(XenQdiskDevice, conf),
+    DEFINE_PROP_UINT32("max-ring-page-order", XenQdiskDevice,
+                       max_ring_page_order, 4),
+    DEFINE_PROP_LINK("iothread", XenQdiskDevice, iothread, TYPE_IOTHREAD,
+                     IOThread *),
     DEFINE_PROP_END_OF_LIST()
 };
 
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index 64c8af54b0..c4b253103f 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -217,8 +217,8 @@ static const TypeInfo xen_bus_type_info = {
     .class_init = xen_bus_class_init,
 };
 
-static void xen_device_backend_printf(XenDevice *xendev, const char *key,
-                                      const char *fmt, ...)
+void xen_device_backend_printf(XenDevice *xendev, const char *key,
+                               const char *fmt, ...)
 {
     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
     va_list ap;
@@ -305,8 +305,8 @@ static void xen_device_backend_destroy(XenDevice *xendev)
     g_free(xendev->backend_path);
 }
 
-static void xen_device_frontend_printf(XenDevice *xendev, const char *key,
-                                       const char *fmt, ...)
+void xen_device_frontend_printf(XenDevice *xendev, const char *key,
+                                const char *fmt, ...)
 {
     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
     va_list ap;
@@ -318,8 +318,8 @@ static void xen_device_frontend_printf(XenDevice *xendev, const char *key,
     va_end(ap);
 }
 
-static int xen_device_frontend_scanf(XenDevice *xendev, const char *key,
-                                      const char *fmt, ...)
+int xen_device_frontend_scanf(XenDevice *xendev, const char *key,
+                              const char *fmt, ...)
 {
     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
     va_list ap;
diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h
index 386f6bfc93..d931e01268 100644
--- a/include/hw/xen/xen-bus.h
+++ b/include/hw/xen/xen-bus.h
@@ -82,6 +82,14 @@ void xen_device_backend_set_state(XenDevice *xendev,
                                   enum xenbus_state state);
 enum xenbus_state xen_device_backend_get_state(XenDevice *xendev);
 
+void xen_device_backend_printf(XenDevice *xendev, const char *key,
+                               const char *fmt, ...);
+
+void xen_device_frontend_printf(XenDevice *xendev, const char *key,
+                                const char *fmt, ...);
+int xen_device_frontend_scanf(XenDevice *xendev, const char *key,
+                              const char *fmt, ...);
+
 void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs,
                                    Error **errp);
 void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs,
diff --git a/include/hw/xen/xen-qdisk.h b/include/hw/xen/xen-qdisk.h
index ade0866037..d7dd2bf0ee 100644
--- a/include/hw/xen/xen-qdisk.h
+++ b/include/hw/xen/xen-qdisk.h
@@ -6,7 +6,15 @@
 #ifndef HW_XEN_QDISK_H
 #define HW_XEN_QDISK_H
 
+#include "hw/xen/xen.h"
 #include "hw/xen/xen-bus.h"
+#include "hw/block/block.h"
+#include "hw/block/xen_blkif.h"
+#include "hw/block/dataplane/xen-qdisk.h"
+#include "sysemu/blockdev.h"
+#include "sysemu/iothread.h"
+#include "sysemu/block-backend.h"
+#include "sysemu/iothread.h"
 
 typedef enum XenQdiskVdevType {
     XEN_QDISK_VDEV_TYPE_DP,
@@ -33,6 +41,10 @@ typedef struct XenQdiskDevice XenQdiskDevice;
 struct XenQdiskDevice {
     XenDevice xendev;
     XenQdiskVdev vdev;
+    BlockConf conf;
+    unsigned int max_ring_page_order;
+    IOThread *iothread;
+    XenQdiskDataPlane *dataplane;
 };
 
 #endif /* HW_XEN_QDISK_H */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [PATCH 14/18] xen: add implementations of xen-qdisk connect and disconnect functions...
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
                   ` (18 preceding siblings ...)
  2018-11-21 15:12   ` Paul Durrant
@ 2018-11-21 15:12 ` Paul Durrant
  2018-11-21 15:12 ` [Qemu-devel] " Paul Durrant
                   ` (5 subsequent siblings)
  25 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Anthony Perard, Kevin Wolf, Paul Durrant, Stefano Stabellini, Max Reitz

...and wire in the dataplane.

This patch adds the remaining code to make the xen-qdisk XenDevice
functional. The parameters that a block frontend expects to find are
populated in the backend xenstore area, and the 'ring-ref' and
'event-channel' values specified in the frontend xenstore area are
mapped/bound and used to set up the dataplane.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
---
 hw/block/xen-qdisk.c       | 140 +++++++++++++++++++++++++++++++++++++++++++++
 hw/xen/xen-bus.c           |  12 ++--
 include/hw/xen/xen-bus.h   |   8 +++
 include/hw/xen/xen-qdisk.h |  12 ++++
 4 files changed, 166 insertions(+), 6 deletions(-)

diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
index 35f7b70480..8c88393832 100644
--- a/hw/block/xen-qdisk.c
+++ b/hw/block/xen-qdisk.c
@@ -9,6 +9,10 @@
 #include "qapi/visitor.h"
 #include "hw/hw.h"
 #include "hw/xen/xen-qdisk.h"
+#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
+#include "sysemu/iothread.h"
+#include "dataplane/xen-qdisk.h"
 #include "trace.h"
 
 static char *xen_qdisk_get_name(XenDevice *xendev, Error **errp)
@@ -23,6 +27,11 @@ static void xen_qdisk_realize(XenDevice *xendev, Error **errp)
 {
     XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
     XenQdiskVdev *vdev = &qdiskdev->vdev;
+    BlockConf *conf = &qdiskdev->conf;
+    DriveInfo *dinfo;
+    bool is_cdrom;
+    unsigned int info;
+    int64_t size;
 
     if (!vdev->valid) {
         error_setg(errp, "vdev property not set");
@@ -30,13 +39,134 @@ static void xen_qdisk_realize(XenDevice *xendev, Error **errp)
     }
 
     trace_xen_qdisk_realize(vdev->disk, vdev->partition);
+
+    if (!conf->blk) {
+        error_setg(errp, "drive property not set");
+        return;
+    }
+
+    if (!blk_is_inserted(conf->blk)) {
+        error_setg(errp, "device needs media, but drive is empty");
+        return;
+    }
+
+    if (!blkconf_apply_backend_options(conf, blk_is_read_only(conf->blk),
+                                       false, errp)) {
+        return;
+    }
+
+    if (!blkconf_geometry(conf, NULL, 65535, 255, 255, errp)) {
+        return;
+    }
+
+    dinfo = blk_legacy_dinfo(conf->blk);
+    is_cdrom = (dinfo && dinfo->media_cd);
+
+    blkconf_blocksizes(conf);
+
+    if (conf->logical_block_size > conf->physical_block_size) {
+        error_setg(
+            errp, "logical_block_size > physical_block_size not supported");
+        return;
+    }
+
+    blk_set_guest_block_size(conf->blk, conf->logical_block_size);
+
+    if (conf->discard_granularity > 0) {
+        xen_device_backend_printf(xendev, "feature-discard", "%u", 1);
+    }
+
+    xen_device_backend_printf(xendev, "feature-flush-cache", "%u", 1);
+    xen_device_backend_printf(xendev, "max-ring-page-order", "%u",
+                              qdiskdev->max_ring_page_order);
+
+    info = blk_is_read_only(conf->blk) ? VDISK_READONLY : 0;
+    info |= is_cdrom ? VDISK_CDROM : 0;
+
+    xen_device_backend_printf(xendev, "info", "%u", info);
+
+    xen_device_frontend_printf(xendev, "virtual-device", "%u",
+                               vdev->number);
+    xen_device_frontend_printf(xendev, "device-type", "%s",
+                               is_cdrom ? "cdrom" : "disk");
+
+    size = blk_getlength(conf->blk);
+    xen_device_backend_printf(xendev, "sector-size", "%u",
+                              conf->logical_block_size);
+    xen_device_backend_printf(xendev, "sectors", "%lu",
+                              size / conf->logical_block_size);
+
+    qdiskdev->dataplane = xen_qdisk_dataplane_create(xendev, conf,
+                                                     qdiskdev->iothread);
 }
 
 static void xen_qdisk_connect(XenQdiskDevice *qdiskdev, Error **errp)
 {
     XenQdiskVdev *vdev = &qdiskdev->vdev;
+    XenDevice *xendev = XEN_DEVICE(qdiskdev);
+    unsigned int order, nr_ring_ref, *ring_ref, event_channel, protocol;
+    char *str;
 
     trace_xen_qdisk_connect(vdev->disk, vdev->partition);
+
+    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");
+            return;
+        }
+    } else if (order <= qdiskdev->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);
+                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");
+        return;
+    }
+
+    if (xen_device_frontend_scanf(xendev, "protocol", "%ms",
+                                  &str) != 1) {
+        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_qdisk_dataplane_start(qdiskdev->dataplane, ring_ref, nr_ring_ref,
+                              event_channel, protocol);
+
+    g_free(ring_ref);
 }
 
 static void xen_qdisk_disconnect(XenQdiskDevice *qdiskdev, Error **errp)
@@ -44,6 +174,8 @@ static void xen_qdisk_disconnect(XenQdiskDevice *qdiskdev, Error **errp)
     XenQdiskVdev *vdev = &qdiskdev->vdev;
 
     trace_xen_qdisk_disconnect(vdev->disk, vdev->partition);
+
+    xen_qdisk_dataplane_stop(qdiskdev->dataplane);
 }
 
 static void xen_qdisk_frontend_changed(XenDevice *xendev,
@@ -93,6 +225,9 @@ static void xen_qdisk_unrealize(XenDevice *xendev, Error **errp)
     trace_xen_qdisk_unrealize(vdev->disk, vdev->partition);
 
     xen_qdisk_disconnect(qdiskdev, &error_fatal);
+
+    xen_qdisk_dataplane_destroy(qdiskdev->dataplane);
+    qdiskdev->dataplane = NULL;
 }
 
 static char *disk_to_vbd_name(unsigned int disk)
@@ -289,6 +424,11 @@ const PropertyInfo xen_qdisk_prop_vdev = {
 static Property xen_qdisk_props[] = {
     DEFINE_PROP("vdev", XenQdiskDevice, vdev,
                 xen_qdisk_prop_vdev, XenQdiskVdev),
+    DEFINE_BLOCK_PROPERTIES(XenQdiskDevice, conf),
+    DEFINE_PROP_UINT32("max-ring-page-order", XenQdiskDevice,
+                       max_ring_page_order, 4),
+    DEFINE_PROP_LINK("iothread", XenQdiskDevice, iothread, TYPE_IOTHREAD,
+                     IOThread *),
     DEFINE_PROP_END_OF_LIST()
 };
 
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index 64c8af54b0..c4b253103f 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -217,8 +217,8 @@ static const TypeInfo xen_bus_type_info = {
     .class_init = xen_bus_class_init,
 };
 
-static void xen_device_backend_printf(XenDevice *xendev, const char *key,
-                                      const char *fmt, ...)
+void xen_device_backend_printf(XenDevice *xendev, const char *key,
+                               const char *fmt, ...)
 {
     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
     va_list ap;
@@ -305,8 +305,8 @@ static void xen_device_backend_destroy(XenDevice *xendev)
     g_free(xendev->backend_path);
 }
 
-static void xen_device_frontend_printf(XenDevice *xendev, const char *key,
-                                       const char *fmt, ...)
+void xen_device_frontend_printf(XenDevice *xendev, const char *key,
+                                const char *fmt, ...)
 {
     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
     va_list ap;
@@ -318,8 +318,8 @@ static void xen_device_frontend_printf(XenDevice *xendev, const char *key,
     va_end(ap);
 }
 
-static int xen_device_frontend_scanf(XenDevice *xendev, const char *key,
-                                      const char *fmt, ...)
+int xen_device_frontend_scanf(XenDevice *xendev, const char *key,
+                              const char *fmt, ...)
 {
     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
     va_list ap;
diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h
index 386f6bfc93..d931e01268 100644
--- a/include/hw/xen/xen-bus.h
+++ b/include/hw/xen/xen-bus.h
@@ -82,6 +82,14 @@ void xen_device_backend_set_state(XenDevice *xendev,
                                   enum xenbus_state state);
 enum xenbus_state xen_device_backend_get_state(XenDevice *xendev);
 
+void xen_device_backend_printf(XenDevice *xendev, const char *key,
+                               const char *fmt, ...);
+
+void xen_device_frontend_printf(XenDevice *xendev, const char *key,
+                                const char *fmt, ...);
+int xen_device_frontend_scanf(XenDevice *xendev, const char *key,
+                              const char *fmt, ...);
+
 void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs,
                                    Error **errp);
 void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs,
diff --git a/include/hw/xen/xen-qdisk.h b/include/hw/xen/xen-qdisk.h
index ade0866037..d7dd2bf0ee 100644
--- a/include/hw/xen/xen-qdisk.h
+++ b/include/hw/xen/xen-qdisk.h
@@ -6,7 +6,15 @@
 #ifndef HW_XEN_QDISK_H
 #define HW_XEN_QDISK_H
 
+#include "hw/xen/xen.h"
 #include "hw/xen/xen-bus.h"
+#include "hw/block/block.h"
+#include "hw/block/xen_blkif.h"
+#include "hw/block/dataplane/xen-qdisk.h"
+#include "sysemu/blockdev.h"
+#include "sysemu/iothread.h"
+#include "sysemu/block-backend.h"
+#include "sysemu/iothread.h"
 
 typedef enum XenQdiskVdevType {
     XEN_QDISK_VDEV_TYPE_DP,
@@ -33,6 +41,10 @@ typedef struct XenQdiskDevice XenQdiskDevice;
 struct XenQdiskDevice {
     XenDevice xendev;
     XenQdiskVdev vdev;
+    BlockConf conf;
+    unsigned int max_ring_page_order;
+    IOThread *iothread;
+    XenQdiskDataPlane *dataplane;
 };
 
 #endif /* HW_XEN_QDISK_H */
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [Qemu-devel] [PATCH 15/18] xen: add a mechanism to automatically create XenDevice-s...
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
@ 2018-11-21 15:12   ` Paul Durrant
  2018-11-21 15:11 ` [Qemu-devel] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy Paul Durrant
                     ` (24 subsequent siblings)
  25 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Paul Durrant, Stefano Stabellini, Anthony Perard

...that maintains compatibility with existing Xen toolstacks.

Xen toolstacks instantiate PV backends by simply writing information into
xenstore and expecting a backend implementation to be watching for this.

This patch adds a new 'xen-backend' module to allow individual XenDevice
implementations to register a creator function to be called when a tool-
stack instantiates a new backend in this way.

To support this it is also necessary to add new watchers into the XenBus
implementation to handle enumeration of new backends and also destruction
of XenDevice-s when the toolstack sets the backend 'online' key to 0.

NOTE: This patch only adds the framework. A subsequent patch will add a
      creator function for xen-qdisk.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
---
 hw/xen/Makefile.objs         |   2 +-
 hw/xen/trace-events          |   5 +
 hw/xen/xen-backend.c         |  67 +++++++++++++
 hw/xen/xen-bus.c             | 220 +++++++++++++++++++++++++++++++++++++++----
 include/hw/xen/xen-backend.h |  24 +++++
 include/hw/xen/xen-bus.h     |   5 +-
 include/qemu/module.h        |   3 +
 7 files changed, 305 insertions(+), 21 deletions(-)
 create mode 100644 hw/xen/xen-backend.c
 create mode 100644 include/hw/xen/xen-backend.h

diff --git a/hw/xen/Makefile.objs b/hw/xen/Makefile.objs
index 77c0868190..84df60a928 100644
--- a/hw/xen/Makefile.objs
+++ b/hw/xen/Makefile.objs
@@ -1,5 +1,5 @@
 # xen backend driver support
-common-obj-$(CONFIG_XEN) += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o xen-common.o xen-bus.o xen-bus-helper.o
+common-obj-$(CONFIG_XEN) += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o xen-common.o xen-bus.o xen-bus-helper.o xen-backend.o
 
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_graphics.o xen_pt_msi.o
diff --git a/hw/xen/trace-events b/hw/xen/trace-events
index 94c46c2e34..5b12135083 100644
--- a/hw/xen/trace-events
+++ b/hw/xen/trace-events
@@ -16,11 +16,16 @@ xen_domid_restrict(int err) "err: %u"
 # include/hw/xen/xen-bus.c
 xen_bus_realize(void) ""
 xen_bus_unrealize(void) ""
+xen_bus_enumerate(void) ""
+xen_bus_type_enumerate(const char *type) "type: %s"
+xen_bus_backend_create(const char *type, const char *path) "type: %s path: %s"
 xen_bus_add_watch(const char *node, const char *key, char *token) "node: %s key: %s token: %s"
 xen_bus_remove_watch(const char *node, const char *key, char *token) "node: %s key: %s token: %s"
 xen_bus_watch(const char *token) "token: %s"
 xen_device_realize(const char *type, char *name) "type: %s name: %s"
 xen_device_unrealize(const char *type, char *name) "type: %s name: %s"
 xen_device_backend_state(const char *type, char *name, const char *state) "type: %s name: %s -> %s"
+xen_device_backend_online(const char *type, char *name, bool online) "type: %s name: %s -> %u"
 xen_device_frontend_state(const char *type, char *name, const char *state) "type: %s name: %s -> %s"
+xen_device_backend_changed(const char *type, char *name) "type: %s name: %s"
 xen_device_frontend_changed(const char *type, char *name) "type: %s name: %s"
diff --git a/hw/xen/xen-backend.c b/hw/xen/xen-backend.c
new file mode 100644
index 0000000000..7581fd390d
--- /dev/null
+++ b/hw/xen/xen-backend.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "hw/xen/xen-backend.h"
+
+typedef struct XenBackendImpl {
+    const char *type;
+    XenBackendDeviceCreate create;
+} XenBackendImpl;
+
+static GHashTable *xen_backend_table_get(void)
+{
+    static GHashTable *table;
+
+    if (table == NULL) {
+        table = g_hash_table_new(g_str_hash, g_str_equal);
+    }
+
+    return table;
+}
+
+static void xen_backend_table_add(XenBackendImpl *impl)
+{
+    g_hash_table_insert(xen_backend_table_get(), (void *)impl->type, impl);
+}
+
+static XenBackendImpl *xen_backend_table_lookup(const char *type)
+{
+    return g_hash_table_lookup(xen_backend_table_get(), type);
+}
+
+void xen_backend_register(const XenBackendInfo *info)
+{
+    XenBackendImpl *impl = g_new0(XenBackendImpl, 1);
+
+    g_assert(info->type);
+
+    if (xen_backend_table_lookup(info->type)) {
+        error_report("attempt to register duplicate Xen backend type '%s'",
+                     info->type);
+        abort();
+    }
+
+    if (!info->create) {
+        error_report("backend type '%s' has no creator", info->type);
+        abort();
+    }
+
+    impl->type = info->type;
+    impl->create = info->create;
+
+    xen_backend_table_add(impl);
+}
+
+void xen_backend_device_create(BusState *bus, const char *type,
+                               const char *name, QDict *opts, Error **errp)
+{
+    XenBackendImpl *impl = xen_backend_table_lookup(type);
+
+    if (impl) {
+        impl->create(bus, name, opts, errp);
+    }
+}
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index c4b253103f..e58b891c93 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -10,10 +10,12 @@
 #include "hw/hw.h"
 #include "hw/sysbus.h"
 #include "hw/xen/xen.h"
+#include "hw/xen/xen-backend.h"
 #include "hw/xen/xen-bus.h"
 #include "hw/xen/xen-bus-helper.h"
 #include "monitor/monitor.h"
 #include "qapi/error.h"
+#include "qapi/qmp/qdict.h"
 #include "sysemu/sysemu.h"
 #include "trace.h"
 
@@ -132,12 +134,118 @@ static void xen_bus_remove_watch(XenBus *xenbus, XenWatch *watch)
     g_free(watch);
 }
 
+static void xen_bus_backend_create(XenBus *xenbus, const char *type,
+                                   const char *name, char *path)
+{
+    char **key;
+    QDict *opts;
+    unsigned int i, n;
+    Error *local_err = NULL;
+
+    trace_xen_bus_backend_create(type, path);
+
+    key = xs_directory(xenbus->xsh, XBT_NULL, path, &n);
+    if (!key) {
+        return;
+    }
+
+    opts = qdict_new();
+    for (i = 0; i < n; i++) {
+        char *val;
+
+        /*
+         * Assume anything found in the xenstore backend area, other than
+         * the keys created for a generic XenDevice, are parameters
+         * to be used to configure the backend.
+         */
+        if (!strcmp(key[i], "state") ||
+            !strcmp(key[i], "online") ||
+            !strcmp(key[i], "frontend") ||
+            !strcmp(key[i], "frontend-id") ||
+            !strcmp(key[i], "hotplug-status"))
+            continue;
+
+        if (xs_node_scanf(xenbus->xsh, path, key[i], "%ms", &val) == 1) {
+            qdict_put_str(opts, key[i], val);
+            free(val);
+        }
+    }
+
+    xen_backend_device_create(BUS(xenbus), type, name, opts, &local_err);
+    qobject_unref(opts);
+
+    if (local_err) {
+        const char *msg = error_get_pretty(local_err);
+
+        error_report("failed to create '%s' device '%s': %s", type, name,
+                     msg);
+        error_free(local_err);
+    }
+}
+
+static void xen_bus_type_enumerate(XenBus *xenbus, const char *type)
+{
+    char *domain_path = g_strdup_printf("backend/%s/%u", type, xen_domid);
+    char **backend;
+    unsigned int i, n;
+
+    trace_xen_bus_type_enumerate(type);
+
+    backend = xs_directory(xenbus->xsh, XBT_NULL, domain_path, &n);
+    if (!backend) {
+        return;
+    }
+
+    for (i = 0; i < n; i++) {
+        char *backend_path = g_strdup_printf("%s/%s", domain_path,
+                                             backend[i]);
+        enum xenbus_state backend_state;
+
+        if (xs_node_scanf(xenbus->xsh, backend_path, "state", "%u",
+                          &backend_state) != 1)
+            backend_state = XenbusStateUnknown;
+
+        if (backend_state == XenbusStateInitialising) {
+            xen_bus_backend_create(xenbus, type, backend[i], backend_path);
+        }
+
+        g_free(backend_path);
+    }
+
+    free(backend);
+    g_free(domain_path);
+}
+
+static void xen_bus_enumerate(void *opaque)
+{
+    XenBus *xenbus = opaque;
+    char **type;
+    unsigned int i, n;
+
+    trace_xen_bus_enumerate();
+
+    type = xs_directory(xenbus->xsh, XBT_NULL, "backend", &n);
+    if (!type) {
+        return;
+    }
+
+    for (i = 0; i < n; i++) {
+        xen_bus_type_enumerate(xenbus, type[i]);
+    }
+
+    free(type);
+}
+
 static void xen_bus_unrealize(BusState *bus, Error **errp)
 {
     XenBus *xenbus = XEN_BUS(bus);
 
     trace_xen_bus_unrealize();
 
+    if (xenbus->backend_watch) {
+        xen_bus_remove_watch(xenbus, xenbus->backend_watch);
+    }
+
     if (!xenbus->xsh) {
         return;
     }
@@ -174,6 +282,7 @@ static void xen_bus_realize(BusState *bus, Error **errp)
 {
     XenBus *xenbus = XEN_BUS(bus);
     unsigned int domid;
+    Error *local_err = NULL;
 
     trace_xen_bus_realize();
 
@@ -193,6 +302,17 @@ static void xen_bus_realize(BusState *bus, Error **errp)
     notifier_list_init(&xenbus->watch_notifiers);
     qemu_set_fd_handler(xs_fileno(xenbus->xsh), xen_bus_watch, NULL,
                         xenbus);
+
+    module_call_init(MODULE_INIT_XEN_BACKEND);
+
+    xenbus->backend_watch =
+        xen_bus_add_watch(xenbus, "", /* domain root node */
+                          "backend", xen_bus_enumerate, xenbus, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to set up enumeration watch: ");
+    }
+
     return;
 
 fail:
@@ -268,6 +388,60 @@ enum xenbus_state xen_device_backend_get_state(XenDevice *xendev)
     return xendev->backend_state;
 }
 
+static void xen_device_backend_set_online(XenDevice *xendev, bool online)
+{
+    const char *type = object_get_typename(OBJECT(xendev));
+
+    if (xendev->backend_online == online) {
+        return;
+    }
+
+    trace_xen_device_backend_online(type, xendev->name, online);
+
+    xendev->backend_online = online;
+    xen_device_backend_printf(xendev, "online", "%u", online);
+}
+
+static void xen_device_backend_changed(void *opaque)
+{
+    XenDevice *xendev = opaque;
+    const char *type = object_get_typename(OBJECT(xendev));
+    enum xenbus_state state;
+    unsigned int online;
+
+    trace_xen_device_backend_changed(type, xendev->name);
+
+    if (xen_device_backend_scanf(xendev, "state", "%u", &state) != 1) {
+        state = XenbusStateUnknown;
+    }
+
+    xen_device_backend_set_state(xendev, state);
+
+    if (xen_device_backend_scanf(xendev, "online", "%u", &online) != 1) {
+        online = 0;
+    }
+
+    xen_device_backend_set_online(xendev, !!online);
+
+    /*
+     * If a backend is still 'online' then its state should be cycled
+     * back round to InitWait in order for a new frontend instance to
+     * connect. This may happen when, for example, a frontend driver is
+     * re-installed or updated.
+     * If a backend id not 'online' then the device should be destroyed.
+     */
+    if (xendev->backend_online &&
+        xendev->backend_state == XenbusStateClosed) {
+        xen_device_backend_set_state(xendev, XenbusStateInitWait);
+    } else if (!xendev->backend_online &&
+               (xendev->backend_state == XenbusStateClosed ||
+                xendev->backend_state == XenbusStateInitialising ||
+                xendev->backend_state == XenbusStateInitWait ||
+                xendev->backend_state == XenbusStateUnknown)) {
+        object_unparent(OBJECT(xendev));
+    }
+}
+
 static void xen_device_backend_create(XenDevice *xendev, Error **errp)
 {
     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
@@ -289,12 +463,38 @@ static void xen_device_backend_create(XenDevice *xendev, Error **errp)
         error_propagate(errp, local_err);
         error_prepend(errp, "failed to create backend: ");
     }
+
+    xendev->backend_state_watch =
+        xen_bus_add_watch(xenbus, xendev->backend_path,
+                          "state", xen_device_backend_changed,
+                          xendev, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to watch backend state: ");
+    }
+
+    xendev->backend_online_watch =
+        xen_bus_add_watch(xenbus, xendev->backend_path,
+                          "online", xen_device_backend_changed,
+                          xendev, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to watch backend online: ");
+    }
 }
 
 static void xen_device_backend_destroy(XenDevice *xendev)
 {
     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
 
+    if (xendev->backend_online_watch) {
+        xen_bus_remove_watch(xenbus, xendev->backend_online_watch);
+    }
+
+    if (xendev->backend_state_watch) {
+        xen_bus_remove_watch(xenbus, xendev->backend_state_watch);
+    }
+
     if (!xendev->backend_path) {
         return;
     }
@@ -378,24 +578,6 @@ static void xen_device_frontend_changed(void *opaque)
             error_free(local_err);
         }
     }
-
-    /*
-     * If a backend is still 'online' then its state should be cycled
-     * back round to InitWait in order for a new frontend instance to
-     * connect. This may happen when, for example, a frontend driver is
-     * re-installed or updated.
-     */
-    if (xendev->backend_state == XenbusStateClosed) {
-        unsigned int online;
-
-        if (xen_device_backend_scanf(xendev, "online", "%u", &online) != 1) {
-            online = 0;
-        }
-
-        if (online) {
-            xen_device_backend_set_state(xendev, XenbusStateInitWait);
-        }
-    }
 }
 
 static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
@@ -764,9 +946,9 @@ static void xen_device_realize(DeviceState *dev, Error **errp)
                               xendev->frontend_path);
     xen_device_backend_printf(xendev, "frontend-id", "%u",
                               xendev->frontend_id);
-    xen_device_backend_printf(xendev, "online", "%u", 1);
     xen_device_backend_printf(xendev, "hotplug-status", "connected");
 
+    xen_device_backend_set_online(xendev, true);
     xen_device_backend_set_state(xendev, XenbusStateInitWait);
 
     xen_device_frontend_printf(xendev, "backend", "%s",
diff --git a/include/hw/xen/xen-backend.h b/include/hw/xen/xen-backend.h
new file mode 100644
index 0000000000..ca5ae34398
--- /dev/null
+++ b/include/hw/xen/xen-backend.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ */
+
+#ifndef HW_XEN_BACKEND_H
+#define HW_XEN_BACKEND_H
+
+#include "hw/xen/xen-bus.h"
+
+typedef void (*XenBackendDeviceCreate)(BusState *bus, const char *name,
+                                       QDict *opts, Error **errp);
+
+typedef struct XenBackendInfo {
+    const char *type;
+    XenBackendDeviceCreate create;
+} XenBackendInfo;
+
+void xen_backend_register(const XenBackendInfo *info);
+
+void xen_backend_device_create(BusState *bus, const char *type,
+                               const char *name, QDict *opts, Error **errp);
+
+#endif /* HW_XEN_BACKEND_H */
diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h
index d931e01268..48f3e068d3 100644
--- a/include/hw/xen/xen-bus.h
+++ b/include/hw/xen/xen-bus.h
@@ -21,7 +21,9 @@ typedef struct XenDevice {
     char *backend_path, *frontend_path;
     enum xenbus_state backend_state, frontend_state;
     Notifier exit;
-    XenWatch *frontend_state_watch;
+    XenWatch *backend_state_watch, *frontend_state_watch;
+    bool backend_online;
+    XenWatch *backend_online_watch;
     xengnttab_handle *xgth;
     bool feature_grant_copy;
     xenevtchn_handle *xeh;
@@ -61,6 +63,7 @@ typedef struct XenBus {
     domid_t backend_id;
     struct xs_handle *xsh;
     NotifierList watch_notifiers;
+    XenWatch *backend_watch;
 } XenBus;
 
 typedef struct XenBusClass {
diff --git a/include/qemu/module.h b/include/qemu/module.h
index 54300ab6e5..55dd2beea8 100644
--- a/include/qemu/module.h
+++ b/include/qemu/module.h
@@ -44,6 +44,7 @@ typedef enum {
     MODULE_INIT_OPTS,
     MODULE_INIT_QOM,
     MODULE_INIT_TRACE,
+    MODULE_INIT_XEN_BACKEND,
     MODULE_INIT_MAX
 } module_init_type;
 
@@ -51,6 +52,8 @@ typedef enum {
 #define opts_init(function) module_init(function, MODULE_INIT_OPTS)
 #define type_init(function) module_init(function, MODULE_INIT_QOM)
 #define trace_init(function) module_init(function, MODULE_INIT_TRACE)
+#define xen_backend_init(function) module_init(function, \
+                                               MODULE_INIT_XEN_BACKEND)
 
 #define block_module_load_one(lib) module_load_one("block-", lib)
 #define ui_module_load_one(lib) module_load_one("ui-", lib)
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [PATCH 15/18] xen: add a mechanism to automatically create XenDevice-s...
@ 2018-11-21 15:12   ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Anthony Perard, Paul Durrant, Stefano Stabellini

...that maintains compatibility with existing Xen toolstacks.

Xen toolstacks instantiate PV backends by simply writing information into
xenstore and expecting a backend implementation to be watching for this.

This patch adds a new 'xen-backend' module to allow individual XenDevice
implementations to register a creator function to be called when a tool-
stack instantiates a new backend in this way.

To support this it is also necessary to add new watchers into the XenBus
implementation to handle enumeration of new backends and also destruction
of XenDevice-s when the toolstack sets the backend 'online' key to 0.

NOTE: This patch only adds the framework. A subsequent patch will add a
      creator function for xen-qdisk.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
---
 hw/xen/Makefile.objs         |   2 +-
 hw/xen/trace-events          |   5 +
 hw/xen/xen-backend.c         |  67 +++++++++++++
 hw/xen/xen-bus.c             | 220 +++++++++++++++++++++++++++++++++++++++----
 include/hw/xen/xen-backend.h |  24 +++++
 include/hw/xen/xen-bus.h     |   5 +-
 include/qemu/module.h        |   3 +
 7 files changed, 305 insertions(+), 21 deletions(-)
 create mode 100644 hw/xen/xen-backend.c
 create mode 100644 include/hw/xen/xen-backend.h

diff --git a/hw/xen/Makefile.objs b/hw/xen/Makefile.objs
index 77c0868190..84df60a928 100644
--- a/hw/xen/Makefile.objs
+++ b/hw/xen/Makefile.objs
@@ -1,5 +1,5 @@
 # xen backend driver support
-common-obj-$(CONFIG_XEN) += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o xen-common.o xen-bus.o xen-bus-helper.o
+common-obj-$(CONFIG_XEN) += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o xen-common.o xen-bus.o xen-bus-helper.o xen-backend.o
 
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_graphics.o xen_pt_msi.o
diff --git a/hw/xen/trace-events b/hw/xen/trace-events
index 94c46c2e34..5b12135083 100644
--- a/hw/xen/trace-events
+++ b/hw/xen/trace-events
@@ -16,11 +16,16 @@ xen_domid_restrict(int err) "err: %u"
 # include/hw/xen/xen-bus.c
 xen_bus_realize(void) ""
 xen_bus_unrealize(void) ""
+xen_bus_enumerate(void) ""
+xen_bus_type_enumerate(const char *type) "type: %s"
+xen_bus_backend_create(const char *type, const char *path) "type: %s path: %s"
 xen_bus_add_watch(const char *node, const char *key, char *token) "node: %s key: %s token: %s"
 xen_bus_remove_watch(const char *node, const char *key, char *token) "node: %s key: %s token: %s"
 xen_bus_watch(const char *token) "token: %s"
 xen_device_realize(const char *type, char *name) "type: %s name: %s"
 xen_device_unrealize(const char *type, char *name) "type: %s name: %s"
 xen_device_backend_state(const char *type, char *name, const char *state) "type: %s name: %s -> %s"
+xen_device_backend_online(const char *type, char *name, bool online) "type: %s name: %s -> %u"
 xen_device_frontend_state(const char *type, char *name, const char *state) "type: %s name: %s -> %s"
+xen_device_backend_changed(const char *type, char *name) "type: %s name: %s"
 xen_device_frontend_changed(const char *type, char *name) "type: %s name: %s"
diff --git a/hw/xen/xen-backend.c b/hw/xen/xen-backend.c
new file mode 100644
index 0000000000..7581fd390d
--- /dev/null
+++ b/hw/xen/xen-backend.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "hw/xen/xen-backend.h"
+
+typedef struct XenBackendImpl {
+    const char *type;
+    XenBackendDeviceCreate create;
+} XenBackendImpl;
+
+static GHashTable *xen_backend_table_get(void)
+{
+    static GHashTable *table;
+
+    if (table == NULL) {
+        table = g_hash_table_new(g_str_hash, g_str_equal);
+    }
+
+    return table;
+}
+
+static void xen_backend_table_add(XenBackendImpl *impl)
+{
+    g_hash_table_insert(xen_backend_table_get(), (void *)impl->type, impl);
+}
+
+static XenBackendImpl *xen_backend_table_lookup(const char *type)
+{
+    return g_hash_table_lookup(xen_backend_table_get(), type);
+}
+
+void xen_backend_register(const XenBackendInfo *info)
+{
+    XenBackendImpl *impl = g_new0(XenBackendImpl, 1);
+
+    g_assert(info->type);
+
+    if (xen_backend_table_lookup(info->type)) {
+        error_report("attempt to register duplicate Xen backend type '%s'",
+                     info->type);
+        abort();
+    }
+
+    if (!info->create) {
+        error_report("backend type '%s' has no creator", info->type);
+        abort();
+    }
+
+    impl->type = info->type;
+    impl->create = info->create;
+
+    xen_backend_table_add(impl);
+}
+
+void xen_backend_device_create(BusState *bus, const char *type,
+                               const char *name, QDict *opts, Error **errp)
+{
+    XenBackendImpl *impl = xen_backend_table_lookup(type);
+
+    if (impl) {
+        impl->create(bus, name, opts, errp);
+    }
+}
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index c4b253103f..e58b891c93 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -10,10 +10,12 @@
 #include "hw/hw.h"
 #include "hw/sysbus.h"
 #include "hw/xen/xen.h"
+#include "hw/xen/xen-backend.h"
 #include "hw/xen/xen-bus.h"
 #include "hw/xen/xen-bus-helper.h"
 #include "monitor/monitor.h"
 #include "qapi/error.h"
+#include "qapi/qmp/qdict.h"
 #include "sysemu/sysemu.h"
 #include "trace.h"
 
@@ -132,12 +134,118 @@ static void xen_bus_remove_watch(XenBus *xenbus, XenWatch *watch)
     g_free(watch);
 }
 
+static void xen_bus_backend_create(XenBus *xenbus, const char *type,
+                                   const char *name, char *path)
+{
+    char **key;
+    QDict *opts;
+    unsigned int i, n;
+    Error *local_err = NULL;
+
+    trace_xen_bus_backend_create(type, path);
+
+    key = xs_directory(xenbus->xsh, XBT_NULL, path, &n);
+    if (!key) {
+        return;
+    }
+
+    opts = qdict_new();
+    for (i = 0; i < n; i++) {
+        char *val;
+
+        /*
+         * Assume anything found in the xenstore backend area, other than
+         * the keys created for a generic XenDevice, are parameters
+         * to be used to configure the backend.
+         */
+        if (!strcmp(key[i], "state") ||
+            !strcmp(key[i], "online") ||
+            !strcmp(key[i], "frontend") ||
+            !strcmp(key[i], "frontend-id") ||
+            !strcmp(key[i], "hotplug-status"))
+            continue;
+
+        if (xs_node_scanf(xenbus->xsh, path, key[i], "%ms", &val) == 1) {
+            qdict_put_str(opts, key[i], val);
+            free(val);
+        }
+    }
+
+    xen_backend_device_create(BUS(xenbus), type, name, opts, &local_err);
+    qobject_unref(opts);
+
+    if (local_err) {
+        const char *msg = error_get_pretty(local_err);
+
+        error_report("failed to create '%s' device '%s': %s", type, name,
+                     msg);
+        error_free(local_err);
+    }
+}
+
+static void xen_bus_type_enumerate(XenBus *xenbus, const char *type)
+{
+    char *domain_path = g_strdup_printf("backend/%s/%u", type, xen_domid);
+    char **backend;
+    unsigned int i, n;
+
+    trace_xen_bus_type_enumerate(type);
+
+    backend = xs_directory(xenbus->xsh, XBT_NULL, domain_path, &n);
+    if (!backend) {
+        return;
+    }
+
+    for (i = 0; i < n; i++) {
+        char *backend_path = g_strdup_printf("%s/%s", domain_path,
+                                             backend[i]);
+        enum xenbus_state backend_state;
+
+        if (xs_node_scanf(xenbus->xsh, backend_path, "state", "%u",
+                          &backend_state) != 1)
+            backend_state = XenbusStateUnknown;
+
+        if (backend_state == XenbusStateInitialising) {
+            xen_bus_backend_create(xenbus, type, backend[i], backend_path);
+        }
+
+        g_free(backend_path);
+    }
+
+    free(backend);
+    g_free(domain_path);
+}
+
+static void xen_bus_enumerate(void *opaque)
+{
+    XenBus *xenbus = opaque;
+    char **type;
+    unsigned int i, n;
+
+    trace_xen_bus_enumerate();
+
+    type = xs_directory(xenbus->xsh, XBT_NULL, "backend", &n);
+    if (!type) {
+        return;
+    }
+
+    for (i = 0; i < n; i++) {
+        xen_bus_type_enumerate(xenbus, type[i]);
+    }
+
+    free(type);
+}
+
 static void xen_bus_unrealize(BusState *bus, Error **errp)
 {
     XenBus *xenbus = XEN_BUS(bus);
 
     trace_xen_bus_unrealize();
 
+    if (xenbus->backend_watch) {
+        xen_bus_remove_watch(xenbus, xenbus->backend_watch);
+    }
+
     if (!xenbus->xsh) {
         return;
     }
@@ -174,6 +282,7 @@ static void xen_bus_realize(BusState *bus, Error **errp)
 {
     XenBus *xenbus = XEN_BUS(bus);
     unsigned int domid;
+    Error *local_err = NULL;
 
     trace_xen_bus_realize();
 
@@ -193,6 +302,17 @@ static void xen_bus_realize(BusState *bus, Error **errp)
     notifier_list_init(&xenbus->watch_notifiers);
     qemu_set_fd_handler(xs_fileno(xenbus->xsh), xen_bus_watch, NULL,
                         xenbus);
+
+    module_call_init(MODULE_INIT_XEN_BACKEND);
+
+    xenbus->backend_watch =
+        xen_bus_add_watch(xenbus, "", /* domain root node */
+                          "backend", xen_bus_enumerate, xenbus, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to set up enumeration watch: ");
+    }
+
     return;
 
 fail:
@@ -268,6 +388,60 @@ enum xenbus_state xen_device_backend_get_state(XenDevice *xendev)
     return xendev->backend_state;
 }
 
+static void xen_device_backend_set_online(XenDevice *xendev, bool online)
+{
+    const char *type = object_get_typename(OBJECT(xendev));
+
+    if (xendev->backend_online == online) {
+        return;
+    }
+
+    trace_xen_device_backend_online(type, xendev->name, online);
+
+    xendev->backend_online = online;
+    xen_device_backend_printf(xendev, "online", "%u", online);
+}
+
+static void xen_device_backend_changed(void *opaque)
+{
+    XenDevice *xendev = opaque;
+    const char *type = object_get_typename(OBJECT(xendev));
+    enum xenbus_state state;
+    unsigned int online;
+
+    trace_xen_device_backend_changed(type, xendev->name);
+
+    if (xen_device_backend_scanf(xendev, "state", "%u", &state) != 1) {
+        state = XenbusStateUnknown;
+    }
+
+    xen_device_backend_set_state(xendev, state);
+
+    if (xen_device_backend_scanf(xendev, "online", "%u", &online) != 1) {
+        online = 0;
+    }
+
+    xen_device_backend_set_online(xendev, !!online);
+
+    /*
+     * If a backend is still 'online' then its state should be cycled
+     * back round to InitWait in order for a new frontend instance to
+     * connect. This may happen when, for example, a frontend driver is
+     * re-installed or updated.
+     * If a backend id not 'online' then the device should be destroyed.
+     */
+    if (xendev->backend_online &&
+        xendev->backend_state == XenbusStateClosed) {
+        xen_device_backend_set_state(xendev, XenbusStateInitWait);
+    } else if (!xendev->backend_online &&
+               (xendev->backend_state == XenbusStateClosed ||
+                xendev->backend_state == XenbusStateInitialising ||
+                xendev->backend_state == XenbusStateInitWait ||
+                xendev->backend_state == XenbusStateUnknown)) {
+        object_unparent(OBJECT(xendev));
+    }
+}
+
 static void xen_device_backend_create(XenDevice *xendev, Error **errp)
 {
     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
@@ -289,12 +463,38 @@ static void xen_device_backend_create(XenDevice *xendev, Error **errp)
         error_propagate(errp, local_err);
         error_prepend(errp, "failed to create backend: ");
     }
+
+    xendev->backend_state_watch =
+        xen_bus_add_watch(xenbus, xendev->backend_path,
+                          "state", xen_device_backend_changed,
+                          xendev, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to watch backend state: ");
+    }
+
+    xendev->backend_online_watch =
+        xen_bus_add_watch(xenbus, xendev->backend_path,
+                          "online", xen_device_backend_changed,
+                          xendev, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to watch backend online: ");
+    }
 }
 
 static void xen_device_backend_destroy(XenDevice *xendev)
 {
     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
 
+    if (xendev->backend_online_watch) {
+        xen_bus_remove_watch(xenbus, xendev->backend_online_watch);
+    }
+
+    if (xendev->backend_state_watch) {
+        xen_bus_remove_watch(xenbus, xendev->backend_state_watch);
+    }
+
     if (!xendev->backend_path) {
         return;
     }
@@ -378,24 +578,6 @@ static void xen_device_frontend_changed(void *opaque)
             error_free(local_err);
         }
     }
-
-    /*
-     * If a backend is still 'online' then its state should be cycled
-     * back round to InitWait in order for a new frontend instance to
-     * connect. This may happen when, for example, a frontend driver is
-     * re-installed or updated.
-     */
-    if (xendev->backend_state == XenbusStateClosed) {
-        unsigned int online;
-
-        if (xen_device_backend_scanf(xendev, "online", "%u", &online) != 1) {
-            online = 0;
-        }
-
-        if (online) {
-            xen_device_backend_set_state(xendev, XenbusStateInitWait);
-        }
-    }
 }
 
 static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
@@ -764,9 +946,9 @@ static void xen_device_realize(DeviceState *dev, Error **errp)
                               xendev->frontend_path);
     xen_device_backend_printf(xendev, "frontend-id", "%u",
                               xendev->frontend_id);
-    xen_device_backend_printf(xendev, "online", "%u", 1);
     xen_device_backend_printf(xendev, "hotplug-status", "connected");
 
+    xen_device_backend_set_online(xendev, true);
     xen_device_backend_set_state(xendev, XenbusStateInitWait);
 
     xen_device_frontend_printf(xendev, "backend", "%s",
diff --git a/include/hw/xen/xen-backend.h b/include/hw/xen/xen-backend.h
new file mode 100644
index 0000000000..ca5ae34398
--- /dev/null
+++ b/include/hw/xen/xen-backend.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ */
+
+#ifndef HW_XEN_BACKEND_H
+#define HW_XEN_BACKEND_H
+
+#include "hw/xen/xen-bus.h"
+
+typedef void (*XenBackendDeviceCreate)(BusState *bus, const char *name,
+                                       QDict *opts, Error **errp);
+
+typedef struct XenBackendInfo {
+    const char *type;
+    XenBackendDeviceCreate create;
+} XenBackendInfo;
+
+void xen_backend_register(const XenBackendInfo *info);
+
+void xen_backend_device_create(BusState *bus, const char *type,
+                               const char *name, QDict *opts, Error **errp);
+
+#endif /* HW_XEN_BACKEND_H */
diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h
index d931e01268..48f3e068d3 100644
--- a/include/hw/xen/xen-bus.h
+++ b/include/hw/xen/xen-bus.h
@@ -21,7 +21,9 @@ typedef struct XenDevice {
     char *backend_path, *frontend_path;
     enum xenbus_state backend_state, frontend_state;
     Notifier exit;
-    XenWatch *frontend_state_watch;
+    XenWatch *backend_state_watch, *frontend_state_watch;
+    bool backend_online;
+    XenWatch *backend_online_watch;
     xengnttab_handle *xgth;
     bool feature_grant_copy;
     xenevtchn_handle *xeh;
@@ -61,6 +63,7 @@ typedef struct XenBus {
     domid_t backend_id;
     struct xs_handle *xsh;
     NotifierList watch_notifiers;
+    XenWatch *backend_watch;
 } XenBus;
 
 typedef struct XenBusClass {
diff --git a/include/qemu/module.h b/include/qemu/module.h
index 54300ab6e5..55dd2beea8 100644
--- a/include/qemu/module.h
+++ b/include/qemu/module.h
@@ -44,6 +44,7 @@ typedef enum {
     MODULE_INIT_OPTS,
     MODULE_INIT_QOM,
     MODULE_INIT_TRACE,
+    MODULE_INIT_XEN_BACKEND,
     MODULE_INIT_MAX
 } module_init_type;
 
@@ -51,6 +52,8 @@ typedef enum {
 #define opts_init(function) module_init(function, MODULE_INIT_OPTS)
 #define type_init(function) module_init(function, MODULE_INIT_QOM)
 #define trace_init(function) module_init(function, MODULE_INIT_TRACE)
+#define xen_backend_init(function) module_init(function, \
+                                               MODULE_INIT_XEN_BACKEND)
 
 #define block_module_load_one(lib) module_load_one("block-", lib)
 #define ui_module_load_one(lib) module_load_one("ui-", lib)
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [Qemu-devel] [PATCH 16/18] xen: automatically create XenQdiskDevice-s
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
                   ` (21 preceding siblings ...)
  2018-11-21 15:12   ` Paul Durrant
@ 2018-11-21 15:12 ` Paul Durrant
  2018-12-04 16:40     ` Anthony PERARD
  2018-11-21 15:12 ` Paul Durrant
                   ` (2 subsequent siblings)
  25 siblings, 1 reply; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Paul Durrant, Kevin Wolf, Max Reitz, Stefano Stabellini, Anthony Perard

This patch adds a creator function for XenQdiskDevice-s so that they can
be created automatically when the Xen toolstack instantiates a new
PV backend. When the XenQdiskDevice is created this way it is also
necessary to create a drive which matches the configuration that the Xen
toolstack has written into xenstore. This drive is marked 'auto_del' so
that it will be removed when the XenQdiskDevice is destroyed. Also, for
compatibilitye with the legacy 'xen_disk' implementation, an iothread
is automatically created for the new XenQdiskDevice. This will also be
removed when he XenQdiskDevice is destroyed.

Correspondingly the legacy backend scan for 'qdisk' is removed.

After this patch is applied the legacy 'xen_disk' code is redundant. It
will be removed by a subsequent patch.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
---
 hw/block/trace-events       |   1 +
 hw/block/xen-qdisk.c        | 237 +++++++++++++++++++++++++++++++++++++++++++-
 hw/xen/xen-legacy-backend.c |   1 -
 include/hw/xen/xen-qdisk.h  |   1 +
 4 files changed, 238 insertions(+), 2 deletions(-)

diff --git a/hw/block/trace-events b/hw/block/trace-events
index 8b95567560..ee2ac756cf 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -133,3 +133,4 @@ xen_qdisk_realize(uint32_t disk, uint32_t partition) "d%up%u"
 xen_qdisk_connect(uint32_t disk, uint32_t partition) "d%up%u"
 xen_qdisk_disconnect(uint32_t disk, uint32_t partition) "d%up%u"
 xen_qdisk_unrealize(uint32_t disk, uint32_t partition) "d%up%u"
+xen_qdisk_device_create(const char *name) "name: %s"
diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
index 8c88393832..00cdd8181b 100644
--- a/hw/block/xen-qdisk.c
+++ b/hw/block/xen-qdisk.c
@@ -5,9 +5,12 @@
 
 #include "qemu/osdep.h"
 #include "qemu/cutils.h"
+#include "qemu/option.h"
 #include "qapi/error.h"
 #include "qapi/visitor.h"
+#include "qapi/qmp/qdict.h"
 #include "hw/hw.h"
+#include "hw/xen/xen-backend.h"
 #include "hw/xen/xen-qdisk.h"
 #include "sysemu/blockdev.h"
 #include "sysemu/block-backend.h"
@@ -28,6 +31,8 @@ static void xen_qdisk_realize(XenDevice *xendev, Error **errp)
     XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
     XenQdiskVdev *vdev = &qdiskdev->vdev;
     BlockConf *conf = &qdiskdev->conf;
+    IOThread *iothread = qdiskdev->auto_iothread ?
+        qdiskdev->auto_iothread : qdiskdev->iothread;
     DriveInfo *dinfo;
     bool is_cdrom;
     unsigned int info;
@@ -97,7 +102,7 @@ static void xen_qdisk_realize(XenDevice *xendev, Error **errp)
                               size / conf->logical_block_size);
 
     qdiskdev->dataplane = xen_qdisk_dataplane_create(xendev, conf,
-                                                     qdiskdev->iothread);
+                                                     iothread);
 }
 
 static void xen_qdisk_connect(XenQdiskDevice *qdiskdev, Error **errp)
@@ -228,6 +233,11 @@ static void xen_qdisk_unrealize(XenDevice *xendev, Error **errp)
 
     xen_qdisk_dataplane_destroy(qdiskdev->dataplane);
     qdiskdev->dataplane = NULL;
+
+    if (qdiskdev->auto_iothread) {
+        iothread_destroy(qdiskdev->auto_iothread);
+        qdiskdev->auto_iothread = NULL;
+    }
 }
 
 static char *disk_to_vbd_name(unsigned int disk)
@@ -461,3 +471,228 @@ static void xen_qdisk_register_types(void)
 }
 
 type_init(xen_qdisk_register_types)
+
+static void xen_qdisk_drive_create(const char *id, QDict *opts,
+                                   Error **errp)
+{
+    const char *params, *device_type, *mode, *direct_io_safe,
+        *discard_enable;
+    char *format = NULL;
+    char *file = NULL;
+    char *drive_optstr = NULL;
+    QemuOpts *drive_opts;
+    Error *local_err = NULL;
+
+    params = qdict_get_try_str(opts, "params");
+    if (params) {
+        char **v = g_strsplit(params, ":", 2);
+
+        if (v[1] == NULL) {
+            file = g_strdup(v[0]);
+        } else {
+            if (strcmp(v[0], "aio") == 0) {
+                format = g_strdup("raw");
+            } else if (strcmp(v[0], "vhd") == 0) {
+                format = g_strdup("vpc");
+            } else {
+                format = g_strdup(v[0]);
+            }
+            file = g_strdup(v[1]);
+        }
+
+        g_strfreev(v);
+    }
+
+    if (!file) {
+        error_setg(errp, "no file parameter");
+        return;
+    }
+
+    drive_optstr = g_strdup_printf("id=%s", id);
+    drive_opts = drive_def(drive_optstr);
+    if (!drive_opts) {
+        error_setg(errp, "failed to create drive options");
+        goto done;
+    }
+
+    qemu_opt_set(drive_opts, "file", file, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to set 'file': ");
+        goto done;
+    }
+
+    if (format) {
+        qemu_opt_set(drive_opts, "format", format, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            error_prepend(errp, "failed to set 'format': ");
+            goto done;
+        }
+    }
+
+    device_type = qdict_get_try_str(opts, "device-type");
+    if (device_type) {
+        qemu_opt_set(drive_opts, "media", device_type, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            error_prepend(errp, "failed to set 'media': ");
+            goto done;
+        }
+    }
+
+    mode = qdict_get_try_str(opts, "mode");
+    if (mode && *mode != 'w') {
+        qemu_opt_set_bool(drive_opts, BDRV_OPT_READ_ONLY, true, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            error_prepend(errp, "failed to set '%s': ", BDRV_OPT_READ_ONLY);
+            goto done;
+        }
+    }
+
+    qemu_opt_set(drive_opts, "file.locking", "off", &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to set 'file.locking': ");
+        goto done;
+    }
+
+    qemu_opt_set_bool(drive_opts, BDRV_OPT_CACHE_WB, true, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to set '%s': ", BDRV_OPT_CACHE_WB);
+        goto done;
+    }
+
+    direct_io_safe = qdict_get_try_str(opts, "direct-io-safe");
+    if (direct_io_safe) {
+        qemu_opt_set_bool(drive_opts, BDRV_OPT_CACHE_DIRECT, true,
+                          &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            error_prepend(errp, "failed to set '%s': ",
+                          BDRV_OPT_CACHE_DIRECT);
+            goto done;
+        }
+
+        qemu_opt_set(drive_opts, "aio", "native", &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            error_prepend(errp, "failed to set 'aio': ");
+            goto done;
+        }
+    }
+
+    discard_enable = qdict_get_try_str(opts, "discard-enable");
+    if (discard_enable) {
+        unsigned long value;
+
+        if (!qemu_strtoul(discard_enable, NULL, 2, &value)) {
+            qemu_opt_set_bool(drive_opts, BDRV_OPT_DISCARD, !!value,
+                              &local_err);
+            if (local_err) {
+                error_propagate(errp, local_err);
+                error_prepend(errp, "failed to set '%s': ",
+                              BDRV_OPT_DISCARD);
+                goto done;
+            }
+        }
+    }
+
+    drive_new(drive_opts, IF_NONE, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to create drive: ");
+        goto done;
+    }
+
+done:
+    g_free(drive_optstr);
+    g_free(format);
+    g_free(file);
+}
+
+static void xen_qdisk_device_create(BusState *bus, const char *name,
+                                    QDict *opts, Error **errp)
+{
+    unsigned long number;
+    const char *vdev;
+    BlockBackend *blk = NULL;
+    IOThread *iothread = NULL;
+    DeviceState *dev = NULL;
+    Error *local_err = NULL;
+
+    trace_xen_qdisk_device_create(name);
+
+    if (qemu_strtoul(name, NULL, 10, &number)) {
+        error_setg(errp, "failed to parse name '%s'", name);
+        return;
+    }
+
+    vdev = qdict_get_try_str(opts, "dev");
+    if (!vdev) {
+        error_setg(errp, "no dev parameter");
+        return;
+    }
+
+    xen_qdisk_drive_create(vdev, opts, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    blk = blk_by_name(vdev);
+    g_assert(blk);
+
+    iothread = iothread_create(vdev, &error_abort);
+
+    dev = qdev_create(bus, TYPE_XEN_QDISK_DEVICE);
+
+    qdev_prop_set_string(dev, "vdev", vdev);
+
+    if (XEN_QDISK_DEVICE(dev)->vdev.number != number) {
+        error_setg(errp, "invalid dev parameter '%s'", vdev);
+        goto unref;
+    }
+
+    qdev_prop_set_drive(dev, "drive", blk, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to set 'drive': ");
+        goto unref;
+    }
+
+    XEN_QDISK_DEVICE(dev)->auto_iothread = iothread;
+
+    qdev_init_nofail(dev);
+
+    blockdev_mark_auto_del(blk);
+    return;
+
+unref:
+    if (dev) {
+        object_unparent(OBJECT(dev));
+    }
+
+    if (iothread) {
+        iothread_destroy(iothread);
+    }
+
+    if (blk) {
+        monitor_remove_blk(blk);
+        blk_unref(blk);
+    }
+}
+
+static const XenBackendInfo xen_qdisk_backend_info = {
+    .type = "qdisk",
+    .create = xen_qdisk_device_create,
+};
+
+static void xen_qdisk_register_backend(void)
+{
+    xen_backend_register(&xen_qdisk_backend_info);
+}
+
+xen_backend_init(xen_qdisk_register_backend);
diff --git a/hw/xen/xen-legacy-backend.c b/hw/xen/xen-legacy-backend.c
index 2d748665a6..cc0add0a5b 100644
--- a/hw/xen/xen-legacy-backend.c
+++ b/hw/xen/xen-legacy-backend.c
@@ -753,7 +753,6 @@ void xen_be_register_common(void)
 
     xen_be_register("console", &xen_console_ops);
     xen_be_register("vkbd", &xen_kbdmouse_ops);
-    xen_be_register("qdisk", &xen_blkdev_ops);
 #ifdef CONFIG_VIRTFS
     xen_be_register("9pfs", &xen_9pfs_ops);
 #endif
diff --git a/include/hw/xen/xen-qdisk.h b/include/hw/xen/xen-qdisk.h
index d7dd2bf0ee..c7bc011731 100644
--- a/include/hw/xen/xen-qdisk.h
+++ b/include/hw/xen/xen-qdisk.h
@@ -44,6 +44,7 @@ struct XenQdiskDevice {
     BlockConf conf;
     unsigned int max_ring_page_order;
     IOThread *iothread;
+    IOThread *auto_iothread;
     XenQdiskDataPlane *dataplane;
 };
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [PATCH 16/18] xen: automatically create XenQdiskDevice-s
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
                   ` (22 preceding siblings ...)
  2018-11-21 15:12 ` [Qemu-devel] [PATCH 16/18] xen: automatically create XenQdiskDevice-s Paul Durrant
@ 2018-11-21 15:12 ` Paul Durrant
  2018-11-21 15:12   ` Paul Durrant
  2018-11-21 15:12   ` Paul Durrant
  25 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Kevin Wolf, Anthony Perard, Paul Durrant, Stefano Stabellini, Max Reitz

This patch adds a creator function for XenQdiskDevice-s so that they can
be created automatically when the Xen toolstack instantiates a new
PV backend. When the XenQdiskDevice is created this way it is also
necessary to create a drive which matches the configuration that the Xen
toolstack has written into xenstore. This drive is marked 'auto_del' so
that it will be removed when the XenQdiskDevice is destroyed. Also, for
compatibilitye with the legacy 'xen_disk' implementation, an iothread
is automatically created for the new XenQdiskDevice. This will also be
removed when he XenQdiskDevice is destroyed.

Correspondingly the legacy backend scan for 'qdisk' is removed.

After this patch is applied the legacy 'xen_disk' code is redundant. It
will be removed by a subsequent patch.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
---
 hw/block/trace-events       |   1 +
 hw/block/xen-qdisk.c        | 237 +++++++++++++++++++++++++++++++++++++++++++-
 hw/xen/xen-legacy-backend.c |   1 -
 include/hw/xen/xen-qdisk.h  |   1 +
 4 files changed, 238 insertions(+), 2 deletions(-)

diff --git a/hw/block/trace-events b/hw/block/trace-events
index 8b95567560..ee2ac756cf 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -133,3 +133,4 @@ xen_qdisk_realize(uint32_t disk, uint32_t partition) "d%up%u"
 xen_qdisk_connect(uint32_t disk, uint32_t partition) "d%up%u"
 xen_qdisk_disconnect(uint32_t disk, uint32_t partition) "d%up%u"
 xen_qdisk_unrealize(uint32_t disk, uint32_t partition) "d%up%u"
+xen_qdisk_device_create(const char *name) "name: %s"
diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
index 8c88393832..00cdd8181b 100644
--- a/hw/block/xen-qdisk.c
+++ b/hw/block/xen-qdisk.c
@@ -5,9 +5,12 @@
 
 #include "qemu/osdep.h"
 #include "qemu/cutils.h"
+#include "qemu/option.h"
 #include "qapi/error.h"
 #include "qapi/visitor.h"
+#include "qapi/qmp/qdict.h"
 #include "hw/hw.h"
+#include "hw/xen/xen-backend.h"
 #include "hw/xen/xen-qdisk.h"
 #include "sysemu/blockdev.h"
 #include "sysemu/block-backend.h"
@@ -28,6 +31,8 @@ static void xen_qdisk_realize(XenDevice *xendev, Error **errp)
     XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
     XenQdiskVdev *vdev = &qdiskdev->vdev;
     BlockConf *conf = &qdiskdev->conf;
+    IOThread *iothread = qdiskdev->auto_iothread ?
+        qdiskdev->auto_iothread : qdiskdev->iothread;
     DriveInfo *dinfo;
     bool is_cdrom;
     unsigned int info;
@@ -97,7 +102,7 @@ static void xen_qdisk_realize(XenDevice *xendev, Error **errp)
                               size / conf->logical_block_size);
 
     qdiskdev->dataplane = xen_qdisk_dataplane_create(xendev, conf,
-                                                     qdiskdev->iothread);
+                                                     iothread);
 }
 
 static void xen_qdisk_connect(XenQdiskDevice *qdiskdev, Error **errp)
@@ -228,6 +233,11 @@ static void xen_qdisk_unrealize(XenDevice *xendev, Error **errp)
 
     xen_qdisk_dataplane_destroy(qdiskdev->dataplane);
     qdiskdev->dataplane = NULL;
+
+    if (qdiskdev->auto_iothread) {
+        iothread_destroy(qdiskdev->auto_iothread);
+        qdiskdev->auto_iothread = NULL;
+    }
 }
 
 static char *disk_to_vbd_name(unsigned int disk)
@@ -461,3 +471,228 @@ static void xen_qdisk_register_types(void)
 }
 
 type_init(xen_qdisk_register_types)
+
+static void xen_qdisk_drive_create(const char *id, QDict *opts,
+                                   Error **errp)
+{
+    const char *params, *device_type, *mode, *direct_io_safe,
+        *discard_enable;
+    char *format = NULL;
+    char *file = NULL;
+    char *drive_optstr = NULL;
+    QemuOpts *drive_opts;
+    Error *local_err = NULL;
+
+    params = qdict_get_try_str(opts, "params");
+    if (params) {
+        char **v = g_strsplit(params, ":", 2);
+
+        if (v[1] == NULL) {
+            file = g_strdup(v[0]);
+        } else {
+            if (strcmp(v[0], "aio") == 0) {
+                format = g_strdup("raw");
+            } else if (strcmp(v[0], "vhd") == 0) {
+                format = g_strdup("vpc");
+            } else {
+                format = g_strdup(v[0]);
+            }
+            file = g_strdup(v[1]);
+        }
+
+        g_strfreev(v);
+    }
+
+    if (!file) {
+        error_setg(errp, "no file parameter");
+        return;
+    }
+
+    drive_optstr = g_strdup_printf("id=%s", id);
+    drive_opts = drive_def(drive_optstr);
+    if (!drive_opts) {
+        error_setg(errp, "failed to create drive options");
+        goto done;
+    }
+
+    qemu_opt_set(drive_opts, "file", file, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to set 'file': ");
+        goto done;
+    }
+
+    if (format) {
+        qemu_opt_set(drive_opts, "format", format, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            error_prepend(errp, "failed to set 'format': ");
+            goto done;
+        }
+    }
+
+    device_type = qdict_get_try_str(opts, "device-type");
+    if (device_type) {
+        qemu_opt_set(drive_opts, "media", device_type, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            error_prepend(errp, "failed to set 'media': ");
+            goto done;
+        }
+    }
+
+    mode = qdict_get_try_str(opts, "mode");
+    if (mode && *mode != 'w') {
+        qemu_opt_set_bool(drive_opts, BDRV_OPT_READ_ONLY, true, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            error_prepend(errp, "failed to set '%s': ", BDRV_OPT_READ_ONLY);
+            goto done;
+        }
+    }
+
+    qemu_opt_set(drive_opts, "file.locking", "off", &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to set 'file.locking': ");
+        goto done;
+    }
+
+    qemu_opt_set_bool(drive_opts, BDRV_OPT_CACHE_WB, true, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to set '%s': ", BDRV_OPT_CACHE_WB);
+        goto done;
+    }
+
+    direct_io_safe = qdict_get_try_str(opts, "direct-io-safe");
+    if (direct_io_safe) {
+        qemu_opt_set_bool(drive_opts, BDRV_OPT_CACHE_DIRECT, true,
+                          &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            error_prepend(errp, "failed to set '%s': ",
+                          BDRV_OPT_CACHE_DIRECT);
+            goto done;
+        }
+
+        qemu_opt_set(drive_opts, "aio", "native", &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            error_prepend(errp, "failed to set 'aio': ");
+            goto done;
+        }
+    }
+
+    discard_enable = qdict_get_try_str(opts, "discard-enable");
+    if (discard_enable) {
+        unsigned long value;
+
+        if (!qemu_strtoul(discard_enable, NULL, 2, &value)) {
+            qemu_opt_set_bool(drive_opts, BDRV_OPT_DISCARD, !!value,
+                              &local_err);
+            if (local_err) {
+                error_propagate(errp, local_err);
+                error_prepend(errp, "failed to set '%s': ",
+                              BDRV_OPT_DISCARD);
+                goto done;
+            }
+        }
+    }
+
+    drive_new(drive_opts, IF_NONE, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to create drive: ");
+        goto done;
+    }
+
+done:
+    g_free(drive_optstr);
+    g_free(format);
+    g_free(file);
+}
+
+static void xen_qdisk_device_create(BusState *bus, const char *name,
+                                    QDict *opts, Error **errp)
+{
+    unsigned long number;
+    const char *vdev;
+    BlockBackend *blk = NULL;
+    IOThread *iothread = NULL;
+    DeviceState *dev = NULL;
+    Error *local_err = NULL;
+
+    trace_xen_qdisk_device_create(name);
+
+    if (qemu_strtoul(name, NULL, 10, &number)) {
+        error_setg(errp, "failed to parse name '%s'", name);
+        return;
+    }
+
+    vdev = qdict_get_try_str(opts, "dev");
+    if (!vdev) {
+        error_setg(errp, "no dev parameter");
+        return;
+    }
+
+    xen_qdisk_drive_create(vdev, opts, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    blk = blk_by_name(vdev);
+    g_assert(blk);
+
+    iothread = iothread_create(vdev, &error_abort);
+
+    dev = qdev_create(bus, TYPE_XEN_QDISK_DEVICE);
+
+    qdev_prop_set_string(dev, "vdev", vdev);
+
+    if (XEN_QDISK_DEVICE(dev)->vdev.number != number) {
+        error_setg(errp, "invalid dev parameter '%s'", vdev);
+        goto unref;
+    }
+
+    qdev_prop_set_drive(dev, "drive", blk, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "failed to set 'drive': ");
+        goto unref;
+    }
+
+    XEN_QDISK_DEVICE(dev)->auto_iothread = iothread;
+
+    qdev_init_nofail(dev);
+
+    blockdev_mark_auto_del(blk);
+    return;
+
+unref:
+    if (dev) {
+        object_unparent(OBJECT(dev));
+    }
+
+    if (iothread) {
+        iothread_destroy(iothread);
+    }
+
+    if (blk) {
+        monitor_remove_blk(blk);
+        blk_unref(blk);
+    }
+}
+
+static const XenBackendInfo xen_qdisk_backend_info = {
+    .type = "qdisk",
+    .create = xen_qdisk_device_create,
+};
+
+static void xen_qdisk_register_backend(void)
+{
+    xen_backend_register(&xen_qdisk_backend_info);
+}
+
+xen_backend_init(xen_qdisk_register_backend);
diff --git a/hw/xen/xen-legacy-backend.c b/hw/xen/xen-legacy-backend.c
index 2d748665a6..cc0add0a5b 100644
--- a/hw/xen/xen-legacy-backend.c
+++ b/hw/xen/xen-legacy-backend.c
@@ -753,7 +753,6 @@ void xen_be_register_common(void)
 
     xen_be_register("console", &xen_console_ops);
     xen_be_register("vkbd", &xen_kbdmouse_ops);
-    xen_be_register("qdisk", &xen_blkdev_ops);
 #ifdef CONFIG_VIRTFS
     xen_be_register("9pfs", &xen_9pfs_ops);
 #endif
diff --git a/include/hw/xen/xen-qdisk.h b/include/hw/xen/xen-qdisk.h
index d7dd2bf0ee..c7bc011731 100644
--- a/include/hw/xen/xen-qdisk.h
+++ b/include/hw/xen/xen-qdisk.h
@@ -44,6 +44,7 @@ struct XenQdiskDevice {
     BlockConf conf;
     unsigned int max_ring_page_order;
     IOThread *iothread;
+    IOThread *auto_iothread;
     XenQdiskDataPlane *dataplane;
 };
 
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [Qemu-devel] [PATCH 17/18] MAINTAINERS: add myself as a Xen maintainer
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
@ 2018-11-21 15:12   ` Paul Durrant
  2018-11-21 15:11 ` [Qemu-devel] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy Paul Durrant
                     ` (24 subsequent siblings)
  25 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Paul Durrant, Stefano Stabellini, Anthony Perard, Paolo Bonzini

I have made many significant contributions to the Xen code in QEMU,
particularly the recent patches introducing a new PV device framework.
I intend to make further significant contributions, porting other PV back-
ends to the new framework with the intent of eventually removing the
legacy code. It therefore seems reasonable that I become a maintiner of
the Xen code.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 5871f035c3..0b668dd205 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -382,6 +382,7 @@ Guest CPU Cores (Xen):
 X86
 M: Stefano Stabellini <sstabellini@kernel.org>
 M: Anthony Perard <anthony.perard@citrix.com>
+M: Paul Durrant <paul.durrant@citrix.com>
 L: xen-devel@lists.xenproject.org
 S: Supported
 F: */xen*
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [PATCH 17/18] MAINTAINERS: add myself as a Xen maintainer
@ 2018-11-21 15:12   ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel
  Cc: Anthony Perard, Paolo Bonzini, Paul Durrant, Stefano Stabellini

I have made many significant contributions to the Xen code in QEMU,
particularly the recent patches introducing a new PV device framework.
I intend to make further significant contributions, porting other PV back-
ends to the new framework with the intent of eventually removing the
legacy code. It therefore seems reasonable that I become a maintiner of
the Xen code.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 5871f035c3..0b668dd205 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -382,6 +382,7 @@ Guest CPU Cores (Xen):
 X86
 M: Stefano Stabellini <sstabellini@kernel.org>
 M: Anthony Perard <anthony.perard@citrix.com>
+M: Paul Durrant <paul.durrant@citrix.com>
 L: xen-devel@lists.xenproject.org
 S: Supported
 F: */xen*
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [Qemu-devel] [PATCH 18/18] xen: remove the legacy 'xen_disk' backend
  2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
@ 2018-11-21 15:12   ` Paul Durrant
  2018-11-21 15:11 ` [Qemu-devel] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy Paul Durrant
                     ` (24 subsequent siblings)
  25 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel; +Cc: Paul Durrant, Kevin Wolf, Max Reitz

This backend has now been replaced by the 'xen-qdisk' XenDevice.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
---
 hw/block/Makefile.objs |    1 -
 hw/block/xen_disk.c    | 1011 ------------------------------------------------
 2 files changed, 1012 deletions(-)
 delete mode 100644 hw/block/xen_disk.c

diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs
index bcdd36d318..d9d2f3fde5 100644
--- a/hw/block/Makefile.objs
+++ b/hw/block/Makefile.objs
@@ -4,7 +4,6 @@ common-obj-$(CONFIG_SSI_M25P80) += m25p80.o
 common-obj-$(CONFIG_NAND) += nand.o
 common-obj-$(CONFIG_PFLASH_CFI01) += pflash_cfi01.o
 common-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
-common-obj-$(CONFIG_XEN) += xen_disk.o
 common-obj-$(CONFIG_XEN) += xen-qdisk.o
 common-obj-$(CONFIG_ECC) += ecc.o
 common-obj-$(CONFIG_ONENAND) += onenand.o
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
deleted file mode 100644
index 75fe55f2ae..0000000000
--- a/hw/block/xen_disk.c
+++ /dev/null
@@ -1,1011 +0,0 @@
-/*
- *  xen paravirt block device backend
- *
- *  (c) Gerd Hoffmann <kraxel@redhat.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; under version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- *  Contributions after 2012-01-13 are licensed under the terms of the
- *  GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include "qemu/osdep.h"
-#include "qemu/units.h"
-#include <sys/ioctl.h>
-#include <sys/uio.h>
-
-#include "hw/hw.h"
-#include "hw/xen/xen-legacy-backend.h"
-#include "xen_blkif.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/iothread.h"
-#include "sysemu/block-backend.h"
-#include "qapi/error.h"
-#include "qapi/qmp/qdict.h"
-#include "qapi/qmp/qstring.h"
-#include "trace.h"
-
-/* ------------------------------------------------------------- */
-
-#define BLOCK_SIZE  512
-#define IOCB_COUNT  (BLKIF_MAX_SEGMENTS_PER_REQUEST + 2)
-
-struct ioreq {
-    blkif_request_t     req;
-    int16_t             status;
-
-    /* parsed request */
-    off_t               start;
-    QEMUIOVector        v;
-    void                *buf;
-    size_t              size;
-    int                 presync;
-
-    /* aio status */
-    int                 aio_inflight;
-    int                 aio_errors;
-
-    struct XenBlkDev    *blkdev;
-    QLIST_ENTRY(ioreq)   list;
-    BlockAcctCookie     acct;
-};
-
-#define MAX_RING_PAGE_ORDER 4
-
-struct XenBlkDev {
-    struct XenLegacyDevice    xendev;  /* must be first */
-    char                *params;
-    char                *mode;
-    char                *type;
-    char                *dev;
-    char                *devtype;
-    bool                directiosafe;
-    const char          *fileproto;
-    const char          *filename;
-    unsigned int        ring_ref[1 << MAX_RING_PAGE_ORDER];
-    unsigned int        nr_ring_ref;
-    void                *sring;
-    int64_t             file_blk;
-    int64_t             file_size;
-    int                 protocol;
-    blkif_back_rings_t  rings;
-    int                 more_work;
-
-    /* request lists */
-    QLIST_HEAD(inflight_head, ioreq) inflight;
-    QLIST_HEAD(finished_head, ioreq) finished;
-    QLIST_HEAD(freelist_head, ioreq) freelist;
-    int                 requests_total;
-    int                 requests_inflight;
-    int                 requests_finished;
-    unsigned int        max_requests;
-
-    gboolean            feature_discard;
-
-    /* qemu block driver */
-    DriveInfo           *dinfo;
-    BlockBackend        *blk;
-    QEMUBH              *bh;
-
-    IOThread            *iothread;
-    AioContext          *ctx;
-};
-
-/* ------------------------------------------------------------- */
-
-static void ioreq_reset(struct ioreq *ioreq)
-{
-    memset(&ioreq->req, 0, sizeof(ioreq->req));
-    ioreq->status = 0;
-    ioreq->start = 0;
-    ioreq->buf = NULL;
-    ioreq->size = 0;
-    ioreq->presync = 0;
-
-    ioreq->aio_inflight = 0;
-    ioreq->aio_errors = 0;
-
-    ioreq->blkdev = NULL;
-    memset(&ioreq->list, 0, sizeof(ioreq->list));
-    memset(&ioreq->acct, 0, sizeof(ioreq->acct));
-
-    qemu_iovec_reset(&ioreq->v);
-}
-
-static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
-{
-    struct ioreq *ioreq = NULL;
-
-    if (QLIST_EMPTY(&blkdev->freelist)) {
-        if (blkdev->requests_total >= blkdev->max_requests) {
-            goto out;
-        }
-        /* allocate new struct */
-        ioreq = g_malloc0(sizeof(*ioreq));
-        ioreq->blkdev = blkdev;
-        blkdev->requests_total++;
-        qemu_iovec_init(&ioreq->v, 1);
-    } else {
-        /* get one from freelist */
-        ioreq = QLIST_FIRST(&blkdev->freelist);
-        QLIST_REMOVE(ioreq, list);
-    }
-    QLIST_INSERT_HEAD(&blkdev->inflight, ioreq, list);
-    blkdev->requests_inflight++;
-
-out:
-    return ioreq;
-}
-
-static void ioreq_finish(struct ioreq *ioreq)
-{
-    struct XenBlkDev *blkdev = ioreq->blkdev;
-
-    QLIST_REMOVE(ioreq, list);
-    QLIST_INSERT_HEAD(&blkdev->finished, ioreq, list);
-    blkdev->requests_inflight--;
-    blkdev->requests_finished++;
-}
-
-static void ioreq_release(struct ioreq *ioreq, bool finish)
-{
-    struct XenBlkDev *blkdev = ioreq->blkdev;
-
-    QLIST_REMOVE(ioreq, list);
-    ioreq_reset(ioreq);
-    ioreq->blkdev = blkdev;
-    QLIST_INSERT_HEAD(&blkdev->freelist, ioreq, list);
-    if (finish) {
-        blkdev->requests_finished--;
-    } else {
-        blkdev->requests_inflight--;
-    }
-}
-
-/*
- * translate request into iovec + start offset
- * do sanity checks along the way
- */
-static int ioreq_parse(struct ioreq *ioreq)
-{
-    struct XenBlkDev *blkdev = ioreq->blkdev;
-    struct XenLegacyDevice *xendev = &blkdev->xendev;
-    size_t len;
-    int i;
-
-    xen_pv_printf(xendev, 3,
-                  "op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 "\n",
-                  ioreq->req.operation, ioreq->req.nr_segments,
-                  ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number);
-    switch (ioreq->req.operation) {
-    case BLKIF_OP_READ:
-        break;
-    case BLKIF_OP_FLUSH_DISKCACHE:
-        ioreq->presync = 1;
-        if (!ioreq->req.nr_segments) {
-            return 0;
-        }
-        /* fall through */
-    case BLKIF_OP_WRITE:
-        break;
-    case BLKIF_OP_DISCARD:
-        return 0;
-    default:
-        xen_pv_printf(xendev, 0, "error: unknown operation (%d)\n",
-                      ioreq->req.operation);
-        goto err;
-    };
-
-    if (ioreq->req.operation != BLKIF_OP_READ && blkdev->mode[0] != 'w') {
-        xen_pv_printf(xendev, 0, "error: write req for ro device\n");
-        goto err;
-    }
-
-    ioreq->start = ioreq->req.sector_number * blkdev->file_blk;
-    for (i = 0; i < ioreq->req.nr_segments; i++) {
-        if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
-            xen_pv_printf(xendev, 0, "error: nr_segments too big\n");
-            goto err;
-        }
-        if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) {
-            xen_pv_printf(xendev, 0, "error: first > last sector\n");
-            goto err;
-        }
-        if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >= XC_PAGE_SIZE) {
-            xen_pv_printf(xendev, 0, "error: page crossing\n");
-            goto err;
-        }
-
-        len = (ioreq->req.seg[i].last_sect - ioreq->req.seg[i].first_sect + 1) * blkdev->file_blk;
-        ioreq->size += len;
-    }
-    if (ioreq->start + ioreq->size > blkdev->file_size) {
-        xen_pv_printf(xendev, 0, "error: access beyond end of file\n");
-        goto err;
-    }
-    return 0;
-
-err:
-    ioreq->status = BLKIF_RSP_ERROR;
-    return -1;
-}
-
-static int ioreq_grant_copy(struct ioreq *ioreq)
-{
-    struct XenBlkDev *blkdev = ioreq->blkdev;
-    struct XenLegacyDevice *xendev = &blkdev->xendev;
-    XenGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
-    int i, count, rc;
-    int64_t file_blk = blkdev->file_blk;
-    bool to_domain = (ioreq->req.operation == BLKIF_OP_READ);
-    void *virt = ioreq->buf;
-
-    if (ioreq->req.nr_segments == 0) {
-        return 0;
-    }
-
-    count = ioreq->req.nr_segments;
-
-    for (i = 0; i < count; i++) {
-        if (to_domain) {
-            segs[i].dest.foreign.ref = ioreq->req.seg[i].gref;
-            segs[i].dest.foreign.offset = ioreq->req.seg[i].first_sect * file_blk;
-            segs[i].source.virt = virt;
-        } else {
-            segs[i].source.foreign.ref = ioreq->req.seg[i].gref;
-            segs[i].source.foreign.offset = ioreq->req.seg[i].first_sect * file_blk;
-            segs[i].dest.virt = virt;
-        }
-        segs[i].len = (ioreq->req.seg[i].last_sect
-                       - ioreq->req.seg[i].first_sect + 1) * file_blk;
-        virt += segs[i].len;
-    }
-
-    rc = xen_be_copy_grant_refs(xendev, to_domain, segs, count);
-
-    if (rc) {
-        xen_pv_printf(xendev, 0,
-                      "failed to copy data %d\n", rc);
-        ioreq->aio_errors++;
-        return -1;
-    }
-
-    return rc;
-}
-
-static int ioreq_runio_qemu_aio(struct ioreq *ioreq);
-
-static void qemu_aio_complete(void *opaque, int ret)
-{
-    struct ioreq *ioreq = opaque;
-    struct XenBlkDev *blkdev = ioreq->blkdev;
-    struct XenLegacyDevice *xendev = &blkdev->xendev;
-
-    aio_context_acquire(blkdev->ctx);
-
-    if (ret != 0) {
-        xen_pv_printf(xendev, 0, "%s I/O error\n",
-                      ioreq->req.operation == BLKIF_OP_READ ? "read" : "write");
-        ioreq->aio_errors++;
-    }
-
-    ioreq->aio_inflight--;
-    if (ioreq->presync) {
-        ioreq->presync = 0;
-        ioreq_runio_qemu_aio(ioreq);
-        goto done;
-    }
-    if (ioreq->aio_inflight > 0) {
-        goto done;
-    }
-
-    switch (ioreq->req.operation) {
-    case BLKIF_OP_READ:
-        /* in case of failure ioreq->aio_errors is increased */
-        if (ret == 0) {
-            ioreq_grant_copy(ioreq);
-        }
-        qemu_vfree(ioreq->buf);
-        break;
-    case BLKIF_OP_WRITE:
-    case BLKIF_OP_FLUSH_DISKCACHE:
-        if (!ioreq->req.nr_segments) {
-            break;
-        }
-        qemu_vfree(ioreq->buf);
-        break;
-    default:
-        break;
-    }
-
-    ioreq->status = ioreq->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY;
-    ioreq_finish(ioreq);
-
-    switch (ioreq->req.operation) {
-    case BLKIF_OP_WRITE:
-    case BLKIF_OP_FLUSH_DISKCACHE:
-        if (!ioreq->req.nr_segments) {
-            break;
-        }
-    case BLKIF_OP_READ:
-        if (ioreq->status == BLKIF_RSP_OKAY) {
-            block_acct_done(blk_get_stats(blkdev->blk), &ioreq->acct);
-        } else {
-            block_acct_failed(blk_get_stats(blkdev->blk), &ioreq->acct);
-        }
-        break;
-    case BLKIF_OP_DISCARD:
-    default:
-        break;
-    }
-    qemu_bh_schedule(blkdev->bh);
-
-done:
-    aio_context_release(blkdev->ctx);
-}
-
-static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_number,
-                              uint64_t nr_sectors)
-{
-    struct XenBlkDev *blkdev = ioreq->blkdev;
-    int64_t byte_offset;
-    int byte_chunk;
-    uint64_t byte_remaining, limit;
-    uint64_t sec_start = sector_number;
-    uint64_t sec_count = nr_sectors;
-
-    /* Wrap around, or overflowing byte limit? */
-    if (sec_start + sec_count < sec_count ||
-        sec_start + sec_count > INT64_MAX >> BDRV_SECTOR_BITS) {
-        return false;
-    }
-
-    limit = BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS;
-    byte_offset = sec_start << BDRV_SECTOR_BITS;
-    byte_remaining = sec_count << BDRV_SECTOR_BITS;
-
-    do {
-        byte_chunk = byte_remaining > limit ? limit : byte_remaining;
-        ioreq->aio_inflight++;
-        blk_aio_pdiscard(blkdev->blk, byte_offset, byte_chunk,
-                         qemu_aio_complete, ioreq);
-        byte_remaining -= byte_chunk;
-        byte_offset += byte_chunk;
-    } while (byte_remaining > 0);
-
-    return true;
-}
-
-static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
-{
-    struct XenBlkDev *blkdev = ioreq->blkdev;
-
-    ioreq->buf = qemu_memalign(XC_PAGE_SIZE, ioreq->size);
-    if (ioreq->req.nr_segments &&
-        (ioreq->req.operation == BLKIF_OP_WRITE ||
-         ioreq->req.operation == BLKIF_OP_FLUSH_DISKCACHE) &&
-        ioreq_grant_copy(ioreq)) {
-        qemu_vfree(ioreq->buf);
-        goto err;
-    }
-
-    ioreq->aio_inflight++;
-    if (ioreq->presync) {
-        blk_aio_flush(ioreq->blkdev->blk, qemu_aio_complete, ioreq);
-        return 0;
-    }
-
-    switch (ioreq->req.operation) {
-    case BLKIF_OP_READ:
-        qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size);
-        block_acct_start(blk_get_stats(blkdev->blk), &ioreq->acct,
-                         ioreq->v.size, BLOCK_ACCT_READ);
-        ioreq->aio_inflight++;
-        blk_aio_preadv(blkdev->blk, ioreq->start, &ioreq->v, 0,
-                       qemu_aio_complete, ioreq);
-        break;
-    case BLKIF_OP_WRITE:
-    case BLKIF_OP_FLUSH_DISKCACHE:
-        if (!ioreq->req.nr_segments) {
-            break;
-        }
-
-        qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size);
-        block_acct_start(blk_get_stats(blkdev->blk), &ioreq->acct,
-                         ioreq->v.size,
-                         ioreq->req.operation == BLKIF_OP_WRITE ?
-                         BLOCK_ACCT_WRITE : BLOCK_ACCT_FLUSH);
-        ioreq->aio_inflight++;
-        blk_aio_pwritev(blkdev->blk, ioreq->start, &ioreq->v, 0,
-                        qemu_aio_complete, ioreq);
-        break;
-    case BLKIF_OP_DISCARD:
-    {
-        struct blkif_request_discard *req = (void *)&ioreq->req;
-        if (!blk_split_discard(ioreq, req->sector_number, req->nr_sectors)) {
-            goto err;
-        }
-        break;
-    }
-    default:
-        /* unknown operation (shouldn't happen -- parse catches this) */
-        goto err;
-    }
-
-    qemu_aio_complete(ioreq, 0);
-
-    return 0;
-
-err:
-    ioreq_finish(ioreq);
-    ioreq->status = BLKIF_RSP_ERROR;
-    return -1;
-}
-
-static int blk_send_response_one(struct ioreq *ioreq)
-{
-    struct XenBlkDev  *blkdev = ioreq->blkdev;
-    int               send_notify   = 0;
-    int               have_requests = 0;
-    blkif_response_t  *resp;
-
-    /* Place on the response ring for the relevant domain. */
-    switch (blkdev->protocol) {
-    case BLKIF_PROTOCOL_NATIVE:
-        resp = (blkif_response_t *) RING_GET_RESPONSE(&blkdev->rings.native,
-                                 blkdev->rings.native.rsp_prod_pvt);
-        break;
-    case BLKIF_PROTOCOL_X86_32:
-        resp = (blkif_response_t *) RING_GET_RESPONSE(&blkdev->rings.x86_32_part,
-                                 blkdev->rings.x86_32_part.rsp_prod_pvt);
-        break;
-    case BLKIF_PROTOCOL_X86_64:
-        resp = (blkif_response_t *) RING_GET_RESPONSE(&blkdev->rings.x86_64_part,
-                                 blkdev->rings.x86_64_part.rsp_prod_pvt);
-        break;
-    default:
-        return 0;
-    }
-
-    resp->id        = ioreq->req.id;
-    resp->operation = ioreq->req.operation;
-    resp->status    = ioreq->status;
-
-    blkdev->rings.common.rsp_prod_pvt++;
-
-    RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blkdev->rings.common, send_notify);
-    if (blkdev->rings.common.rsp_prod_pvt == blkdev->rings.common.req_cons) {
-        /*
-         * Tail check for pending requests. Allows frontend to avoid
-         * notifications if requests are already in flight (lower
-         * overheads and promotes batching).
-         */
-        RING_FINAL_CHECK_FOR_REQUESTS(&blkdev->rings.common, have_requests);
-    } else if (RING_HAS_UNCONSUMED_REQUESTS(&blkdev->rings.common)) {
-        have_requests = 1;
-    }
-
-    if (have_requests) {
-        blkdev->more_work++;
-    }
-    return send_notify;
-}
-
-/* walk finished list, send outstanding responses, free requests */
-static void blk_send_response_all(struct XenBlkDev *blkdev)
-{
-    struct ioreq *ioreq;
-    int send_notify = 0;
-
-    while (!QLIST_EMPTY(&blkdev->finished)) {
-        ioreq = QLIST_FIRST(&blkdev->finished);
-        send_notify += blk_send_response_one(ioreq);
-        ioreq_release(ioreq, true);
-    }
-    if (send_notify) {
-        xen_pv_send_notify(&blkdev->xendev);
-    }
-}
-
-static int blk_get_request(struct XenBlkDev *blkdev, struct ioreq *ioreq, RING_IDX rc)
-{
-    switch (blkdev->protocol) {
-    case BLKIF_PROTOCOL_NATIVE:
-        memcpy(&ioreq->req, RING_GET_REQUEST(&blkdev->rings.native, rc),
-               sizeof(ioreq->req));
-        break;
-    case BLKIF_PROTOCOL_X86_32:
-        blkif_get_x86_32_req(&ioreq->req,
-                             RING_GET_REQUEST(&blkdev->rings.x86_32_part, rc));
-        break;
-    case BLKIF_PROTOCOL_X86_64:
-        blkif_get_x86_64_req(&ioreq->req,
-                             RING_GET_REQUEST(&blkdev->rings.x86_64_part, rc));
-        break;
-    }
-    /* Prevent the compiler from accessing the on-ring fields instead. */
-    barrier();
-    return 0;
-}
-
-static void blk_handle_requests(struct XenBlkDev *blkdev)
-{
-    RING_IDX rc, rp;
-    struct ioreq *ioreq;
-
-    blkdev->more_work = 0;
-
-    rc = blkdev->rings.common.req_cons;
-    rp = blkdev->rings.common.sring->req_prod;
-    xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
-
-    blk_send_response_all(blkdev);
-    while (rc != rp) {
-        /* pull request from ring */
-        if (RING_REQUEST_CONS_OVERFLOW(&blkdev->rings.common, rc)) {
-            break;
-        }
-        ioreq = ioreq_start(blkdev);
-        if (ioreq == NULL) {
-            blkdev->more_work++;
-            break;
-        }
-        blk_get_request(blkdev, ioreq, rc);
-        blkdev->rings.common.req_cons = ++rc;
-
-        /* parse them */
-        if (ioreq_parse(ioreq) != 0) {
-
-            switch (ioreq->req.operation) {
-            case BLKIF_OP_READ:
-                block_acct_invalid(blk_get_stats(blkdev->blk),
-                                   BLOCK_ACCT_READ);
-                break;
-            case BLKIF_OP_WRITE:
-                block_acct_invalid(blk_get_stats(blkdev->blk),
-                                   BLOCK_ACCT_WRITE);
-                break;
-            case BLKIF_OP_FLUSH_DISKCACHE:
-                block_acct_invalid(blk_get_stats(blkdev->blk),
-                                   BLOCK_ACCT_FLUSH);
-            default:
-                break;
-            };
-
-            if (blk_send_response_one(ioreq)) {
-                xen_pv_send_notify(&blkdev->xendev);
-            }
-            ioreq_release(ioreq, false);
-            continue;
-        }
-
-        ioreq_runio_qemu_aio(ioreq);
-    }
-
-    if (blkdev->more_work && blkdev->requests_inflight < blkdev->max_requests) {
-        qemu_bh_schedule(blkdev->bh);
-    }
-}
-
-/* ------------------------------------------------------------- */
-
-static void blk_bh(void *opaque)
-{
-    struct XenBlkDev *blkdev = opaque;
-
-    aio_context_acquire(blkdev->ctx);
-    blk_handle_requests(blkdev);
-    aio_context_release(blkdev->ctx);
-}
-
-static void blk_alloc(struct XenLegacyDevice *xendev)
-{
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
-    Error *err = NULL;
-
-    trace_xen_disk_alloc(xendev->name);
-
-    QLIST_INIT(&blkdev->inflight);
-    QLIST_INIT(&blkdev->finished);
-    QLIST_INIT(&blkdev->freelist);
-
-    blkdev->iothread = iothread_create(xendev->name, &err);
-    assert(!err);
-
-    blkdev->ctx = iothread_get_aio_context(blkdev->iothread);
-    blkdev->bh = aio_bh_new(blkdev->ctx, blk_bh, blkdev);
-}
-
-static void blk_parse_discard(struct XenBlkDev *blkdev)
-{
-    struct XenLegacyDevice *xendev = &blkdev->xendev;
-    int enable;
-
-    blkdev->feature_discard = true;
-
-    if (xenstore_read_be_int(xendev, "discard-enable", &enable) == 0) {
-        blkdev->feature_discard = !!enable;
-    }
-
-    if (blkdev->feature_discard) {
-        xenstore_write_be_int(xendev, "feature-discard", 1);
-    }
-}
-
-static int blk_init(struct XenLegacyDevice *xendev)
-{
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
-    int info = 0;
-    char *directiosafe = NULL;
-
-    trace_xen_disk_init(xendev->name);
-
-    /* read xenstore entries */
-    if (blkdev->params == NULL) {
-        char *h = NULL;
-        blkdev->params = xenstore_read_be_str(xendev, "params");
-        if (blkdev->params != NULL) {
-            h = strchr(blkdev->params, ':');
-        }
-        if (h != NULL) {
-            blkdev->fileproto = blkdev->params;
-            blkdev->filename  = h+1;
-            *h = 0;
-        } else {
-            blkdev->fileproto = "<unset>";
-            blkdev->filename  = blkdev->params;
-        }
-    }
-    if (!strcmp("aio", blkdev->fileproto)) {
-        blkdev->fileproto = "raw";
-    }
-    if (!strcmp("vhd", blkdev->fileproto)) {
-        blkdev->fileproto = "vpc";
-    }
-    if (blkdev->mode == NULL) {
-        blkdev->mode = xenstore_read_be_str(xendev, "mode");
-    }
-    if (blkdev->type == NULL) {
-        blkdev->type = xenstore_read_be_str(xendev, "type");
-    }
-    if (blkdev->dev == NULL) {
-        blkdev->dev = xenstore_read_be_str(xendev, "dev");
-    }
-    if (blkdev->devtype == NULL) {
-        blkdev->devtype = xenstore_read_be_str(xendev, "device-type");
-    }
-    directiosafe = xenstore_read_be_str(xendev, "direct-io-safe");
-    blkdev->directiosafe = (directiosafe && atoi(directiosafe));
-
-    /* do we have all we need? */
-    if (blkdev->params == NULL ||
-        blkdev->mode == NULL   ||
-        blkdev->type == NULL   ||
-        blkdev->dev == NULL) {
-        goto out_error;
-    }
-
-    /* read-only ? */
-    if (strcmp(blkdev->mode, "w")) {
-        info  |= VDISK_READONLY;
-    }
-
-    /* cdrom ? */
-    if (blkdev->devtype && !strcmp(blkdev->devtype, "cdrom")) {
-        info  |= VDISK_CDROM;
-    }
-
-    blkdev->file_blk  = BLOCK_SIZE;
-
-    /* fill info
-     * blk_connect supplies sector-size and sectors
-     */
-    xenstore_write_be_int(xendev, "feature-flush-cache", 1);
-    xenstore_write_be_int(xendev, "info", info);
-
-    xenstore_write_be_int(xendev, "max-ring-page-order",
-                          MAX_RING_PAGE_ORDER);
-
-    blk_parse_discard(blkdev);
-
-    g_free(directiosafe);
-    return 0;
-
-out_error:
-    g_free(blkdev->params);
-    blkdev->params = NULL;
-    g_free(blkdev->mode);
-    blkdev->mode = NULL;
-    g_free(blkdev->type);
-    blkdev->type = NULL;
-    g_free(blkdev->dev);
-    blkdev->dev = NULL;
-    g_free(blkdev->devtype);
-    blkdev->devtype = NULL;
-    g_free(directiosafe);
-    blkdev->directiosafe = false;
-    return -1;
-}
-
-static int blk_connect(struct XenLegacyDevice *xendev)
-{
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
-    int index, qflags;
-    bool readonly = true;
-    bool writethrough = true;
-    int order, ring_ref;
-    unsigned int ring_size, max_grants;
-    unsigned int i;
-
-    trace_xen_disk_connect(xendev->name);
-
-    /* read-only ? */
-    if (blkdev->directiosafe) {
-        qflags = BDRV_O_NOCACHE | BDRV_O_NATIVE_AIO;
-    } else {
-        qflags = 0;
-        writethrough = false;
-    }
-    if (strcmp(blkdev->mode, "w") == 0) {
-        qflags |= BDRV_O_RDWR;
-        readonly = false;
-    }
-    if (blkdev->feature_discard) {
-        qflags |= BDRV_O_UNMAP;
-    }
-
-    /* init qemu block driver */
-    index = (xendev->dev - 202 * 256) / 16;
-    blkdev->dinfo = drive_get(IF_XEN, 0, index);
-    if (!blkdev->dinfo) {
-        Error *local_err = NULL;
-        QDict *options = NULL;
-
-        if (strcmp(blkdev->fileproto, "<unset>")) {
-            options = qdict_new();
-            qdict_put_str(options, "driver", blkdev->fileproto);
-        }
-
-        /* setup via xenbus -> create new block driver instance */
-        xen_pv_printf(xendev, 2, "create new bdrv (xenbus setup)\n");
-        blkdev->blk = blk_new_open(blkdev->filename, NULL, options,
-                                   qflags, &local_err);
-        if (!blkdev->blk) {
-            xen_pv_printf(xendev, 0, "error: %s\n",
-                          error_get_pretty(local_err));
-            error_free(local_err);
-            return -1;
-        }
-        blk_set_enable_write_cache(blkdev->blk, !writethrough);
-    } else {
-        /* setup via qemu cmdline -> already setup for us */
-        xen_pv_printf(xendev, 2,
-                      "get configured bdrv (cmdline setup)\n");
-        blkdev->blk = blk_by_legacy_dinfo(blkdev->dinfo);
-        if (blk_is_read_only(blkdev->blk) && !readonly) {
-            xen_pv_printf(xendev, 0, "Unexpected read-only drive");
-            blkdev->blk = NULL;
-            return -1;
-        }
-        /* blkdev->blk is not create by us, we get a reference
-         * so we can blk_unref() unconditionally */
-        blk_ref(blkdev->blk);
-    }
-    blk_attach_dev_legacy(blkdev->blk, blkdev);
-    blkdev->file_size = blk_getlength(blkdev->blk);
-    if (blkdev->file_size < 0) {
-        BlockDriverState *bs = blk_bs(blkdev->blk);
-        const char *drv_name = bs ? bdrv_get_format_name(bs) : NULL;
-        xen_pv_printf(xendev, 1, "blk_getlength: %d (%s) | drv %s\n",
-                      (int)blkdev->file_size, strerror(-blkdev->file_size),
-                      drv_name ?: "-");
-        blkdev->file_size = 0;
-    }
-
-    xen_pv_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\","
-                  " size %" PRId64 " (%" PRId64 " MB)\n",
-                  blkdev->type, blkdev->fileproto, blkdev->filename,
-                  blkdev->file_size, blkdev->file_size / MiB);
-
-    /* Fill in number of sector size and number of sectors */
-    xenstore_write_be_int(xendev, "sector-size", blkdev->file_blk);
-    xenstore_write_be_int64(xendev, "sectors",
-                            blkdev->file_size / blkdev->file_blk);
-
-    if (xenstore_read_fe_int(xendev, "ring-page-order",
-                             &order) == -1) {
-        blkdev->nr_ring_ref = 1;
-
-        if (xenstore_read_fe_int(xendev, "ring-ref",
-                                 &ring_ref) == -1) {
-            return -1;
-        }
-        blkdev->ring_ref[0] = ring_ref;
-
-    } else if (order >= 0 && order <= MAX_RING_PAGE_ORDER) {
-        blkdev->nr_ring_ref = 1 << order;
-
-        for (i = 0; i < blkdev->nr_ring_ref; i++) {
-            char *key;
-
-            key = g_strdup_printf("ring-ref%u", i);
-            if (!key) {
-                return -1;
-            }
-
-            if (xenstore_read_fe_int(xendev, key,
-                                     &ring_ref) == -1) {
-                g_free(key);
-                return -1;
-            }
-            blkdev->ring_ref[i] = ring_ref;
-
-            g_free(key);
-        }
-    } else {
-        xen_pv_printf(xendev, 0, "invalid ring-page-order: %d\n",
-                      order);
-        return -1;
-    }
-
-    if (xenstore_read_fe_int(xendev, "event-channel",
-                             &xendev->remote_port) == -1) {
-        return -1;
-    }
-
-    if (!xendev->protocol) {
-        blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
-    } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_NATIVE) == 0) {
-        blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
-    } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_X86_32) == 0) {
-        blkdev->protocol = BLKIF_PROTOCOL_X86_32;
-    } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_X86_64) == 0) {
-        blkdev->protocol = BLKIF_PROTOCOL_X86_64;
-    } else {
-        blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
-    }
-
-    ring_size = XC_PAGE_SIZE * blkdev->nr_ring_ref;
-    switch (blkdev->protocol) {
-    case BLKIF_PROTOCOL_NATIVE:
-    {
-        blkdev->max_requests = __CONST_RING_SIZE(blkif, ring_size);
-        break;
-    }
-    case BLKIF_PROTOCOL_X86_32:
-    {
-        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_32, ring_size);
-        break;
-    }
-    case BLKIF_PROTOCOL_X86_64:
-    {
-        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_64, ring_size);
-        break;
-    }
-    default:
-        return -1;
-    }
-
-    /* Add on the number needed for the ring pages */
-    max_grants = blkdev->nr_ring_ref;
-
-    xen_be_set_max_grant_refs(xendev, max_grants);
-    blkdev->sring = xen_be_map_grant_refs(xendev, blkdev->ring_ref,
-                                          blkdev->nr_ring_ref,
-                                          PROT_READ | PROT_WRITE);
-    if (!blkdev->sring) {
-        return -1;
-    }
-
-    switch (blkdev->protocol) {
-    case BLKIF_PROTOCOL_NATIVE:
-    {
-        blkif_sring_t *sring_native = blkdev->sring;
-        BACK_RING_INIT(&blkdev->rings.native, sring_native, ring_size);
-        break;
-    }
-    case BLKIF_PROTOCOL_X86_32:
-    {
-        blkif_x86_32_sring_t *sring_x86_32 = blkdev->sring;
-
-        BACK_RING_INIT(&blkdev->rings.x86_32_part, sring_x86_32, ring_size);
-        break;
-    }
-    case BLKIF_PROTOCOL_X86_64:
-    {
-        blkif_x86_64_sring_t *sring_x86_64 = blkdev->sring;
-
-        BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64, ring_size);
-        break;
-    }
-    }
-
-    blk_set_aio_context(blkdev->blk, blkdev->ctx);
-
-    xen_be_bind_evtchn(xendev);
-
-    xen_pv_printf(xendev, 1, "ok: proto %s, nr-ring-ref %u, "
-                  "remote port %d, local port %d\n",
-                  xendev->protocol, blkdev->nr_ring_ref,
-                  xendev->remote_port, xendev->local_port);
-    return 0;
-}
-
-static void blk_disconnect(struct XenLegacyDevice *xendev)
-{
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
-
-    trace_xen_disk_disconnect(xendev->name);
-
-    aio_context_acquire(blkdev->ctx);
-
-    if (blkdev->blk) {
-        blk_set_aio_context(blkdev->blk, qemu_get_aio_context());
-        blk_detach_dev(blkdev->blk, blkdev);
-        blk_unref(blkdev->blk);
-        blkdev->blk = NULL;
-    }
-    xen_pv_unbind_evtchn(xendev);
-
-    aio_context_release(blkdev->ctx);
-
-    if (blkdev->sring) {
-        xen_be_unmap_grant_refs(xendev, blkdev->sring,
-                                blkdev->nr_ring_ref);
-        blkdev->sring = NULL;
-    }
-}
-
-static int blk_free(struct XenLegacyDevice *xendev)
-{
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
-    struct ioreq *ioreq;
-
-    trace_xen_disk_free(xendev->name);
-
-    blk_disconnect(xendev);
-
-    while (!QLIST_EMPTY(&blkdev->freelist)) {
-        ioreq = QLIST_FIRST(&blkdev->freelist);
-        QLIST_REMOVE(ioreq, list);
-        qemu_iovec_destroy(&ioreq->v);
-        g_free(ioreq);
-    }
-
-    g_free(blkdev->params);
-    g_free(blkdev->mode);
-    g_free(blkdev->type);
-    g_free(blkdev->dev);
-    g_free(blkdev->devtype);
-    qemu_bh_delete(blkdev->bh);
-    iothread_destroy(blkdev->iothread);
-    return 0;
-}
-
-static void blk_event(struct XenLegacyDevice *xendev)
-{
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
-
-    qemu_bh_schedule(blkdev->bh);
-}
-
-struct XenDevOps xen_blkdev_ops = {
-    .flags      = DEVOPS_FLAG_NEED_GNTDEV,
-    .size       = sizeof(struct XenBlkDev),
-    .alloc      = blk_alloc,
-    .init       = blk_init,
-    .initialise = blk_connect,
-    .disconnect = blk_disconnect,
-    .event      = blk_event,
-    .free       = blk_free,
-};
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* [PATCH 18/18] xen: remove the legacy 'xen_disk' backend
@ 2018-11-21 15:12   ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-21 15:12 UTC (permalink / raw)
  To: qemu-block, qemu-devel, xen-devel; +Cc: Kevin Wolf, Paul Durrant, Max Reitz

This backend has now been replaced by the 'xen-qdisk' XenDevice.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
---
 hw/block/Makefile.objs |    1 -
 hw/block/xen_disk.c    | 1011 ------------------------------------------------
 2 files changed, 1012 deletions(-)
 delete mode 100644 hw/block/xen_disk.c

diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs
index bcdd36d318..d9d2f3fde5 100644
--- a/hw/block/Makefile.objs
+++ b/hw/block/Makefile.objs
@@ -4,7 +4,6 @@ common-obj-$(CONFIG_SSI_M25P80) += m25p80.o
 common-obj-$(CONFIG_NAND) += nand.o
 common-obj-$(CONFIG_PFLASH_CFI01) += pflash_cfi01.o
 common-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
-common-obj-$(CONFIG_XEN) += xen_disk.o
 common-obj-$(CONFIG_XEN) += xen-qdisk.o
 common-obj-$(CONFIG_ECC) += ecc.o
 common-obj-$(CONFIG_ONENAND) += onenand.o
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
deleted file mode 100644
index 75fe55f2ae..0000000000
--- a/hw/block/xen_disk.c
+++ /dev/null
@@ -1,1011 +0,0 @@
-/*
- *  xen paravirt block device backend
- *
- *  (c) Gerd Hoffmann <kraxel@redhat.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; under version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- *  Contributions after 2012-01-13 are licensed under the terms of the
- *  GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include "qemu/osdep.h"
-#include "qemu/units.h"
-#include <sys/ioctl.h>
-#include <sys/uio.h>
-
-#include "hw/hw.h"
-#include "hw/xen/xen-legacy-backend.h"
-#include "xen_blkif.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/iothread.h"
-#include "sysemu/block-backend.h"
-#include "qapi/error.h"
-#include "qapi/qmp/qdict.h"
-#include "qapi/qmp/qstring.h"
-#include "trace.h"
-
-/* ------------------------------------------------------------- */
-
-#define BLOCK_SIZE  512
-#define IOCB_COUNT  (BLKIF_MAX_SEGMENTS_PER_REQUEST + 2)
-
-struct ioreq {
-    blkif_request_t     req;
-    int16_t             status;
-
-    /* parsed request */
-    off_t               start;
-    QEMUIOVector        v;
-    void                *buf;
-    size_t              size;
-    int                 presync;
-
-    /* aio status */
-    int                 aio_inflight;
-    int                 aio_errors;
-
-    struct XenBlkDev    *blkdev;
-    QLIST_ENTRY(ioreq)   list;
-    BlockAcctCookie     acct;
-};
-
-#define MAX_RING_PAGE_ORDER 4
-
-struct XenBlkDev {
-    struct XenLegacyDevice    xendev;  /* must be first */
-    char                *params;
-    char                *mode;
-    char                *type;
-    char                *dev;
-    char                *devtype;
-    bool                directiosafe;
-    const char          *fileproto;
-    const char          *filename;
-    unsigned int        ring_ref[1 << MAX_RING_PAGE_ORDER];
-    unsigned int        nr_ring_ref;
-    void                *sring;
-    int64_t             file_blk;
-    int64_t             file_size;
-    int                 protocol;
-    blkif_back_rings_t  rings;
-    int                 more_work;
-
-    /* request lists */
-    QLIST_HEAD(inflight_head, ioreq) inflight;
-    QLIST_HEAD(finished_head, ioreq) finished;
-    QLIST_HEAD(freelist_head, ioreq) freelist;
-    int                 requests_total;
-    int                 requests_inflight;
-    int                 requests_finished;
-    unsigned int        max_requests;
-
-    gboolean            feature_discard;
-
-    /* qemu block driver */
-    DriveInfo           *dinfo;
-    BlockBackend        *blk;
-    QEMUBH              *bh;
-
-    IOThread            *iothread;
-    AioContext          *ctx;
-};
-
-/* ------------------------------------------------------------- */
-
-static void ioreq_reset(struct ioreq *ioreq)
-{
-    memset(&ioreq->req, 0, sizeof(ioreq->req));
-    ioreq->status = 0;
-    ioreq->start = 0;
-    ioreq->buf = NULL;
-    ioreq->size = 0;
-    ioreq->presync = 0;
-
-    ioreq->aio_inflight = 0;
-    ioreq->aio_errors = 0;
-
-    ioreq->blkdev = NULL;
-    memset(&ioreq->list, 0, sizeof(ioreq->list));
-    memset(&ioreq->acct, 0, sizeof(ioreq->acct));
-
-    qemu_iovec_reset(&ioreq->v);
-}
-
-static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
-{
-    struct ioreq *ioreq = NULL;
-
-    if (QLIST_EMPTY(&blkdev->freelist)) {
-        if (blkdev->requests_total >= blkdev->max_requests) {
-            goto out;
-        }
-        /* allocate new struct */
-        ioreq = g_malloc0(sizeof(*ioreq));
-        ioreq->blkdev = blkdev;
-        blkdev->requests_total++;
-        qemu_iovec_init(&ioreq->v, 1);
-    } else {
-        /* get one from freelist */
-        ioreq = QLIST_FIRST(&blkdev->freelist);
-        QLIST_REMOVE(ioreq, list);
-    }
-    QLIST_INSERT_HEAD(&blkdev->inflight, ioreq, list);
-    blkdev->requests_inflight++;
-
-out:
-    return ioreq;
-}
-
-static void ioreq_finish(struct ioreq *ioreq)
-{
-    struct XenBlkDev *blkdev = ioreq->blkdev;
-
-    QLIST_REMOVE(ioreq, list);
-    QLIST_INSERT_HEAD(&blkdev->finished, ioreq, list);
-    blkdev->requests_inflight--;
-    blkdev->requests_finished++;
-}
-
-static void ioreq_release(struct ioreq *ioreq, bool finish)
-{
-    struct XenBlkDev *blkdev = ioreq->blkdev;
-
-    QLIST_REMOVE(ioreq, list);
-    ioreq_reset(ioreq);
-    ioreq->blkdev = blkdev;
-    QLIST_INSERT_HEAD(&blkdev->freelist, ioreq, list);
-    if (finish) {
-        blkdev->requests_finished--;
-    } else {
-        blkdev->requests_inflight--;
-    }
-}
-
-/*
- * translate request into iovec + start offset
- * do sanity checks along the way
- */
-static int ioreq_parse(struct ioreq *ioreq)
-{
-    struct XenBlkDev *blkdev = ioreq->blkdev;
-    struct XenLegacyDevice *xendev = &blkdev->xendev;
-    size_t len;
-    int i;
-
-    xen_pv_printf(xendev, 3,
-                  "op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 "\n",
-                  ioreq->req.operation, ioreq->req.nr_segments,
-                  ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number);
-    switch (ioreq->req.operation) {
-    case BLKIF_OP_READ:
-        break;
-    case BLKIF_OP_FLUSH_DISKCACHE:
-        ioreq->presync = 1;
-        if (!ioreq->req.nr_segments) {
-            return 0;
-        }
-        /* fall through */
-    case BLKIF_OP_WRITE:
-        break;
-    case BLKIF_OP_DISCARD:
-        return 0;
-    default:
-        xen_pv_printf(xendev, 0, "error: unknown operation (%d)\n",
-                      ioreq->req.operation);
-        goto err;
-    };
-
-    if (ioreq->req.operation != BLKIF_OP_READ && blkdev->mode[0] != 'w') {
-        xen_pv_printf(xendev, 0, "error: write req for ro device\n");
-        goto err;
-    }
-
-    ioreq->start = ioreq->req.sector_number * blkdev->file_blk;
-    for (i = 0; i < ioreq->req.nr_segments; i++) {
-        if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
-            xen_pv_printf(xendev, 0, "error: nr_segments too big\n");
-            goto err;
-        }
-        if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) {
-            xen_pv_printf(xendev, 0, "error: first > last sector\n");
-            goto err;
-        }
-        if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >= XC_PAGE_SIZE) {
-            xen_pv_printf(xendev, 0, "error: page crossing\n");
-            goto err;
-        }
-
-        len = (ioreq->req.seg[i].last_sect - ioreq->req.seg[i].first_sect + 1) * blkdev->file_blk;
-        ioreq->size += len;
-    }
-    if (ioreq->start + ioreq->size > blkdev->file_size) {
-        xen_pv_printf(xendev, 0, "error: access beyond end of file\n");
-        goto err;
-    }
-    return 0;
-
-err:
-    ioreq->status = BLKIF_RSP_ERROR;
-    return -1;
-}
-
-static int ioreq_grant_copy(struct ioreq *ioreq)
-{
-    struct XenBlkDev *blkdev = ioreq->blkdev;
-    struct XenLegacyDevice *xendev = &blkdev->xendev;
-    XenGrantCopySegment segs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
-    int i, count, rc;
-    int64_t file_blk = blkdev->file_blk;
-    bool to_domain = (ioreq->req.operation == BLKIF_OP_READ);
-    void *virt = ioreq->buf;
-
-    if (ioreq->req.nr_segments == 0) {
-        return 0;
-    }
-
-    count = ioreq->req.nr_segments;
-
-    for (i = 0; i < count; i++) {
-        if (to_domain) {
-            segs[i].dest.foreign.ref = ioreq->req.seg[i].gref;
-            segs[i].dest.foreign.offset = ioreq->req.seg[i].first_sect * file_blk;
-            segs[i].source.virt = virt;
-        } else {
-            segs[i].source.foreign.ref = ioreq->req.seg[i].gref;
-            segs[i].source.foreign.offset = ioreq->req.seg[i].first_sect * file_blk;
-            segs[i].dest.virt = virt;
-        }
-        segs[i].len = (ioreq->req.seg[i].last_sect
-                       - ioreq->req.seg[i].first_sect + 1) * file_blk;
-        virt += segs[i].len;
-    }
-
-    rc = xen_be_copy_grant_refs(xendev, to_domain, segs, count);
-
-    if (rc) {
-        xen_pv_printf(xendev, 0,
-                      "failed to copy data %d\n", rc);
-        ioreq->aio_errors++;
-        return -1;
-    }
-
-    return rc;
-}
-
-static int ioreq_runio_qemu_aio(struct ioreq *ioreq);
-
-static void qemu_aio_complete(void *opaque, int ret)
-{
-    struct ioreq *ioreq = opaque;
-    struct XenBlkDev *blkdev = ioreq->blkdev;
-    struct XenLegacyDevice *xendev = &blkdev->xendev;
-
-    aio_context_acquire(blkdev->ctx);
-
-    if (ret != 0) {
-        xen_pv_printf(xendev, 0, "%s I/O error\n",
-                      ioreq->req.operation == BLKIF_OP_READ ? "read" : "write");
-        ioreq->aio_errors++;
-    }
-
-    ioreq->aio_inflight--;
-    if (ioreq->presync) {
-        ioreq->presync = 0;
-        ioreq_runio_qemu_aio(ioreq);
-        goto done;
-    }
-    if (ioreq->aio_inflight > 0) {
-        goto done;
-    }
-
-    switch (ioreq->req.operation) {
-    case BLKIF_OP_READ:
-        /* in case of failure ioreq->aio_errors is increased */
-        if (ret == 0) {
-            ioreq_grant_copy(ioreq);
-        }
-        qemu_vfree(ioreq->buf);
-        break;
-    case BLKIF_OP_WRITE:
-    case BLKIF_OP_FLUSH_DISKCACHE:
-        if (!ioreq->req.nr_segments) {
-            break;
-        }
-        qemu_vfree(ioreq->buf);
-        break;
-    default:
-        break;
-    }
-
-    ioreq->status = ioreq->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY;
-    ioreq_finish(ioreq);
-
-    switch (ioreq->req.operation) {
-    case BLKIF_OP_WRITE:
-    case BLKIF_OP_FLUSH_DISKCACHE:
-        if (!ioreq->req.nr_segments) {
-            break;
-        }
-    case BLKIF_OP_READ:
-        if (ioreq->status == BLKIF_RSP_OKAY) {
-            block_acct_done(blk_get_stats(blkdev->blk), &ioreq->acct);
-        } else {
-            block_acct_failed(blk_get_stats(blkdev->blk), &ioreq->acct);
-        }
-        break;
-    case BLKIF_OP_DISCARD:
-    default:
-        break;
-    }
-    qemu_bh_schedule(blkdev->bh);
-
-done:
-    aio_context_release(blkdev->ctx);
-}
-
-static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_number,
-                              uint64_t nr_sectors)
-{
-    struct XenBlkDev *blkdev = ioreq->blkdev;
-    int64_t byte_offset;
-    int byte_chunk;
-    uint64_t byte_remaining, limit;
-    uint64_t sec_start = sector_number;
-    uint64_t sec_count = nr_sectors;
-
-    /* Wrap around, or overflowing byte limit? */
-    if (sec_start + sec_count < sec_count ||
-        sec_start + sec_count > INT64_MAX >> BDRV_SECTOR_BITS) {
-        return false;
-    }
-
-    limit = BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS;
-    byte_offset = sec_start << BDRV_SECTOR_BITS;
-    byte_remaining = sec_count << BDRV_SECTOR_BITS;
-
-    do {
-        byte_chunk = byte_remaining > limit ? limit : byte_remaining;
-        ioreq->aio_inflight++;
-        blk_aio_pdiscard(blkdev->blk, byte_offset, byte_chunk,
-                         qemu_aio_complete, ioreq);
-        byte_remaining -= byte_chunk;
-        byte_offset += byte_chunk;
-    } while (byte_remaining > 0);
-
-    return true;
-}
-
-static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
-{
-    struct XenBlkDev *blkdev = ioreq->blkdev;
-
-    ioreq->buf = qemu_memalign(XC_PAGE_SIZE, ioreq->size);
-    if (ioreq->req.nr_segments &&
-        (ioreq->req.operation == BLKIF_OP_WRITE ||
-         ioreq->req.operation == BLKIF_OP_FLUSH_DISKCACHE) &&
-        ioreq_grant_copy(ioreq)) {
-        qemu_vfree(ioreq->buf);
-        goto err;
-    }
-
-    ioreq->aio_inflight++;
-    if (ioreq->presync) {
-        blk_aio_flush(ioreq->blkdev->blk, qemu_aio_complete, ioreq);
-        return 0;
-    }
-
-    switch (ioreq->req.operation) {
-    case BLKIF_OP_READ:
-        qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size);
-        block_acct_start(blk_get_stats(blkdev->blk), &ioreq->acct,
-                         ioreq->v.size, BLOCK_ACCT_READ);
-        ioreq->aio_inflight++;
-        blk_aio_preadv(blkdev->blk, ioreq->start, &ioreq->v, 0,
-                       qemu_aio_complete, ioreq);
-        break;
-    case BLKIF_OP_WRITE:
-    case BLKIF_OP_FLUSH_DISKCACHE:
-        if (!ioreq->req.nr_segments) {
-            break;
-        }
-
-        qemu_iovec_add(&ioreq->v, ioreq->buf, ioreq->size);
-        block_acct_start(blk_get_stats(blkdev->blk), &ioreq->acct,
-                         ioreq->v.size,
-                         ioreq->req.operation == BLKIF_OP_WRITE ?
-                         BLOCK_ACCT_WRITE : BLOCK_ACCT_FLUSH);
-        ioreq->aio_inflight++;
-        blk_aio_pwritev(blkdev->blk, ioreq->start, &ioreq->v, 0,
-                        qemu_aio_complete, ioreq);
-        break;
-    case BLKIF_OP_DISCARD:
-    {
-        struct blkif_request_discard *req = (void *)&ioreq->req;
-        if (!blk_split_discard(ioreq, req->sector_number, req->nr_sectors)) {
-            goto err;
-        }
-        break;
-    }
-    default:
-        /* unknown operation (shouldn't happen -- parse catches this) */
-        goto err;
-    }
-
-    qemu_aio_complete(ioreq, 0);
-
-    return 0;
-
-err:
-    ioreq_finish(ioreq);
-    ioreq->status = BLKIF_RSP_ERROR;
-    return -1;
-}
-
-static int blk_send_response_one(struct ioreq *ioreq)
-{
-    struct XenBlkDev  *blkdev = ioreq->blkdev;
-    int               send_notify   = 0;
-    int               have_requests = 0;
-    blkif_response_t  *resp;
-
-    /* Place on the response ring for the relevant domain. */
-    switch (blkdev->protocol) {
-    case BLKIF_PROTOCOL_NATIVE:
-        resp = (blkif_response_t *) RING_GET_RESPONSE(&blkdev->rings.native,
-                                 blkdev->rings.native.rsp_prod_pvt);
-        break;
-    case BLKIF_PROTOCOL_X86_32:
-        resp = (blkif_response_t *) RING_GET_RESPONSE(&blkdev->rings.x86_32_part,
-                                 blkdev->rings.x86_32_part.rsp_prod_pvt);
-        break;
-    case BLKIF_PROTOCOL_X86_64:
-        resp = (blkif_response_t *) RING_GET_RESPONSE(&blkdev->rings.x86_64_part,
-                                 blkdev->rings.x86_64_part.rsp_prod_pvt);
-        break;
-    default:
-        return 0;
-    }
-
-    resp->id        = ioreq->req.id;
-    resp->operation = ioreq->req.operation;
-    resp->status    = ioreq->status;
-
-    blkdev->rings.common.rsp_prod_pvt++;
-
-    RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blkdev->rings.common, send_notify);
-    if (blkdev->rings.common.rsp_prod_pvt == blkdev->rings.common.req_cons) {
-        /*
-         * Tail check for pending requests. Allows frontend to avoid
-         * notifications if requests are already in flight (lower
-         * overheads and promotes batching).
-         */
-        RING_FINAL_CHECK_FOR_REQUESTS(&blkdev->rings.common, have_requests);
-    } else if (RING_HAS_UNCONSUMED_REQUESTS(&blkdev->rings.common)) {
-        have_requests = 1;
-    }
-
-    if (have_requests) {
-        blkdev->more_work++;
-    }
-    return send_notify;
-}
-
-/* walk finished list, send outstanding responses, free requests */
-static void blk_send_response_all(struct XenBlkDev *blkdev)
-{
-    struct ioreq *ioreq;
-    int send_notify = 0;
-
-    while (!QLIST_EMPTY(&blkdev->finished)) {
-        ioreq = QLIST_FIRST(&blkdev->finished);
-        send_notify += blk_send_response_one(ioreq);
-        ioreq_release(ioreq, true);
-    }
-    if (send_notify) {
-        xen_pv_send_notify(&blkdev->xendev);
-    }
-}
-
-static int blk_get_request(struct XenBlkDev *blkdev, struct ioreq *ioreq, RING_IDX rc)
-{
-    switch (blkdev->protocol) {
-    case BLKIF_PROTOCOL_NATIVE:
-        memcpy(&ioreq->req, RING_GET_REQUEST(&blkdev->rings.native, rc),
-               sizeof(ioreq->req));
-        break;
-    case BLKIF_PROTOCOL_X86_32:
-        blkif_get_x86_32_req(&ioreq->req,
-                             RING_GET_REQUEST(&blkdev->rings.x86_32_part, rc));
-        break;
-    case BLKIF_PROTOCOL_X86_64:
-        blkif_get_x86_64_req(&ioreq->req,
-                             RING_GET_REQUEST(&blkdev->rings.x86_64_part, rc));
-        break;
-    }
-    /* Prevent the compiler from accessing the on-ring fields instead. */
-    barrier();
-    return 0;
-}
-
-static void blk_handle_requests(struct XenBlkDev *blkdev)
-{
-    RING_IDX rc, rp;
-    struct ioreq *ioreq;
-
-    blkdev->more_work = 0;
-
-    rc = blkdev->rings.common.req_cons;
-    rp = blkdev->rings.common.sring->req_prod;
-    xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
-
-    blk_send_response_all(blkdev);
-    while (rc != rp) {
-        /* pull request from ring */
-        if (RING_REQUEST_CONS_OVERFLOW(&blkdev->rings.common, rc)) {
-            break;
-        }
-        ioreq = ioreq_start(blkdev);
-        if (ioreq == NULL) {
-            blkdev->more_work++;
-            break;
-        }
-        blk_get_request(blkdev, ioreq, rc);
-        blkdev->rings.common.req_cons = ++rc;
-
-        /* parse them */
-        if (ioreq_parse(ioreq) != 0) {
-
-            switch (ioreq->req.operation) {
-            case BLKIF_OP_READ:
-                block_acct_invalid(blk_get_stats(blkdev->blk),
-                                   BLOCK_ACCT_READ);
-                break;
-            case BLKIF_OP_WRITE:
-                block_acct_invalid(blk_get_stats(blkdev->blk),
-                                   BLOCK_ACCT_WRITE);
-                break;
-            case BLKIF_OP_FLUSH_DISKCACHE:
-                block_acct_invalid(blk_get_stats(blkdev->blk),
-                                   BLOCK_ACCT_FLUSH);
-            default:
-                break;
-            };
-
-            if (blk_send_response_one(ioreq)) {
-                xen_pv_send_notify(&blkdev->xendev);
-            }
-            ioreq_release(ioreq, false);
-            continue;
-        }
-
-        ioreq_runio_qemu_aio(ioreq);
-    }
-
-    if (blkdev->more_work && blkdev->requests_inflight < blkdev->max_requests) {
-        qemu_bh_schedule(blkdev->bh);
-    }
-}
-
-/* ------------------------------------------------------------- */
-
-static void blk_bh(void *opaque)
-{
-    struct XenBlkDev *blkdev = opaque;
-
-    aio_context_acquire(blkdev->ctx);
-    blk_handle_requests(blkdev);
-    aio_context_release(blkdev->ctx);
-}
-
-static void blk_alloc(struct XenLegacyDevice *xendev)
-{
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
-    Error *err = NULL;
-
-    trace_xen_disk_alloc(xendev->name);
-
-    QLIST_INIT(&blkdev->inflight);
-    QLIST_INIT(&blkdev->finished);
-    QLIST_INIT(&blkdev->freelist);
-
-    blkdev->iothread = iothread_create(xendev->name, &err);
-    assert(!err);
-
-    blkdev->ctx = iothread_get_aio_context(blkdev->iothread);
-    blkdev->bh = aio_bh_new(blkdev->ctx, blk_bh, blkdev);
-}
-
-static void blk_parse_discard(struct XenBlkDev *blkdev)
-{
-    struct XenLegacyDevice *xendev = &blkdev->xendev;
-    int enable;
-
-    blkdev->feature_discard = true;
-
-    if (xenstore_read_be_int(xendev, "discard-enable", &enable) == 0) {
-        blkdev->feature_discard = !!enable;
-    }
-
-    if (blkdev->feature_discard) {
-        xenstore_write_be_int(xendev, "feature-discard", 1);
-    }
-}
-
-static int blk_init(struct XenLegacyDevice *xendev)
-{
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
-    int info = 0;
-    char *directiosafe = NULL;
-
-    trace_xen_disk_init(xendev->name);
-
-    /* read xenstore entries */
-    if (blkdev->params == NULL) {
-        char *h = NULL;
-        blkdev->params = xenstore_read_be_str(xendev, "params");
-        if (blkdev->params != NULL) {
-            h = strchr(blkdev->params, ':');
-        }
-        if (h != NULL) {
-            blkdev->fileproto = blkdev->params;
-            blkdev->filename  = h+1;
-            *h = 0;
-        } else {
-            blkdev->fileproto = "<unset>";
-            blkdev->filename  = blkdev->params;
-        }
-    }
-    if (!strcmp("aio", blkdev->fileproto)) {
-        blkdev->fileproto = "raw";
-    }
-    if (!strcmp("vhd", blkdev->fileproto)) {
-        blkdev->fileproto = "vpc";
-    }
-    if (blkdev->mode == NULL) {
-        blkdev->mode = xenstore_read_be_str(xendev, "mode");
-    }
-    if (blkdev->type == NULL) {
-        blkdev->type = xenstore_read_be_str(xendev, "type");
-    }
-    if (blkdev->dev == NULL) {
-        blkdev->dev = xenstore_read_be_str(xendev, "dev");
-    }
-    if (blkdev->devtype == NULL) {
-        blkdev->devtype = xenstore_read_be_str(xendev, "device-type");
-    }
-    directiosafe = xenstore_read_be_str(xendev, "direct-io-safe");
-    blkdev->directiosafe = (directiosafe && atoi(directiosafe));
-
-    /* do we have all we need? */
-    if (blkdev->params == NULL ||
-        blkdev->mode == NULL   ||
-        blkdev->type == NULL   ||
-        blkdev->dev == NULL) {
-        goto out_error;
-    }
-
-    /* read-only ? */
-    if (strcmp(blkdev->mode, "w")) {
-        info  |= VDISK_READONLY;
-    }
-
-    /* cdrom ? */
-    if (blkdev->devtype && !strcmp(blkdev->devtype, "cdrom")) {
-        info  |= VDISK_CDROM;
-    }
-
-    blkdev->file_blk  = BLOCK_SIZE;
-
-    /* fill info
-     * blk_connect supplies sector-size and sectors
-     */
-    xenstore_write_be_int(xendev, "feature-flush-cache", 1);
-    xenstore_write_be_int(xendev, "info", info);
-
-    xenstore_write_be_int(xendev, "max-ring-page-order",
-                          MAX_RING_PAGE_ORDER);
-
-    blk_parse_discard(blkdev);
-
-    g_free(directiosafe);
-    return 0;
-
-out_error:
-    g_free(blkdev->params);
-    blkdev->params = NULL;
-    g_free(blkdev->mode);
-    blkdev->mode = NULL;
-    g_free(blkdev->type);
-    blkdev->type = NULL;
-    g_free(blkdev->dev);
-    blkdev->dev = NULL;
-    g_free(blkdev->devtype);
-    blkdev->devtype = NULL;
-    g_free(directiosafe);
-    blkdev->directiosafe = false;
-    return -1;
-}
-
-static int blk_connect(struct XenLegacyDevice *xendev)
-{
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
-    int index, qflags;
-    bool readonly = true;
-    bool writethrough = true;
-    int order, ring_ref;
-    unsigned int ring_size, max_grants;
-    unsigned int i;
-
-    trace_xen_disk_connect(xendev->name);
-
-    /* read-only ? */
-    if (blkdev->directiosafe) {
-        qflags = BDRV_O_NOCACHE | BDRV_O_NATIVE_AIO;
-    } else {
-        qflags = 0;
-        writethrough = false;
-    }
-    if (strcmp(blkdev->mode, "w") == 0) {
-        qflags |= BDRV_O_RDWR;
-        readonly = false;
-    }
-    if (blkdev->feature_discard) {
-        qflags |= BDRV_O_UNMAP;
-    }
-
-    /* init qemu block driver */
-    index = (xendev->dev - 202 * 256) / 16;
-    blkdev->dinfo = drive_get(IF_XEN, 0, index);
-    if (!blkdev->dinfo) {
-        Error *local_err = NULL;
-        QDict *options = NULL;
-
-        if (strcmp(blkdev->fileproto, "<unset>")) {
-            options = qdict_new();
-            qdict_put_str(options, "driver", blkdev->fileproto);
-        }
-
-        /* setup via xenbus -> create new block driver instance */
-        xen_pv_printf(xendev, 2, "create new bdrv (xenbus setup)\n");
-        blkdev->blk = blk_new_open(blkdev->filename, NULL, options,
-                                   qflags, &local_err);
-        if (!blkdev->blk) {
-            xen_pv_printf(xendev, 0, "error: %s\n",
-                          error_get_pretty(local_err));
-            error_free(local_err);
-            return -1;
-        }
-        blk_set_enable_write_cache(blkdev->blk, !writethrough);
-    } else {
-        /* setup via qemu cmdline -> already setup for us */
-        xen_pv_printf(xendev, 2,
-                      "get configured bdrv (cmdline setup)\n");
-        blkdev->blk = blk_by_legacy_dinfo(blkdev->dinfo);
-        if (blk_is_read_only(blkdev->blk) && !readonly) {
-            xen_pv_printf(xendev, 0, "Unexpected read-only drive");
-            blkdev->blk = NULL;
-            return -1;
-        }
-        /* blkdev->blk is not create by us, we get a reference
-         * so we can blk_unref() unconditionally */
-        blk_ref(blkdev->blk);
-    }
-    blk_attach_dev_legacy(blkdev->blk, blkdev);
-    blkdev->file_size = blk_getlength(blkdev->blk);
-    if (blkdev->file_size < 0) {
-        BlockDriverState *bs = blk_bs(blkdev->blk);
-        const char *drv_name = bs ? bdrv_get_format_name(bs) : NULL;
-        xen_pv_printf(xendev, 1, "blk_getlength: %d (%s) | drv %s\n",
-                      (int)blkdev->file_size, strerror(-blkdev->file_size),
-                      drv_name ?: "-");
-        blkdev->file_size = 0;
-    }
-
-    xen_pv_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\","
-                  " size %" PRId64 " (%" PRId64 " MB)\n",
-                  blkdev->type, blkdev->fileproto, blkdev->filename,
-                  blkdev->file_size, blkdev->file_size / MiB);
-
-    /* Fill in number of sector size and number of sectors */
-    xenstore_write_be_int(xendev, "sector-size", blkdev->file_blk);
-    xenstore_write_be_int64(xendev, "sectors",
-                            blkdev->file_size / blkdev->file_blk);
-
-    if (xenstore_read_fe_int(xendev, "ring-page-order",
-                             &order) == -1) {
-        blkdev->nr_ring_ref = 1;
-
-        if (xenstore_read_fe_int(xendev, "ring-ref",
-                                 &ring_ref) == -1) {
-            return -1;
-        }
-        blkdev->ring_ref[0] = ring_ref;
-
-    } else if (order >= 0 && order <= MAX_RING_PAGE_ORDER) {
-        blkdev->nr_ring_ref = 1 << order;
-
-        for (i = 0; i < blkdev->nr_ring_ref; i++) {
-            char *key;
-
-            key = g_strdup_printf("ring-ref%u", i);
-            if (!key) {
-                return -1;
-            }
-
-            if (xenstore_read_fe_int(xendev, key,
-                                     &ring_ref) == -1) {
-                g_free(key);
-                return -1;
-            }
-            blkdev->ring_ref[i] = ring_ref;
-
-            g_free(key);
-        }
-    } else {
-        xen_pv_printf(xendev, 0, "invalid ring-page-order: %d\n",
-                      order);
-        return -1;
-    }
-
-    if (xenstore_read_fe_int(xendev, "event-channel",
-                             &xendev->remote_port) == -1) {
-        return -1;
-    }
-
-    if (!xendev->protocol) {
-        blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
-    } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_NATIVE) == 0) {
-        blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
-    } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_X86_32) == 0) {
-        blkdev->protocol = BLKIF_PROTOCOL_X86_32;
-    } else if (strcmp(xendev->protocol, XEN_IO_PROTO_ABI_X86_64) == 0) {
-        blkdev->protocol = BLKIF_PROTOCOL_X86_64;
-    } else {
-        blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
-    }
-
-    ring_size = XC_PAGE_SIZE * blkdev->nr_ring_ref;
-    switch (blkdev->protocol) {
-    case BLKIF_PROTOCOL_NATIVE:
-    {
-        blkdev->max_requests = __CONST_RING_SIZE(blkif, ring_size);
-        break;
-    }
-    case BLKIF_PROTOCOL_X86_32:
-    {
-        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_32, ring_size);
-        break;
-    }
-    case BLKIF_PROTOCOL_X86_64:
-    {
-        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_64, ring_size);
-        break;
-    }
-    default:
-        return -1;
-    }
-
-    /* Add on the number needed for the ring pages */
-    max_grants = blkdev->nr_ring_ref;
-
-    xen_be_set_max_grant_refs(xendev, max_grants);
-    blkdev->sring = xen_be_map_grant_refs(xendev, blkdev->ring_ref,
-                                          blkdev->nr_ring_ref,
-                                          PROT_READ | PROT_WRITE);
-    if (!blkdev->sring) {
-        return -1;
-    }
-
-    switch (blkdev->protocol) {
-    case BLKIF_PROTOCOL_NATIVE:
-    {
-        blkif_sring_t *sring_native = blkdev->sring;
-        BACK_RING_INIT(&blkdev->rings.native, sring_native, ring_size);
-        break;
-    }
-    case BLKIF_PROTOCOL_X86_32:
-    {
-        blkif_x86_32_sring_t *sring_x86_32 = blkdev->sring;
-
-        BACK_RING_INIT(&blkdev->rings.x86_32_part, sring_x86_32, ring_size);
-        break;
-    }
-    case BLKIF_PROTOCOL_X86_64:
-    {
-        blkif_x86_64_sring_t *sring_x86_64 = blkdev->sring;
-
-        BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64, ring_size);
-        break;
-    }
-    }
-
-    blk_set_aio_context(blkdev->blk, blkdev->ctx);
-
-    xen_be_bind_evtchn(xendev);
-
-    xen_pv_printf(xendev, 1, "ok: proto %s, nr-ring-ref %u, "
-                  "remote port %d, local port %d\n",
-                  xendev->protocol, blkdev->nr_ring_ref,
-                  xendev->remote_port, xendev->local_port);
-    return 0;
-}
-
-static void blk_disconnect(struct XenLegacyDevice *xendev)
-{
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
-
-    trace_xen_disk_disconnect(xendev->name);
-
-    aio_context_acquire(blkdev->ctx);
-
-    if (blkdev->blk) {
-        blk_set_aio_context(blkdev->blk, qemu_get_aio_context());
-        blk_detach_dev(blkdev->blk, blkdev);
-        blk_unref(blkdev->blk);
-        blkdev->blk = NULL;
-    }
-    xen_pv_unbind_evtchn(xendev);
-
-    aio_context_release(blkdev->ctx);
-
-    if (blkdev->sring) {
-        xen_be_unmap_grant_refs(xendev, blkdev->sring,
-                                blkdev->nr_ring_ref);
-        blkdev->sring = NULL;
-    }
-}
-
-static int blk_free(struct XenLegacyDevice *xendev)
-{
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
-    struct ioreq *ioreq;
-
-    trace_xen_disk_free(xendev->name);
-
-    blk_disconnect(xendev);
-
-    while (!QLIST_EMPTY(&blkdev->freelist)) {
-        ioreq = QLIST_FIRST(&blkdev->freelist);
-        QLIST_REMOVE(ioreq, list);
-        qemu_iovec_destroy(&ioreq->v);
-        g_free(ioreq);
-    }
-
-    g_free(blkdev->params);
-    g_free(blkdev->mode);
-    g_free(blkdev->type);
-    g_free(blkdev->dev);
-    g_free(blkdev->devtype);
-    qemu_bh_delete(blkdev->bh);
-    iothread_destroy(blkdev->iothread);
-    return 0;
-}
-
-static void blk_event(struct XenLegacyDevice *xendev)
-{
-    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
-
-    qemu_bh_schedule(blkdev->bh);
-}
-
-struct XenDevOps xen_blkdev_ops = {
-    .flags      = DEVOPS_FLAG_NEED_GNTDEV,
-    .size       = sizeof(struct XenBlkDev),
-    .alloc      = blk_alloc,
-    .init       = blk_init,
-    .initialise = blk_connect,
-    .disconnect = blk_disconnect,
-    .event      = blk_event,
-    .free       = blk_free,
-};
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 17/18] MAINTAINERS: add myself as a Xen maintainer
  2018-11-21 15:12   ` Paul Durrant
  (?)
  (?)
@ 2018-11-27 19:05   ` Stefano Stabellini
  -1 siblings, 0 replies; 157+ messages in thread
From: Stefano Stabellini @ 2018-11-27 19:05 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Anthony Perard, Paolo Bonzini

On Wed, 21 Nov 2018, Paul Durrant wrote:
> I have made many significant contributions to the Xen code in QEMU,
> particularly the recent patches introducing a new PV device framework.
> I intend to make further significant contributions, porting other PV back-
> ends to the new framework with the intent of eventually removing the
> legacy code. It therefore seems reasonable that I become a maintiner of
> the Xen code.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

Acked-by: Stefano Stabellini <sstabellini@kernel.org>

> ---
> Cc: Stefano Stabellini <sstabellini@kernel.org>
> Cc: Anthony Perard <anthony.perard@citrix.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  MAINTAINERS | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 5871f035c3..0b668dd205 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -382,6 +382,7 @@ Guest CPU Cores (Xen):
>  X86
>  M: Stefano Stabellini <sstabellini@kernel.org>
>  M: Anthony Perard <anthony.perard@citrix.com>
> +M: Paul Durrant <paul.durrant@citrix.com>
>  L: xen-devel@lists.xenproject.org
>  S: Supported
>  F: */xen*
> -- 
> 2.11.0
> 

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 17/18] MAINTAINERS: add myself as a Xen maintainer
  2018-11-21 15:12   ` Paul Durrant
  (?)
@ 2018-11-27 19:05   ` Stefano Stabellini
  -1 siblings, 0 replies; 157+ messages in thread
From: Stefano Stabellini @ 2018-11-27 19:05 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Stefano Stabellini, qemu-block, qemu-devel, Paolo Bonzini,
	Anthony Perard, xen-devel

On Wed, 21 Nov 2018, Paul Durrant wrote:
> I have made many significant contributions to the Xen code in QEMU,
> particularly the recent patches introducing a new PV device framework.
> I intend to make further significant contributions, porting other PV back-
> ends to the new framework with the intent of eventually removing the
> legacy code. It therefore seems reasonable that I become a maintiner of
> the Xen code.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

Acked-by: Stefano Stabellini <sstabellini@kernel.org>

> ---
> Cc: Stefano Stabellini <sstabellini@kernel.org>
> Cc: Anthony Perard <anthony.perard@citrix.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  MAINTAINERS | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 5871f035c3..0b668dd205 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -382,6 +382,7 @@ Guest CPU Cores (Xen):
>  X86
>  M: Stefano Stabellini <sstabellini@kernel.org>
>  M: Anthony Perard <anthony.perard@citrix.com>
> +M: Paul Durrant <paul.durrant@citrix.com>
>  L: xen-devel@lists.xenproject.org
>  S: Supported
>  F: */xen*
> -- 
> 2.11.0
> 

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 01/18] xen: re-name XenDevice to XenLegacyDevice...
  2018-11-21 15:11   ` Paul Durrant
  (?)
@ 2018-11-28 16:06   ` Anthony PERARD
  -1 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-11-28 16:06 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini, Greg Kurz,
	Kevin Wolf, Max Reitz, Marc-André Lureau, Paolo Bonzini,
	Richard Henderson, Eduardo Habkost, Michael S. Tsirkin,
	Marcel Apfelbaum, Jason Wang, Gerd Hoffmann

On Wed, Nov 21, 2018 at 03:11:54PM +0000, Paul Durrant wrote:
> ...and xen_backend.h to xen-legacy-backend.h
> 
> Rather than attempting to convert the existing backend infrastructure to
> be QOM compliant (which would be hard to do in an incremental fashion),
> subsequent patches will introduce a completely new framework for Xen PV
> backends. Hence it is necessary to re-name parts of existing code to avoid
> name clashes. The re-named 'legacy' infrastructure will be removed once all
> backends have been ported to the new framework.
> 
> This patch is purely cosmetic. No functional change.

Acked-by: Anthony PERARD <anthony.perard@citrix.com>

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 01/18] xen: re-name XenDevice to XenLegacyDevice...
  2018-11-21 15:11   ` Paul Durrant
  (?)
  (?)
@ 2018-11-28 16:06   ` Anthony PERARD
  -1 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-11-28 16:06 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Kevin Wolf, Stefano Stabellini, Eduardo Habkost, qemu-block,
	Michael S. Tsirkin, Jason Wang, qemu-devel, Greg Kurz,
	Paolo Bonzini, Gerd Hoffmann, Marcel Apfelbaum,
	Marc-André Lureau, xen-devel, Max Reitz, Richard Henderson

On Wed, Nov 21, 2018 at 03:11:54PM +0000, Paul Durrant wrote:
> ...and xen_backend.h to xen-legacy-backend.h
> 
> Rather than attempting to convert the existing backend infrastructure to
> be QOM compliant (which would be hard to do in an incremental fashion),
> subsequent patches will introduce a completely new framework for Xen PV
> backends. Hence it is necessary to re-name parts of existing code to avoid
> name clashes. The re-named 'legacy' infrastructure will be removed once all
> backends have been ported to the new framework.
> 
> This patch is purely cosmetic. No functional change.

Acked-by: Anthony PERARD <anthony.perard@citrix.com>

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
  2018-11-21 15:11 ` [Qemu-devel] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy Paul Durrant
  2018-11-28 16:19   ` [Qemu-block] " Kevin Wolf
@ 2018-11-28 16:19   ` Kevin Wolf
  2018-11-28 16:26       ` Paul Durrant
  2018-11-28 17:10     ` Anthony PERARD
  2 siblings, 1 reply; 157+ messages in thread
From: Kevin Wolf @ 2018-11-28 16:19 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Eduardo Habkost, Michael S. Tsirkin, Marcel Apfelbaum,
	Anthony Perard, Paolo Bonzini, Richard Henderson

Am 21.11.2018 um 16:11 hat Paul Durrant geschrieben:
> This patch adds the basic boilerplate for a 'XenBus' object that will act
> as a parent to 'XenDevice' PV backends.
> A new 'XenBridge' object is also added to connect XenBus to the system bus.
> 
> The XenBus object is instantiated by a new xen_bus_init() function called
> from the same sites as the legacy xen_be_init() function.
> 
> Subsequent patches will flesh-out the functionality of these objects.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

> diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> new file mode 100644
> index 0000000000..dede2d914a
> --- /dev/null
> +++ b/hw/xen/xen-bus.c
> @@ -0,0 +1,125 @@
> +/*
> + * Copyright (c) Citrix Systems Inc.
> + * All rights reserved.
> + */

This doesn't look very compatible with the GPL. In fact it might even
make it illegal for the QEMU project to distribute this code. :-)

Other files you add throughout the series seem to have the same problem.

Kevin

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
  2018-11-21 15:11 ` [Qemu-devel] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy Paul Durrant
@ 2018-11-28 16:19   ` Kevin Wolf
  2018-11-28 16:19   ` [Qemu-devel] " Kevin Wolf
  2018-11-28 17:10     ` Anthony PERARD
  2 siblings, 0 replies; 157+ messages in thread
From: Kevin Wolf @ 2018-11-28 16:19 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Stefano Stabellini, Eduardo Habkost, qemu-block,
	Michael S. Tsirkin, qemu-devel, Marcel Apfelbaum, Paolo Bonzini,
	Anthony Perard, xen-devel, Richard Henderson

Am 21.11.2018 um 16:11 hat Paul Durrant geschrieben:
> This patch adds the basic boilerplate for a 'XenBus' object that will act
> as a parent to 'XenDevice' PV backends.
> A new 'XenBridge' object is also added to connect XenBus to the system bus.
> 
> The XenBus object is instantiated by a new xen_bus_init() function called
> from the same sites as the legacy xen_be_init() function.
> 
> Subsequent patches will flesh-out the functionality of these objects.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

> diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> new file mode 100644
> index 0000000000..dede2d914a
> --- /dev/null
> +++ b/hw/xen/xen-bus.c
> @@ -0,0 +1,125 @@
> +/*
> + * Copyright (c) Citrix Systems Inc.
> + * All rights reserved.
> + */

This doesn't look very compatible with the GPL. In fact it might even
make it illegal for the QEMU project to distribute this code. :-)

Other files you add throughout the series seem to have the same problem.

Kevin

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
  2018-11-28 16:19   ` [Qemu-devel] " Kevin Wolf
@ 2018-11-28 16:26       ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-28 16:26 UTC (permalink / raw)
  To: 'Kevin Wolf'
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Eduardo Habkost, Michael S. Tsirkin, Marcel Apfelbaum,
	Anthony Perard, Paolo Bonzini, Richard Henderson

> -----Original Message-----
> From: Kevin Wolf [mailto:kwolf@redhat.com]
> Sent: 28 November 2018 16:19
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> Eduardo Habkost <ehabkost@redhat.com>; Michael S. Tsirkin
> <mst@redhat.com>; Marcel Apfelbaum <marcel.apfelbaum@gmail.com>; Anthony
> Perard <anthony.perard@citrix.com>; Paolo Bonzini <pbonzini@redhat.com>;
> Richard Henderson <rth@twiddle.net>
> Subject: Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and
> 'XenDevice' object hierarchy
> 
> Am 21.11.2018 um 16:11 hat Paul Durrant geschrieben:
> > This patch adds the basic boilerplate for a 'XenBus' object that will
> act
> > as a parent to 'XenDevice' PV backends.
> > A new 'XenBridge' object is also added to connect XenBus to the system
> bus.
> >
> > The XenBus object is instantiated by a new xen_bus_init() function
> called
> > from the same sites as the legacy xen_be_init() function.
> >
> > Subsequent patches will flesh-out the functionality of these objects.
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> 
> > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > new file mode 100644
> > index 0000000000..dede2d914a
> > --- /dev/null
> > +++ b/hw/xen/xen-bus.c
> > @@ -0,0 +1,125 @@
> > +/*
> > + * Copyright (c) Citrix Systems Inc.
> > + * All rights reserved.
> > + */
> 
> This doesn't look very compatible with the GPL. In fact it might even
> make it illegal for the QEMU project to distribute this code. :-)
> 
> Other files you add throughout the series seem to have the same problem.
> 

I was working on the assumption that a lack of explicit license meant that the overall project license as described in item 2 in LICENSE. Did I misinterpret that text?

  Paul

> Kevin

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
@ 2018-11-28 16:26       ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-28 16:26 UTC (permalink / raw)
  To: 'Kevin Wolf'
  Cc: Stefano Stabellini, Eduardo Habkost, qemu-block,
	Michael S. Tsirkin, qemu-devel, Marcel Apfelbaum, Paolo Bonzini,
	Anthony Perard, xen-devel, Richard Henderson

> -----Original Message-----
> From: Kevin Wolf [mailto:kwolf@redhat.com]
> Sent: 28 November 2018 16:19
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> Eduardo Habkost <ehabkost@redhat.com>; Michael S. Tsirkin
> <mst@redhat.com>; Marcel Apfelbaum <marcel.apfelbaum@gmail.com>; Anthony
> Perard <anthony.perard@citrix.com>; Paolo Bonzini <pbonzini@redhat.com>;
> Richard Henderson <rth@twiddle.net>
> Subject: Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and
> 'XenDevice' object hierarchy
> 
> Am 21.11.2018 um 16:11 hat Paul Durrant geschrieben:
> > This patch adds the basic boilerplate for a 'XenBus' object that will
> act
> > as a parent to 'XenDevice' PV backends.
> > A new 'XenBridge' object is also added to connect XenBus to the system
> bus.
> >
> > The XenBus object is instantiated by a new xen_bus_init() function
> called
> > from the same sites as the legacy xen_be_init() function.
> >
> > Subsequent patches will flesh-out the functionality of these objects.
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> 
> > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > new file mode 100644
> > index 0000000000..dede2d914a
> > --- /dev/null
> > +++ b/hw/xen/xen-bus.c
> > @@ -0,0 +1,125 @@
> > +/*
> > + * Copyright (c) Citrix Systems Inc.
> > + * All rights reserved.
> > + */
> 
> This doesn't look very compatible with the GPL. In fact it might even
> make it illegal for the QEMU project to distribute this code. :-)
> 
> Other files you add throughout the series seem to have the same problem.
> 

I was working on the assumption that a lack of explicit license meant that the overall project license as described in item 2 in LICENSE. Did I misinterpret that text?

  Paul

> Kevin

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
  2018-11-28 16:26       ` Paul Durrant
@ 2018-11-28 16:28         ` Paul Durrant
  -1 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-28 16:28 UTC (permalink / raw)
  To: 'Kevin Wolf'
  Cc: 'qemu-block@nongnu.org', 'qemu-devel@nongnu.org',
	'xen-devel@lists.xenproject.org',
	'Stefano Stabellini', 'Eduardo Habkost',
	'Michael S. Tsirkin', 'Marcel Apfelbaum',
	Anthony Perard, 'Paolo Bonzini',
	'Richard Henderson'

> -----Original Message-----
> From: Paul Durrant
> Sent: 28 November 2018 16:27
> To: 'Kevin Wolf' <kwolf@redhat.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> Eduardo Habkost <ehabkost@redhat.com>; Michael S. Tsirkin
> <mst@redhat.com>; Marcel Apfelbaum <marcel.apfelbaum@gmail.com>; Anthony
> Perard <anthony.perard@citrix.com>; Paolo Bonzini <pbonzini@redhat.com>;
> Richard Henderson <rth@twiddle.net>
> Subject: RE: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and
> 'XenDevice' object hierarchy
> 
> > -----Original Message-----
> > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > Sent: 28 November 2018 16:19
> > To: Paul Durrant <Paul.Durrant@citrix.com>
> > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> > Eduardo Habkost <ehabkost@redhat.com>; Michael S. Tsirkin
> > <mst@redhat.com>; Marcel Apfelbaum <marcel.apfelbaum@gmail.com>; Anthony
> > Perard <anthony.perard@citrix.com>; Paolo Bonzini <pbonzini@redhat.com>;
> > Richard Henderson <rth@twiddle.net>
> > Subject: Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and
> > 'XenDevice' object hierarchy
> >
> > Am 21.11.2018 um 16:11 hat Paul Durrant geschrieben:
> > > This patch adds the basic boilerplate for a 'XenBus' object that will
> > act
> > > as a parent to 'XenDevice' PV backends.
> > > A new 'XenBridge' object is also added to connect XenBus to the system
> > bus.
> > >
> > > The XenBus object is instantiated by a new xen_bus_init() function
> > called
> > > from the same sites as the legacy xen_be_init() function.
> > >
> > > Subsequent patches will flesh-out the functionality of these objects.
> > >
> > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> >
> > > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > > new file mode 100644
> > > index 0000000000..dede2d914a
> > > --- /dev/null
> > > +++ b/hw/xen/xen-bus.c
> > > @@ -0,0 +1,125 @@
> > > +/*
> > > + * Copyright (c) Citrix Systems Inc.
> > > + * All rights reserved.
> > > + */
> >
> > This doesn't look very compatible with the GPL. In fact it might even
> > make it illegal for the QEMU project to distribute this code. :-)
> >
> > Other files you add throughout the series seem to have the same problem.
> >
> 
> I was working on the assumption that a lack of explicit license meant that
> the overall project license as described in item 2 in LICENSE. Did I
                             ^ applied
> misinterpret that text?
> 
>   Paul
> 
> > Kevin

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
@ 2018-11-28 16:28         ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-28 16:28 UTC (permalink / raw)
  To: 'Kevin Wolf'
  Cc: 'Stefano Stabellini', 'Eduardo Habkost',
	'qemu-block@nongnu.org', 'Michael S. Tsirkin',
	'qemu-devel@nongnu.org', 'Marcel Apfelbaum',
	'Paolo Bonzini',
	Anthony Perard, 'xen-devel@lists.xenproject.org',
	'Richard Henderson'

> -----Original Message-----
> From: Paul Durrant
> Sent: 28 November 2018 16:27
> To: 'Kevin Wolf' <kwolf@redhat.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> Eduardo Habkost <ehabkost@redhat.com>; Michael S. Tsirkin
> <mst@redhat.com>; Marcel Apfelbaum <marcel.apfelbaum@gmail.com>; Anthony
> Perard <anthony.perard@citrix.com>; Paolo Bonzini <pbonzini@redhat.com>;
> Richard Henderson <rth@twiddle.net>
> Subject: RE: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and
> 'XenDevice' object hierarchy
> 
> > -----Original Message-----
> > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > Sent: 28 November 2018 16:19
> > To: Paul Durrant <Paul.Durrant@citrix.com>
> > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> > Eduardo Habkost <ehabkost@redhat.com>; Michael S. Tsirkin
> > <mst@redhat.com>; Marcel Apfelbaum <marcel.apfelbaum@gmail.com>; Anthony
> > Perard <anthony.perard@citrix.com>; Paolo Bonzini <pbonzini@redhat.com>;
> > Richard Henderson <rth@twiddle.net>
> > Subject: Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and
> > 'XenDevice' object hierarchy
> >
> > Am 21.11.2018 um 16:11 hat Paul Durrant geschrieben:
> > > This patch adds the basic boilerplate for a 'XenBus' object that will
> > act
> > > as a parent to 'XenDevice' PV backends.
> > > A new 'XenBridge' object is also added to connect XenBus to the system
> > bus.
> > >
> > > The XenBus object is instantiated by a new xen_bus_init() function
> > called
> > > from the same sites as the legacy xen_be_init() function.
> > >
> > > Subsequent patches will flesh-out the functionality of these objects.
> > >
> > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> >
> > > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > > new file mode 100644
> > > index 0000000000..dede2d914a
> > > --- /dev/null
> > > +++ b/hw/xen/xen-bus.c
> > > @@ -0,0 +1,125 @@
> > > +/*
> > > + * Copyright (c) Citrix Systems Inc.
> > > + * All rights reserved.
> > > + */
> >
> > This doesn't look very compatible with the GPL. In fact it might even
> > make it illegal for the QEMU project to distribute this code. :-)
> >
> > Other files you add throughout the series seem to have the same problem.
> >
> 
> I was working on the assumption that a lack of explicit license meant that
> the overall project license as described in item 2 in LICENSE. Did I
                             ^ applied
> misinterpret that text?
> 
>   Paul
> 
> > Kevin

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
  2018-11-28 16:26       ` Paul Durrant
@ 2018-11-28 16:28         ` Stefano Stabellini
  -1 siblings, 0 replies; 157+ messages in thread
From: Stefano Stabellini @ 2018-11-28 16:28 UTC (permalink / raw)
  To: Paul Durrant
  Cc: 'Kevin Wolf',
	qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Eduardo Habkost, Michael S. Tsirkin, Marcel Apfelbaum,
	Anthony Perard, Paolo Bonzini, Richard Henderson

On Wed, 28 Nov 2018, Paul Durrant wrote:
> > -----Original Message-----
> > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > Sent: 28 November 2018 16:19
> > To: Paul Durrant <Paul.Durrant@citrix.com>
> > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> > Eduardo Habkost <ehabkost@redhat.com>; Michael S. Tsirkin
> > <mst@redhat.com>; Marcel Apfelbaum <marcel.apfelbaum@gmail.com>; Anthony
> > Perard <anthony.perard@citrix.com>; Paolo Bonzini <pbonzini@redhat.com>;
> > Richard Henderson <rth@twiddle.net>
> > Subject: Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and
> > 'XenDevice' object hierarchy
> > 
> > Am 21.11.2018 um 16:11 hat Paul Durrant geschrieben:
> > > This patch adds the basic boilerplate for a 'XenBus' object that will
> > act
> > > as a parent to 'XenDevice' PV backends.
> > > A new 'XenBridge' object is also added to connect XenBus to the system
> > bus.
> > >
> > > The XenBus object is instantiated by a new xen_bus_init() function
> > called
> > > from the same sites as the legacy xen_be_init() function.
> > >
> > > Subsequent patches will flesh-out the functionality of these objects.
> > >
> > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > 
> > > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > > new file mode 100644
> > > index 0000000000..dede2d914a
> > > --- /dev/null
> > > +++ b/hw/xen/xen-bus.c
> > > @@ -0,0 +1,125 @@
> > > +/*
> > > + * Copyright (c) Citrix Systems Inc.
> > > + * All rights reserved.
> > > + */
> > 
> > This doesn't look very compatible with the GPL. In fact it might even
> > make it illegal for the QEMU project to distribute this code. :-)
> > 
> > Other files you add throughout the series seem to have the same problem.
> > 
> 
> I was working on the assumption that a lack of explicit license meant that the overall project license as described in item 2 in LICENSE. Did I misinterpret that text?

It's "All rights reserved." the problem

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
@ 2018-11-28 16:28         ` Stefano Stabellini
  0 siblings, 0 replies; 157+ messages in thread
From: Stefano Stabellini @ 2018-11-28 16:28 UTC (permalink / raw)
  To: Paul Durrant
  Cc: 'Kevin Wolf',
	Stefano Stabellini, Eduardo Habkost, qemu-block,
	Michael S. Tsirkin, qemu-devel, Marcel Apfelbaum, Paolo Bonzini,
	Anthony Perard, xen-devel, Richard Henderson

On Wed, 28 Nov 2018, Paul Durrant wrote:
> > -----Original Message-----
> > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > Sent: 28 November 2018 16:19
> > To: Paul Durrant <Paul.Durrant@citrix.com>
> > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> > Eduardo Habkost <ehabkost@redhat.com>; Michael S. Tsirkin
> > <mst@redhat.com>; Marcel Apfelbaum <marcel.apfelbaum@gmail.com>; Anthony
> > Perard <anthony.perard@citrix.com>; Paolo Bonzini <pbonzini@redhat.com>;
> > Richard Henderson <rth@twiddle.net>
> > Subject: Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and
> > 'XenDevice' object hierarchy
> > 
> > Am 21.11.2018 um 16:11 hat Paul Durrant geschrieben:
> > > This patch adds the basic boilerplate for a 'XenBus' object that will
> > act
> > > as a parent to 'XenDevice' PV backends.
> > > A new 'XenBridge' object is also added to connect XenBus to the system
> > bus.
> > >
> > > The XenBus object is instantiated by a new xen_bus_init() function
> > called
> > > from the same sites as the legacy xen_be_init() function.
> > >
> > > Subsequent patches will flesh-out the functionality of these objects.
> > >
> > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > 
> > > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > > new file mode 100644
> > > index 0000000000..dede2d914a
> > > --- /dev/null
> > > +++ b/hw/xen/xen-bus.c
> > > @@ -0,0 +1,125 @@
> > > +/*
> > > + * Copyright (c) Citrix Systems Inc.
> > > + * All rights reserved.
> > > + */
> > 
> > This doesn't look very compatible with the GPL. In fact it might even
> > make it illegal for the QEMU project to distribute this code. :-)
> > 
> > Other files you add throughout the series seem to have the same problem.
> > 
> 
> I was working on the assumption that a lack of explicit license meant that the overall project license as described in item 2 in LICENSE. Did I misinterpret that text?

It's "All rights reserved." the problem

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
  2018-11-28 16:28         ` Stefano Stabellini
@ 2018-11-28 16:29           ` Paul Durrant
  -1 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-28 16:29 UTC (permalink / raw)
  To: 'Stefano Stabellini'
  Cc: 'Kevin Wolf',
	qemu-block, qemu-devel, xen-devel, Eduardo Habkost,
	Michael S. Tsirkin, Marcel Apfelbaum, Anthony Perard,
	Paolo Bonzini, Richard Henderson

> -----Original Message-----
> From: Stefano Stabellini [mailto:sstabellini@kernel.org]
> Sent: 28 November 2018 16:28
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: 'Kevin Wolf' <kwolf@redhat.com>; qemu-block@nongnu.org; qemu-
> devel@nongnu.org; xen-devel@lists.xenproject.org; Stefano Stabellini
> <sstabellini@kernel.org>; Eduardo Habkost <ehabkost@redhat.com>; Michael
> S. Tsirkin <mst@redhat.com>; Marcel Apfelbaum
> <marcel.apfelbaum@gmail.com>; Anthony Perard <anthony.perard@citrix.com>;
> Paolo Bonzini <pbonzini@redhat.com>; Richard Henderson <rth@twiddle.net>
> Subject: RE: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and
> 'XenDevice' object hierarchy
> 
> On Wed, 28 Nov 2018, Paul Durrant wrote:
> > > -----Original Message-----
> > > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > > Sent: 28 November 2018 16:19
> > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > > devel@lists.xenproject.org; Stefano Stabellini
> <sstabellini@kernel.org>;
> > > Eduardo Habkost <ehabkost@redhat.com>; Michael S. Tsirkin
> > > <mst@redhat.com>; Marcel Apfelbaum <marcel.apfelbaum@gmail.com>;
> Anthony
> > > Perard <anthony.perard@citrix.com>; Paolo Bonzini
> <pbonzini@redhat.com>;
> > > Richard Henderson <rth@twiddle.net>
> > > Subject: Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus'
> and
> > > 'XenDevice' object hierarchy
> > >
> > > Am 21.11.2018 um 16:11 hat Paul Durrant geschrieben:
> > > > This patch adds the basic boilerplate for a 'XenBus' object that
> will
> > > act
> > > > as a parent to 'XenDevice' PV backends.
> > > > A new 'XenBridge' object is also added to connect XenBus to the
> system
> > > bus.
> > > >
> > > > The XenBus object is instantiated by a new xen_bus_init() function
> > > called
> > > > from the same sites as the legacy xen_be_init() function.
> > > >
> > > > Subsequent patches will flesh-out the functionality of these
> objects.
> > > >
> > > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > >
> > > > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > > > new file mode 100644
> > > > index 0000000000..dede2d914a
> > > > --- /dev/null
> > > > +++ b/hw/xen/xen-bus.c
> > > > @@ -0,0 +1,125 @@
> > > > +/*
> > > > + * Copyright (c) Citrix Systems Inc.
> > > > + * All rights reserved.
> > > > + */
> > >
> > > This doesn't look very compatible with the GPL. In fact it might even
> > > make it illegal for the QEMU project to distribute this code. :-)
> > >
> > > Other files you add throughout the series seem to have the same
> problem.
> > >
> >
> > I was working on the assumption that a lack of explicit license meant
> that the overall project license as described in item 2 in LICENSE. Did I
> misinterpret that text?
> 
> It's "All rights reserved." the problem

Oh, I see. I'm happy to remove that.

  Paul

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
@ 2018-11-28 16:29           ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-28 16:29 UTC (permalink / raw)
  To: 'Stefano Stabellini'
  Cc: 'Kevin Wolf',
	Eduardo Habkost, qemu-block, Michael S. Tsirkin, qemu-devel,
	Marcel Apfelbaum, Paolo Bonzini, Anthony Perard, xen-devel,
	Richard Henderson

> -----Original Message-----
> From: Stefano Stabellini [mailto:sstabellini@kernel.org]
> Sent: 28 November 2018 16:28
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: 'Kevin Wolf' <kwolf@redhat.com>; qemu-block@nongnu.org; qemu-
> devel@nongnu.org; xen-devel@lists.xenproject.org; Stefano Stabellini
> <sstabellini@kernel.org>; Eduardo Habkost <ehabkost@redhat.com>; Michael
> S. Tsirkin <mst@redhat.com>; Marcel Apfelbaum
> <marcel.apfelbaum@gmail.com>; Anthony Perard <anthony.perard@citrix.com>;
> Paolo Bonzini <pbonzini@redhat.com>; Richard Henderson <rth@twiddle.net>
> Subject: RE: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and
> 'XenDevice' object hierarchy
> 
> On Wed, 28 Nov 2018, Paul Durrant wrote:
> > > -----Original Message-----
> > > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > > Sent: 28 November 2018 16:19
> > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > > devel@lists.xenproject.org; Stefano Stabellini
> <sstabellini@kernel.org>;
> > > Eduardo Habkost <ehabkost@redhat.com>; Michael S. Tsirkin
> > > <mst@redhat.com>; Marcel Apfelbaum <marcel.apfelbaum@gmail.com>;
> Anthony
> > > Perard <anthony.perard@citrix.com>; Paolo Bonzini
> <pbonzini@redhat.com>;
> > > Richard Henderson <rth@twiddle.net>
> > > Subject: Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus'
> and
> > > 'XenDevice' object hierarchy
> > >
> > > Am 21.11.2018 um 16:11 hat Paul Durrant geschrieben:
> > > > This patch adds the basic boilerplate for a 'XenBus' object that
> will
> > > act
> > > > as a parent to 'XenDevice' PV backends.
> > > > A new 'XenBridge' object is also added to connect XenBus to the
> system
> > > bus.
> > > >
> > > > The XenBus object is instantiated by a new xen_bus_init() function
> > > called
> > > > from the same sites as the legacy xen_be_init() function.
> > > >
> > > > Subsequent patches will flesh-out the functionality of these
> objects.
> > > >
> > > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > >
> > > > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > > > new file mode 100644
> > > > index 0000000000..dede2d914a
> > > > --- /dev/null
> > > > +++ b/hw/xen/xen-bus.c
> > > > @@ -0,0 +1,125 @@
> > > > +/*
> > > > + * Copyright (c) Citrix Systems Inc.
> > > > + * All rights reserved.
> > > > + */
> > >
> > > This doesn't look very compatible with the GPL. In fact it might even
> > > make it illegal for the QEMU project to distribute this code. :-)
> > >
> > > Other files you add throughout the series seem to have the same
> problem.
> > >
> >
> > I was working on the assumption that a lack of explicit license meant
> that the overall project license as described in item 2 in LICENSE. Did I
> misinterpret that text?
> 
> It's "All rights reserved." the problem

Oh, I see. I'm happy to remove that.

  Paul


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 14/18] xen: add implementations of xen-qdisk connect and disconnect functions...
  2018-11-21 15:12 ` [Qemu-devel] " Paul Durrant
@ 2018-11-28 16:34     ` Kevin Wolf
  2018-12-04 12:33   ` Anthony PERARD
  2018-12-04 12:33   ` [Qemu-devel] " Anthony PERARD
  2 siblings, 0 replies; 157+ messages in thread
From: Kevin Wolf @ 2018-11-28 16:34 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Anthony Perard, Max Reitz

Am 21.11.2018 um 16:12 hat Paul Durrant geschrieben:
> ...and wire in the dataplane.
> 
> This patch adds the remaining code to make the xen-qdisk XenDevice
> functional. The parameters that a block frontend expects to find are
> populated in the backend xenstore area, and the 'ring-ref' and
> 'event-channel' values specified in the frontend xenstore area are
> mapped/bound and used to set up the dataplane.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> ---
> Cc: Stefano Stabellini <sstabellini@kernel.org>
> Cc: Anthony Perard <anthony.perard@citrix.com>
> Cc: Kevin Wolf <kwolf@redhat.com>
> Cc: Max Reitz <mreitz@redhat.com>
> ---
>  hw/block/xen-qdisk.c       | 140 +++++++++++++++++++++++++++++++++++++++++++++
>  hw/xen/xen-bus.c           |  12 ++--
>  include/hw/xen/xen-bus.h   |   8 +++
>  include/hw/xen/xen-qdisk.h |  12 ++++
>  4 files changed, 166 insertions(+), 6 deletions(-)
> 
> diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> index 35f7b70480..8c88393832 100644
> --- a/hw/block/xen-qdisk.c
> +++ b/hw/block/xen-qdisk.c
> @@ -9,6 +9,10 @@
>  #include "qapi/visitor.h"
>  #include "hw/hw.h"
>  #include "hw/xen/xen-qdisk.h"
> +#include "sysemu/blockdev.h"
> +#include "sysemu/block-backend.h"
> +#include "sysemu/iothread.h"
> +#include "dataplane/xen-qdisk.h"
>  #include "trace.h"
>  
>  static char *xen_qdisk_get_name(XenDevice *xendev, Error **errp)
> @@ -23,6 +27,11 @@ static void xen_qdisk_realize(XenDevice *xendev, Error **errp)
>  {
>      XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
>      XenQdiskVdev *vdev = &qdiskdev->vdev;
> +    BlockConf *conf = &qdiskdev->conf;
> +    DriveInfo *dinfo;
> +    bool is_cdrom;
> +    unsigned int info;
> +    int64_t size;
>  
>      if (!vdev->valid) {
>          error_setg(errp, "vdev property not set");
> @@ -30,13 +39,134 @@ static void xen_qdisk_realize(XenDevice *xendev, Error **errp)
>      }
>  
>      trace_xen_qdisk_realize(vdev->disk, vdev->partition);
> +
> +    if (!conf->blk) {
> +        error_setg(errp, "drive property not set");
> +        return;
> +    }
> +
> +    if (!blk_is_inserted(conf->blk)) {
> +        error_setg(errp, "device needs media, but drive is empty");
> +        return;
> +    }

Hm, the code below suggests that you support CD-ROMs. Don't you want to
support media change as well then? Which would mean that you need to
support empty drives.

> +    if (!blkconf_apply_backend_options(conf, blk_is_read_only(conf->blk),
> +                                       false, errp)) {
> +        return;
> +    }
> +
> +    if (!blkconf_geometry(conf, NULL, 65535, 255, 255, errp)) {
> +        return;
> +    }
> +
> +    dinfo = blk_legacy_dinfo(conf->blk);
> +    is_cdrom = (dinfo && dinfo->media_cd);

It's called legacy for a reason. Don't use this in new devices.

The proper way is to have two different devices for hard disks and CDs
(like scsi-hd and scsi-cd).

Kevin

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 14/18] xen: add implementations of xen-qdisk connect and disconnect functions...
@ 2018-11-28 16:34     ` Kevin Wolf
  0 siblings, 0 replies; 157+ messages in thread
From: Kevin Wolf @ 2018-11-28 16:34 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Stefano Stabellini, qemu-block, qemu-devel, Max Reitz,
	Anthony Perard, xen-devel

Am 21.11.2018 um 16:12 hat Paul Durrant geschrieben:
> ...and wire in the dataplane.
> 
> This patch adds the remaining code to make the xen-qdisk XenDevice
> functional. The parameters that a block frontend expects to find are
> populated in the backend xenstore area, and the 'ring-ref' and
> 'event-channel' values specified in the frontend xenstore area are
> mapped/bound and used to set up the dataplane.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> ---
> Cc: Stefano Stabellini <sstabellini@kernel.org>
> Cc: Anthony Perard <anthony.perard@citrix.com>
> Cc: Kevin Wolf <kwolf@redhat.com>
> Cc: Max Reitz <mreitz@redhat.com>
> ---
>  hw/block/xen-qdisk.c       | 140 +++++++++++++++++++++++++++++++++++++++++++++
>  hw/xen/xen-bus.c           |  12 ++--
>  include/hw/xen/xen-bus.h   |   8 +++
>  include/hw/xen/xen-qdisk.h |  12 ++++
>  4 files changed, 166 insertions(+), 6 deletions(-)
> 
> diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> index 35f7b70480..8c88393832 100644
> --- a/hw/block/xen-qdisk.c
> +++ b/hw/block/xen-qdisk.c
> @@ -9,6 +9,10 @@
>  #include "qapi/visitor.h"
>  #include "hw/hw.h"
>  #include "hw/xen/xen-qdisk.h"
> +#include "sysemu/blockdev.h"
> +#include "sysemu/block-backend.h"
> +#include "sysemu/iothread.h"
> +#include "dataplane/xen-qdisk.h"
>  #include "trace.h"
>  
>  static char *xen_qdisk_get_name(XenDevice *xendev, Error **errp)
> @@ -23,6 +27,11 @@ static void xen_qdisk_realize(XenDevice *xendev, Error **errp)
>  {
>      XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
>      XenQdiskVdev *vdev = &qdiskdev->vdev;
> +    BlockConf *conf = &qdiskdev->conf;
> +    DriveInfo *dinfo;
> +    bool is_cdrom;
> +    unsigned int info;
> +    int64_t size;
>  
>      if (!vdev->valid) {
>          error_setg(errp, "vdev property not set");
> @@ -30,13 +39,134 @@ static void xen_qdisk_realize(XenDevice *xendev, Error **errp)
>      }
>  
>      trace_xen_qdisk_realize(vdev->disk, vdev->partition);
> +
> +    if (!conf->blk) {
> +        error_setg(errp, "drive property not set");
> +        return;
> +    }
> +
> +    if (!blk_is_inserted(conf->blk)) {
> +        error_setg(errp, "device needs media, but drive is empty");
> +        return;
> +    }

Hm, the code below suggests that you support CD-ROMs. Don't you want to
support media change as well then? Which would mean that you need to
support empty drives.

> +    if (!blkconf_apply_backend_options(conf, blk_is_read_only(conf->blk),
> +                                       false, errp)) {
> +        return;
> +    }
> +
> +    if (!blkconf_geometry(conf, NULL, 65535, 255, 255, errp)) {
> +        return;
> +    }
> +
> +    dinfo = blk_legacy_dinfo(conf->blk);
> +    is_cdrom = (dinfo && dinfo->media_cd);

It's called legacy for a reason. Don't use this in new devices.

The proper way is to have two different devices for hard disks and CDs
(like scsi-hd and scsi-cd).

Kevin

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
  2018-11-28 16:29           ` Paul Durrant
@ 2018-11-28 16:39             ` Kevin Wolf
  -1 siblings, 0 replies; 157+ messages in thread
From: Kevin Wolf @ 2018-11-28 16:39 UTC (permalink / raw)
  To: Paul Durrant
  Cc: 'Stefano Stabellini',
	qemu-block, qemu-devel, xen-devel, Eduardo Habkost,
	Michael S. Tsirkin, Marcel Apfelbaum, Anthony Perard,
	Paolo Bonzini, Richard Henderson

Am 28.11.2018 um 17:29 hat Paul Durrant geschrieben:
> > -----Original Message-----
> > From: Stefano Stabellini [mailto:sstabellini@kernel.org]
> > Sent: 28 November 2018 16:28
> > To: Paul Durrant <Paul.Durrant@citrix.com>
> > Cc: 'Kevin Wolf' <kwolf@redhat.com>; qemu-block@nongnu.org; qemu-
> > devel@nongnu.org; xen-devel@lists.xenproject.org; Stefano Stabellini
> > <sstabellini@kernel.org>; Eduardo Habkost <ehabkost@redhat.com>; Michael
> > S. Tsirkin <mst@redhat.com>; Marcel Apfelbaum
> > <marcel.apfelbaum@gmail.com>; Anthony Perard <anthony.perard@citrix.com>;
> > Paolo Bonzini <pbonzini@redhat.com>; Richard Henderson <rth@twiddle.net>
> > Subject: RE: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and
> > 'XenDevice' object hierarchy
> > 
> > On Wed, 28 Nov 2018, Paul Durrant wrote:
> > > > -----Original Message-----
> > > > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > > > Sent: 28 November 2018 16:19
> > > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > > > devel@lists.xenproject.org; Stefano Stabellini
> > <sstabellini@kernel.org>;
> > > > Eduardo Habkost <ehabkost@redhat.com>; Michael S. Tsirkin
> > > > <mst@redhat.com>; Marcel Apfelbaum <marcel.apfelbaum@gmail.com>;
> > Anthony
> > > > Perard <anthony.perard@citrix.com>; Paolo Bonzini
> > <pbonzini@redhat.com>;
> > > > Richard Henderson <rth@twiddle.net>
> > > > Subject: Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus'
> > and
> > > > 'XenDevice' object hierarchy
> > > >
> > > > Am 21.11.2018 um 16:11 hat Paul Durrant geschrieben:
> > > > > This patch adds the basic boilerplate for a 'XenBus' object that
> > will
> > > > act
> > > > > as a parent to 'XenDevice' PV backends.
> > > > > A new 'XenBridge' object is also added to connect XenBus to the
> > system
> > > > bus.
> > > > >
> > > > > The XenBus object is instantiated by a new xen_bus_init() function
> > > > called
> > > > > from the same sites as the legacy xen_be_init() function.
> > > > >
> > > > > Subsequent patches will flesh-out the functionality of these
> > objects.
> > > > >
> > > > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > > >
> > > > > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > > > > new file mode 100644
> > > > > index 0000000000..dede2d914a
> > > > > --- /dev/null
> > > > > +++ b/hw/xen/xen-bus.c
> > > > > @@ -0,0 +1,125 @@
> > > > > +/*
> > > > > + * Copyright (c) Citrix Systems Inc.
> > > > > + * All rights reserved.
> > > > > + */
> > > >
> > > > This doesn't look very compatible with the GPL. In fact it might even
> > > > make it illegal for the QEMU project to distribute this code. :-)
> > > >
> > > > Other files you add throughout the series seem to have the same
> > problem.
> > > >
> > >
> > > I was working on the assumption that a lack of explicit license meant
> > that the overall project license as described in item 2 in LICENSE. Did I
> > misinterpret that text?
> > 
> > It's "All rights reserved." the problem
> 
> Oh, I see. I'm happy to remove that.

That would be better at least. I'm not sure about files that have a
copyright header, but no license statement. Do such files exist yet in
the source tree? To be on the safe side, I'd just stick with the
established practice, which is having a license header in every file.

By the way, in a later patch you remove the existing license header,
which is different from the default license (because parts of the source
file are GPL 2 only). If you can't prove that all such parts (and parts
derived from them) have been removed, this is also a problem.

Kevin

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
@ 2018-11-28 16:39             ` Kevin Wolf
  0 siblings, 0 replies; 157+ messages in thread
From: Kevin Wolf @ 2018-11-28 16:39 UTC (permalink / raw)
  To: Paul Durrant
  Cc: 'Stefano Stabellini',
	Eduardo Habkost, qemu-block, Michael S. Tsirkin, qemu-devel,
	Marcel Apfelbaum, Paolo Bonzini, Anthony Perard, xen-devel,
	Richard Henderson

Am 28.11.2018 um 17:29 hat Paul Durrant geschrieben:
> > -----Original Message-----
> > From: Stefano Stabellini [mailto:sstabellini@kernel.org]
> > Sent: 28 November 2018 16:28
> > To: Paul Durrant <Paul.Durrant@citrix.com>
> > Cc: 'Kevin Wolf' <kwolf@redhat.com>; qemu-block@nongnu.org; qemu-
> > devel@nongnu.org; xen-devel@lists.xenproject.org; Stefano Stabellini
> > <sstabellini@kernel.org>; Eduardo Habkost <ehabkost@redhat.com>; Michael
> > S. Tsirkin <mst@redhat.com>; Marcel Apfelbaum
> > <marcel.apfelbaum@gmail.com>; Anthony Perard <anthony.perard@citrix.com>;
> > Paolo Bonzini <pbonzini@redhat.com>; Richard Henderson <rth@twiddle.net>
> > Subject: RE: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and
> > 'XenDevice' object hierarchy
> > 
> > On Wed, 28 Nov 2018, Paul Durrant wrote:
> > > > -----Original Message-----
> > > > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > > > Sent: 28 November 2018 16:19
> > > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > > > devel@lists.xenproject.org; Stefano Stabellini
> > <sstabellini@kernel.org>;
> > > > Eduardo Habkost <ehabkost@redhat.com>; Michael S. Tsirkin
> > > > <mst@redhat.com>; Marcel Apfelbaum <marcel.apfelbaum@gmail.com>;
> > Anthony
> > > > Perard <anthony.perard@citrix.com>; Paolo Bonzini
> > <pbonzini@redhat.com>;
> > > > Richard Henderson <rth@twiddle.net>
> > > > Subject: Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus'
> > and
> > > > 'XenDevice' object hierarchy
> > > >
> > > > Am 21.11.2018 um 16:11 hat Paul Durrant geschrieben:
> > > > > This patch adds the basic boilerplate for a 'XenBus' object that
> > will
> > > > act
> > > > > as a parent to 'XenDevice' PV backends.
> > > > > A new 'XenBridge' object is also added to connect XenBus to the
> > system
> > > > bus.
> > > > >
> > > > > The XenBus object is instantiated by a new xen_bus_init() function
> > > > called
> > > > > from the same sites as the legacy xen_be_init() function.
> > > > >
> > > > > Subsequent patches will flesh-out the functionality of these
> > objects.
> > > > >
> > > > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > > >
> > > > > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > > > > new file mode 100644
> > > > > index 0000000000..dede2d914a
> > > > > --- /dev/null
> > > > > +++ b/hw/xen/xen-bus.c
> > > > > @@ -0,0 +1,125 @@
> > > > > +/*
> > > > > + * Copyright (c) Citrix Systems Inc.
> > > > > + * All rights reserved.
> > > > > + */
> > > >
> > > > This doesn't look very compatible with the GPL. In fact it might even
> > > > make it illegal for the QEMU project to distribute this code. :-)
> > > >
> > > > Other files you add throughout the series seem to have the same
> > problem.
> > > >
> > >
> > > I was working on the assumption that a lack of explicit license meant
> > that the overall project license as described in item 2 in LICENSE. Did I
> > misinterpret that text?
> > 
> > It's "All rights reserved." the problem
> 
> Oh, I see. I'm happy to remove that.

That would be better at least. I'm not sure about files that have a
copyright header, but no license statement. Do such files exist yet in
the source tree? To be on the safe side, I'd just stick with the
established practice, which is having a license header in every file.

By the way, in a later patch you remove the existing license header,
which is different from the default license (because parts of the source
file are GPL 2 only). If you can't prove that all such parts (and parts
derived from them) have been removed, this is also a problem.

Kevin

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 14/18] xen: add implementations of xen-qdisk connect and disconnect functions...
  2018-11-28 16:34     ` Kevin Wolf
@ 2018-11-28 16:40       ` Paul Durrant
  -1 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-28 16:40 UTC (permalink / raw)
  To: 'Kevin Wolf'
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Anthony Perard, Max Reitz

> -----Original Message-----
> From: Kevin Wolf [mailto:kwolf@redhat.com]
> Sent: 28 November 2018 16:35
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> Anthony Perard <anthony.perard@citrix.com>; Max Reitz <mreitz@redhat.com>
> Subject: Re: [PATCH 14/18] xen: add implementations of xen-qdisk connect
> and disconnect functions...
> 
> Am 21.11.2018 um 16:12 hat Paul Durrant geschrieben:
> > ...and wire in the dataplane.
> >
> > This patch adds the remaining code to make the xen-qdisk XenDevice
> > functional. The parameters that a block frontend expects to find are
> > populated in the backend xenstore area, and the 'ring-ref' and
> > 'event-channel' values specified in the frontend xenstore area are
> > mapped/bound and used to set up the dataplane.
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > ---
> > Cc: Stefano Stabellini <sstabellini@kernel.org>
> > Cc: Anthony Perard <anthony.perard@citrix.com>
> > Cc: Kevin Wolf <kwolf@redhat.com>
> > Cc: Max Reitz <mreitz@redhat.com>
> > ---
> >  hw/block/xen-qdisk.c       | 140
> +++++++++++++++++++++++++++++++++++++++++++++
> >  hw/xen/xen-bus.c           |  12 ++--
> >  include/hw/xen/xen-bus.h   |   8 +++
> >  include/hw/xen/xen-qdisk.h |  12 ++++
> >  4 files changed, 166 insertions(+), 6 deletions(-)
> >
> > diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> > index 35f7b70480..8c88393832 100644
> > --- a/hw/block/xen-qdisk.c
> > +++ b/hw/block/xen-qdisk.c
> > @@ -9,6 +9,10 @@
> >  #include "qapi/visitor.h"
> >  #include "hw/hw.h"
> >  #include "hw/xen/xen-qdisk.h"
> > +#include "sysemu/blockdev.h"
> > +#include "sysemu/block-backend.h"
> > +#include "sysemu/iothread.h"
> > +#include "dataplane/xen-qdisk.h"
> >  #include "trace.h"
> >
> >  static char *xen_qdisk_get_name(XenDevice *xendev, Error **errp)
> > @@ -23,6 +27,11 @@ static void xen_qdisk_realize(XenDevice *xendev,
> Error **errp)
> >  {
> >      XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
> >      XenQdiskVdev *vdev = &qdiskdev->vdev;
> > +    BlockConf *conf = &qdiskdev->conf;
> > +    DriveInfo *dinfo;
> > +    bool is_cdrom;
> > +    unsigned int info;
> > +    int64_t size;
> >
> >      if (!vdev->valid) {
> >          error_setg(errp, "vdev property not set");
> > @@ -30,13 +39,134 @@ static void xen_qdisk_realize(XenDevice *xendev,
> Error **errp)
> >      }
> >
> >      trace_xen_qdisk_realize(vdev->disk, vdev->partition);
> > +
> > +    if (!conf->blk) {
> > +        error_setg(errp, "drive property not set");
> > +        return;
> > +    }
> > +
> > +    if (!blk_is_inserted(conf->blk)) {
> > +        error_setg(errp, "device needs media, but drive is empty");
> > +        return;
> > +    }
> 
> Hm, the code below suggests that you support CD-ROMs. Don't you want to
> support media change as well then? Which would mean that you need to
> support empty drives.

Yes, that's a good point. I should get rid of that check.

> 
> > +    if (!blkconf_apply_backend_options(conf, blk_is_read_only(conf-
> >blk),
> > +                                       false, errp)) {
> > +        return;
> > +    }
> > +
> > +    if (!blkconf_geometry(conf, NULL, 65535, 255, 255, errp)) {
> > +        return;
> > +    }
> > +
> > +    dinfo = blk_legacy_dinfo(conf->blk);
> > +    is_cdrom = (dinfo && dinfo->media_cd);
> 
> It's called legacy for a reason. Don't use this in new devices.
> 
> The proper way is to have two different devices for hard disks and CDs
> (like scsi-hd and scsi-cd).

...or presumably I could have a property? The legacy init code could then set it based on the drive info.

  Paul

> 
> Kevin

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 14/18] xen: add implementations of xen-qdisk connect and disconnect functions...
@ 2018-11-28 16:40       ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-28 16:40 UTC (permalink / raw)
  To: 'Kevin Wolf'
  Cc: Stefano Stabellini, qemu-block, qemu-devel, Max Reitz,
	Anthony Perard, xen-devel

> -----Original Message-----
> From: Kevin Wolf [mailto:kwolf@redhat.com]
> Sent: 28 November 2018 16:35
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> Anthony Perard <anthony.perard@citrix.com>; Max Reitz <mreitz@redhat.com>
> Subject: Re: [PATCH 14/18] xen: add implementations of xen-qdisk connect
> and disconnect functions...
> 
> Am 21.11.2018 um 16:12 hat Paul Durrant geschrieben:
> > ...and wire in the dataplane.
> >
> > This patch adds the remaining code to make the xen-qdisk XenDevice
> > functional. The parameters that a block frontend expects to find are
> > populated in the backend xenstore area, and the 'ring-ref' and
> > 'event-channel' values specified in the frontend xenstore area are
> > mapped/bound and used to set up the dataplane.
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > ---
> > Cc: Stefano Stabellini <sstabellini@kernel.org>
> > Cc: Anthony Perard <anthony.perard@citrix.com>
> > Cc: Kevin Wolf <kwolf@redhat.com>
> > Cc: Max Reitz <mreitz@redhat.com>
> > ---
> >  hw/block/xen-qdisk.c       | 140
> +++++++++++++++++++++++++++++++++++++++++++++
> >  hw/xen/xen-bus.c           |  12 ++--
> >  include/hw/xen/xen-bus.h   |   8 +++
> >  include/hw/xen/xen-qdisk.h |  12 ++++
> >  4 files changed, 166 insertions(+), 6 deletions(-)
> >
> > diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> > index 35f7b70480..8c88393832 100644
> > --- a/hw/block/xen-qdisk.c
> > +++ b/hw/block/xen-qdisk.c
> > @@ -9,6 +9,10 @@
> >  #include "qapi/visitor.h"
> >  #include "hw/hw.h"
> >  #include "hw/xen/xen-qdisk.h"
> > +#include "sysemu/blockdev.h"
> > +#include "sysemu/block-backend.h"
> > +#include "sysemu/iothread.h"
> > +#include "dataplane/xen-qdisk.h"
> >  #include "trace.h"
> >
> >  static char *xen_qdisk_get_name(XenDevice *xendev, Error **errp)
> > @@ -23,6 +27,11 @@ static void xen_qdisk_realize(XenDevice *xendev,
> Error **errp)
> >  {
> >      XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
> >      XenQdiskVdev *vdev = &qdiskdev->vdev;
> > +    BlockConf *conf = &qdiskdev->conf;
> > +    DriveInfo *dinfo;
> > +    bool is_cdrom;
> > +    unsigned int info;
> > +    int64_t size;
> >
> >      if (!vdev->valid) {
> >          error_setg(errp, "vdev property not set");
> > @@ -30,13 +39,134 @@ static void xen_qdisk_realize(XenDevice *xendev,
> Error **errp)
> >      }
> >
> >      trace_xen_qdisk_realize(vdev->disk, vdev->partition);
> > +
> > +    if (!conf->blk) {
> > +        error_setg(errp, "drive property not set");
> > +        return;
> > +    }
> > +
> > +    if (!blk_is_inserted(conf->blk)) {
> > +        error_setg(errp, "device needs media, but drive is empty");
> > +        return;
> > +    }
> 
> Hm, the code below suggests that you support CD-ROMs. Don't you want to
> support media change as well then? Which would mean that you need to
> support empty drives.

Yes, that's a good point. I should get rid of that check.

> 
> > +    if (!blkconf_apply_backend_options(conf, blk_is_read_only(conf-
> >blk),
> > +                                       false, errp)) {
> > +        return;
> > +    }
> > +
> > +    if (!blkconf_geometry(conf, NULL, 65535, 255, 255, errp)) {
> > +        return;
> > +    }
> > +
> > +    dinfo = blk_legacy_dinfo(conf->blk);
> > +    is_cdrom = (dinfo && dinfo->media_cd);
> 
> It's called legacy for a reason. Don't use this in new devices.
> 
> The proper way is to have two different devices for hard disks and CDs
> (like scsi-hd and scsi-cd).

...or presumably I could have a property? The legacy init code could then set it based on the drive info.

  Paul

> 
> Kevin

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
  2018-11-28 16:39             ` Kevin Wolf
  (?)
@ 2018-11-28 16:45             ` Paul Durrant
  2018-11-28 16:46                 ` Paul Durrant
  -1 siblings, 1 reply; 157+ messages in thread
From: Paul Durrant @ 2018-11-28 16:45 UTC (permalink / raw)
  To: 'Kevin Wolf'
  Cc: 'Stefano Stabellini',
	qemu-block, qemu-devel, xen-devel, Eduardo Habkost,
	Michael S. Tsirkin, Marcel Apfelbaum, Anthony Perard,
	Paolo Bonzini, Richard Henderson

> -----Original Message-----
> From: Kevin Wolf [mailto:kwolf@redhat.com]
> Sent: 28 November 2018 16:39
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: 'Stefano Stabellini' <sstabellini@kernel.org>; qemu-block@nongnu.org;
> qemu-devel@nongnu.org; xen-devel@lists.xenproject.org; Eduardo Habkost
> <ehabkost@redhat.com>; Michael S. Tsirkin <mst@redhat.com>; Marcel
> Apfelbaum <marcel.apfelbaum@gmail.com>; Anthony Perard
> <anthony.perard@citrix.com>; Paolo Bonzini <pbonzini@redhat.com>; Richard
> Henderson <rth@twiddle.net>
> Subject: Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and
> 'XenDevice' object hierarchy
> 
> Am 28.11.2018 um 17:29 hat Paul Durrant geschrieben:
> > > -----Original Message-----
> > > From: Stefano Stabellini [mailto:sstabellini@kernel.org]
> > > Sent: 28 November 2018 16:28
> > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > Cc: 'Kevin Wolf' <kwolf@redhat.com>; qemu-block@nongnu.org; qemu-
> > > devel@nongnu.org; xen-devel@lists.xenproject.org; Stefano Stabellini
> > > <sstabellini@kernel.org>; Eduardo Habkost <ehabkost@redhat.com>;
> Michael
> > > S. Tsirkin <mst@redhat.com>; Marcel Apfelbaum
> > > <marcel.apfelbaum@gmail.com>; Anthony Perard
> <anthony.perard@citrix.com>;
> > > Paolo Bonzini <pbonzini@redhat.com>; Richard Henderson
> <rth@twiddle.net>
> > > Subject: RE: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus'
> and
> > > 'XenDevice' object hierarchy
> > >
> > > On Wed, 28 Nov 2018, Paul Durrant wrote:
> > > > > -----Original Message-----
> > > > > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > > > > Sent: 28 November 2018 16:19
> > > > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > > > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > > > > devel@lists.xenproject.org; Stefano Stabellini
> > > <sstabellini@kernel.org>;
> > > > > Eduardo Habkost <ehabkost@redhat.com>; Michael S. Tsirkin
> > > > > <mst@redhat.com>; Marcel Apfelbaum <marcel.apfelbaum@gmail.com>;
> > > Anthony
> > > > > Perard <anthony.perard@citrix.com>; Paolo Bonzini
> > > <pbonzini@redhat.com>;
> > > > > Richard Henderson <rth@twiddle.net>
> > > > > Subject: Re: [Qemu-block] [PATCH 02/18] xen: introduce new
> 'XenBus'
> > > and
> > > > > 'XenDevice' object hierarchy
> > > > >
> > > > > Am 21.11.2018 um 16:11 hat Paul Durrant geschrieben:
> > > > > > This patch adds the basic boilerplate for a 'XenBus' object that
> > > will
> > > > > act
> > > > > > as a parent to 'XenDevice' PV backends.
> > > > > > A new 'XenBridge' object is also added to connect XenBus to the
> > > system
> > > > > bus.
> > > > > >
> > > > > > The XenBus object is instantiated by a new xen_bus_init()
> function
> > > > > called
> > > > > > from the same sites as the legacy xen_be_init() function.
> > > > > >
> > > > > > Subsequent patches will flesh-out the functionality of these
> > > objects.
> > > > > >
> > > > > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > > > >
> > > > > > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > > > > > new file mode 100644
> > > > > > index 0000000000..dede2d914a
> > > > > > --- /dev/null
> > > > > > +++ b/hw/xen/xen-bus.c
> > > > > > @@ -0,0 +1,125 @@
> > > > > > +/*
> > > > > > + * Copyright (c) Citrix Systems Inc.
> > > > > > + * All rights reserved.
> > > > > > + */
> > > > >
> > > > > This doesn't look very compatible with the GPL. In fact it might
> even
> > > > > make it illegal for the QEMU project to distribute this code. :-)
> > > > >
> > > > > Other files you add throughout the series seem to have the same
> > > problem.
> > > > >
> > > >
> > > > I was working on the assumption that a lack of explicit license
> meant
> > > that the overall project license as described in item 2 in LICENSE.
> Did I
> > > misinterpret that text?
> > >
> > > It's "All rights reserved." the problem
> >
> > Oh, I see. I'm happy to remove that.
> 
> That would be better at least. I'm not sure about files that have a
> copyright header, but no license statement. Do such files exist yet in
> the source tree?

Yes, there's quite a few... e.g. (first ones I tripped over) hw/rdma/rdma_backend.c, hw/virtio/vhost-backend.c, ... 

> To be on the safe side, I'd just stick with the
> established practice, which is having a license header in every file.

Ok... if that is established practice. It really wasn't clear.

> 
> By the way, in a later patch you remove the existing license header,
> which is different from the default license (because parts of the source
> file are GPL 2 only). If you can't prove that all such parts (and parts
> derived from them) have been removed, this is also a problem.
> 

What should I do? I am duplicating xen_disk, and then heavily modifying it. Should I just leave the old boilerplate in place?

  Paul

> Kevin

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
  2018-11-28 16:39             ` Kevin Wolf
  (?)
  (?)
@ 2018-11-28 16:45             ` Paul Durrant
  -1 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-28 16:45 UTC (permalink / raw)
  To: 'Kevin Wolf'
  Cc: 'Stefano Stabellini',
	Eduardo Habkost, qemu-block, Michael S. Tsirkin, qemu-devel,
	Marcel Apfelbaum, Paolo Bonzini, Anthony Perard, xen-devel,
	Richard Henderson

> -----Original Message-----
> From: Kevin Wolf [mailto:kwolf@redhat.com]
> Sent: 28 November 2018 16:39
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: 'Stefano Stabellini' <sstabellini@kernel.org>; qemu-block@nongnu.org;
> qemu-devel@nongnu.org; xen-devel@lists.xenproject.org; Eduardo Habkost
> <ehabkost@redhat.com>; Michael S. Tsirkin <mst@redhat.com>; Marcel
> Apfelbaum <marcel.apfelbaum@gmail.com>; Anthony Perard
> <anthony.perard@citrix.com>; Paolo Bonzini <pbonzini@redhat.com>; Richard
> Henderson <rth@twiddle.net>
> Subject: Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and
> 'XenDevice' object hierarchy
> 
> Am 28.11.2018 um 17:29 hat Paul Durrant geschrieben:
> > > -----Original Message-----
> > > From: Stefano Stabellini [mailto:sstabellini@kernel.org]
> > > Sent: 28 November 2018 16:28
> > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > Cc: 'Kevin Wolf' <kwolf@redhat.com>; qemu-block@nongnu.org; qemu-
> > > devel@nongnu.org; xen-devel@lists.xenproject.org; Stefano Stabellini
> > > <sstabellini@kernel.org>; Eduardo Habkost <ehabkost@redhat.com>;
> Michael
> > > S. Tsirkin <mst@redhat.com>; Marcel Apfelbaum
> > > <marcel.apfelbaum@gmail.com>; Anthony Perard
> <anthony.perard@citrix.com>;
> > > Paolo Bonzini <pbonzini@redhat.com>; Richard Henderson
> <rth@twiddle.net>
> > > Subject: RE: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus'
> and
> > > 'XenDevice' object hierarchy
> > >
> > > On Wed, 28 Nov 2018, Paul Durrant wrote:
> > > > > -----Original Message-----
> > > > > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > > > > Sent: 28 November 2018 16:19
> > > > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > > > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > > > > devel@lists.xenproject.org; Stefano Stabellini
> > > <sstabellini@kernel.org>;
> > > > > Eduardo Habkost <ehabkost@redhat.com>; Michael S. Tsirkin
> > > > > <mst@redhat.com>; Marcel Apfelbaum <marcel.apfelbaum@gmail.com>;
> > > Anthony
> > > > > Perard <anthony.perard@citrix.com>; Paolo Bonzini
> > > <pbonzini@redhat.com>;
> > > > > Richard Henderson <rth@twiddle.net>
> > > > > Subject: Re: [Qemu-block] [PATCH 02/18] xen: introduce new
> 'XenBus'
> > > and
> > > > > 'XenDevice' object hierarchy
> > > > >
> > > > > Am 21.11.2018 um 16:11 hat Paul Durrant geschrieben:
> > > > > > This patch adds the basic boilerplate for a 'XenBus' object that
> > > will
> > > > > act
> > > > > > as a parent to 'XenDevice' PV backends.
> > > > > > A new 'XenBridge' object is also added to connect XenBus to the
> > > system
> > > > > bus.
> > > > > >
> > > > > > The XenBus object is instantiated by a new xen_bus_init()
> function
> > > > > called
> > > > > > from the same sites as the legacy xen_be_init() function.
> > > > > >
> > > > > > Subsequent patches will flesh-out the functionality of these
> > > objects.
> > > > > >
> > > > > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > > > >
> > > > > > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > > > > > new file mode 100644
> > > > > > index 0000000000..dede2d914a
> > > > > > --- /dev/null
> > > > > > +++ b/hw/xen/xen-bus.c
> > > > > > @@ -0,0 +1,125 @@
> > > > > > +/*
> > > > > > + * Copyright (c) Citrix Systems Inc.
> > > > > > + * All rights reserved.
> > > > > > + */
> > > > >
> > > > > This doesn't look very compatible with the GPL. In fact it might
> even
> > > > > make it illegal for the QEMU project to distribute this code. :-)
> > > > >
> > > > > Other files you add throughout the series seem to have the same
> > > problem.
> > > > >
> > > >
> > > > I was working on the assumption that a lack of explicit license
> meant
> > > that the overall project license as described in item 2 in LICENSE.
> Did I
> > > misinterpret that text?
> > >
> > > It's "All rights reserved." the problem
> >
> > Oh, I see. I'm happy to remove that.
> 
> That would be better at least. I'm not sure about files that have a
> copyright header, but no license statement. Do such files exist yet in
> the source tree?

Yes, there's quite a few... e.g. (first ones I tripped over) hw/rdma/rdma_backend.c, hw/virtio/vhost-backend.c, ... 

> To be on the safe side, I'd just stick with the
> established practice, which is having a license header in every file.

Ok... if that is established practice. It really wasn't clear.

> 
> By the way, in a later patch you remove the existing license header,
> which is different from the default license (because parts of the source
> file are GPL 2 only). If you can't prove that all such parts (and parts
> derived from them) have been removed, this is also a problem.
> 

What should I do? I am duplicating xen_disk, and then heavily modifying it. Should I just leave the old boilerplate in place?

  Paul

> Kevin

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
  2018-11-28 16:45             ` [Qemu-devel] " Paul Durrant
@ 2018-11-28 16:46                 ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-28 16:46 UTC (permalink / raw)
  To: 'Kevin Wolf'
  Cc: 'Stefano Stabellini', 'qemu-block@nongnu.org',
	'qemu-devel@nongnu.org',
	'xen-devel@lists.xenproject.org',
	'Eduardo Habkost', 'Michael S. Tsirkin',
	'Marcel Apfelbaum',
	Anthony Perard, 'Paolo Bonzini',
	'Richard Henderson'

> -----Original Message-----
> From: Paul Durrant
> Sent: 28 November 2018 16:46
> To: 'Kevin Wolf' <kwolf@redhat.com>
> Cc: 'Stefano Stabellini' <sstabellini@kernel.org>; qemu-block@nongnu.org;
> qemu-devel@nongnu.org; xen-devel@lists.xenproject.org; Eduardo Habkost
> <ehabkost@redhat.com>; Michael S. Tsirkin <mst@redhat.com>; Marcel
> Apfelbaum <marcel.apfelbaum@gmail.com>; Anthony Perard
> <anthony.perard@citrix.com>; Paolo Bonzini <pbonzini@redhat.com>; Richard
> Henderson <rth@twiddle.net>
> Subject: RE: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and
> 'XenDevice' object hierarchy
> 
> > -----Original Message-----
> > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > Sent: 28 November 2018 16:39
> > To: Paul Durrant <Paul.Durrant@citrix.com>
> > Cc: 'Stefano Stabellini' <sstabellini@kernel.org>; qemu-
> block@nongnu.org;
> > qemu-devel@nongnu.org; xen-devel@lists.xenproject.org; Eduardo Habkost
> > <ehabkost@redhat.com>; Michael S. Tsirkin <mst@redhat.com>; Marcel
> > Apfelbaum <marcel.apfelbaum@gmail.com>; Anthony Perard
> > <anthony.perard@citrix.com>; Paolo Bonzini <pbonzini@redhat.com>;
> Richard
> > Henderson <rth@twiddle.net>
> > Subject: Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and
> > 'XenDevice' object hierarchy
> >
> > Am 28.11.2018 um 17:29 hat Paul Durrant geschrieben:
> > > > -----Original Message-----
> > > > From: Stefano Stabellini [mailto:sstabellini@kernel.org]
> > > > Sent: 28 November 2018 16:28
> > > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > > Cc: 'Kevin Wolf' <kwolf@redhat.com>; qemu-block@nongnu.org; qemu-
> > > > devel@nongnu.org; xen-devel@lists.xenproject.org; Stefano Stabellini
> > > > <sstabellini@kernel.org>; Eduardo Habkost <ehabkost@redhat.com>;
> > Michael
> > > > S. Tsirkin <mst@redhat.com>; Marcel Apfelbaum
> > > > <marcel.apfelbaum@gmail.com>; Anthony Perard
> > <anthony.perard@citrix.com>;
> > > > Paolo Bonzini <pbonzini@redhat.com>; Richard Henderson
> > <rth@twiddle.net>
> > > > Subject: RE: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus'
> > and
> > > > 'XenDevice' object hierarchy
> > > >
> > > > On Wed, 28 Nov 2018, Paul Durrant wrote:
> > > > > > -----Original Message-----
> > > > > > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > > > > > Sent: 28 November 2018 16:19
> > > > > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > > > > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > > > > > devel@lists.xenproject.org; Stefano Stabellini
> > > > <sstabellini@kernel.org>;
> > > > > > Eduardo Habkost <ehabkost@redhat.com>; Michael S. Tsirkin
> > > > > > <mst@redhat.com>; Marcel Apfelbaum <marcel.apfelbaum@gmail.com>;
> > > > Anthony
> > > > > > Perard <anthony.perard@citrix.com>; Paolo Bonzini
> > > > <pbonzini@redhat.com>;
> > > > > > Richard Henderson <rth@twiddle.net>
> > > > > > Subject: Re: [Qemu-block] [PATCH 02/18] xen: introduce new
> > 'XenBus'
> > > > and
> > > > > > 'XenDevice' object hierarchy
> > > > > >
> > > > > > Am 21.11.2018 um 16:11 hat Paul Durrant geschrieben:
> > > > > > > This patch adds the basic boilerplate for a 'XenBus' object
> that
> > > > will
> > > > > > act
> > > > > > > as a parent to 'XenDevice' PV backends.
> > > > > > > A new 'XenBridge' object is also added to connect XenBus to
> the
> > > > system
> > > > > > bus.
> > > > > > >
> > > > > > > The XenBus object is instantiated by a new xen_bus_init()
> > function
> > > > > > called
> > > > > > > from the same sites as the legacy xen_be_init() function.
> > > > > > >
> > > > > > > Subsequent patches will flesh-out the functionality of these
> > > > objects.
> > > > > > >
> > > > > > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > > > > >
> > > > > > > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > > > > > > new file mode 100644
> > > > > > > index 0000000000..dede2d914a
> > > > > > > --- /dev/null
> > > > > > > +++ b/hw/xen/xen-bus.c
> > > > > > > @@ -0,0 +1,125 @@
> > > > > > > +/*
> > > > > > > + * Copyright (c) Citrix Systems Inc.
> > > > > > > + * All rights reserved.
> > > > > > > + */
> > > > > >
> > > > > > This doesn't look very compatible with the GPL. In fact it might
> > even
> > > > > > make it illegal for the QEMU project to distribute this code. :-
> )
> > > > > >
> > > > > > Other files you add throughout the series seem to have the same
> > > > problem.
> > > > > >
> > > > >
> > > > > I was working on the assumption that a lack of explicit license
> > meant
> > > > that the overall project license as described in item 2 in LICENSE.
> > Did I
> > > > misinterpret that text?
> > > >
> > > > It's "All rights reserved." the problem
> > >
> > > Oh, I see. I'm happy to remove that.
> >
> > That would be better at least. I'm not sure about files that have a
> > copyright header, but no license statement. Do such files exist yet in
> > the source tree?
> 
> Yes, there's quite a few... e.g. (first ones I tripped over)
> hw/rdma/rdma_backend.c, hw/virtio/vhost-backend.c, ...

Oh... I see they have a license statement but no boilerplate... is that statement enough?

  Paul

> 
> > To be on the safe side, I'd just stick with the
> > established practice, which is having a license header in every file.
> 
> Ok... if that is established practice. It really wasn't clear.
> 
> >
> > By the way, in a later patch you remove the existing license header,
> > which is different from the default license (because parts of the source
> > file are GPL 2 only). If you can't prove that all such parts (and parts
> > derived from them) have been removed, this is also a problem.
> >
> 
> What should I do? I am duplicating xen_disk, and then heavily modifying
> it. Should I just leave the old boilerplate in place?
> 
>   Paul
> 
> > Kevin

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
@ 2018-11-28 16:46                 ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-28 16:46 UTC (permalink / raw)
  To: 'Kevin Wolf'
  Cc: 'Stefano Stabellini', 'Eduardo Habkost',
	'qemu-block@nongnu.org', 'Michael S. Tsirkin',
	'qemu-devel@nongnu.org', 'Marcel Apfelbaum',
	'Paolo Bonzini',
	Anthony Perard, 'xen-devel@lists.xenproject.org',
	'Richard Henderson'

> -----Original Message-----
> From: Paul Durrant
> Sent: 28 November 2018 16:46
> To: 'Kevin Wolf' <kwolf@redhat.com>
> Cc: 'Stefano Stabellini' <sstabellini@kernel.org>; qemu-block@nongnu.org;
> qemu-devel@nongnu.org; xen-devel@lists.xenproject.org; Eduardo Habkost
> <ehabkost@redhat.com>; Michael S. Tsirkin <mst@redhat.com>; Marcel
> Apfelbaum <marcel.apfelbaum@gmail.com>; Anthony Perard
> <anthony.perard@citrix.com>; Paolo Bonzini <pbonzini@redhat.com>; Richard
> Henderson <rth@twiddle.net>
> Subject: RE: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and
> 'XenDevice' object hierarchy
> 
> > -----Original Message-----
> > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > Sent: 28 November 2018 16:39
> > To: Paul Durrant <Paul.Durrant@citrix.com>
> > Cc: 'Stefano Stabellini' <sstabellini@kernel.org>; qemu-
> block@nongnu.org;
> > qemu-devel@nongnu.org; xen-devel@lists.xenproject.org; Eduardo Habkost
> > <ehabkost@redhat.com>; Michael S. Tsirkin <mst@redhat.com>; Marcel
> > Apfelbaum <marcel.apfelbaum@gmail.com>; Anthony Perard
> > <anthony.perard@citrix.com>; Paolo Bonzini <pbonzini@redhat.com>;
> Richard
> > Henderson <rth@twiddle.net>
> > Subject: Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and
> > 'XenDevice' object hierarchy
> >
> > Am 28.11.2018 um 17:29 hat Paul Durrant geschrieben:
> > > > -----Original Message-----
> > > > From: Stefano Stabellini [mailto:sstabellini@kernel.org]
> > > > Sent: 28 November 2018 16:28
> > > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > > Cc: 'Kevin Wolf' <kwolf@redhat.com>; qemu-block@nongnu.org; qemu-
> > > > devel@nongnu.org; xen-devel@lists.xenproject.org; Stefano Stabellini
> > > > <sstabellini@kernel.org>; Eduardo Habkost <ehabkost@redhat.com>;
> > Michael
> > > > S. Tsirkin <mst@redhat.com>; Marcel Apfelbaum
> > > > <marcel.apfelbaum@gmail.com>; Anthony Perard
> > <anthony.perard@citrix.com>;
> > > > Paolo Bonzini <pbonzini@redhat.com>; Richard Henderson
> > <rth@twiddle.net>
> > > > Subject: RE: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus'
> > and
> > > > 'XenDevice' object hierarchy
> > > >
> > > > On Wed, 28 Nov 2018, Paul Durrant wrote:
> > > > > > -----Original Message-----
> > > > > > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > > > > > Sent: 28 November 2018 16:19
> > > > > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > > > > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > > > > > devel@lists.xenproject.org; Stefano Stabellini
> > > > <sstabellini@kernel.org>;
> > > > > > Eduardo Habkost <ehabkost@redhat.com>; Michael S. Tsirkin
> > > > > > <mst@redhat.com>; Marcel Apfelbaum <marcel.apfelbaum@gmail.com>;
> > > > Anthony
> > > > > > Perard <anthony.perard@citrix.com>; Paolo Bonzini
> > > > <pbonzini@redhat.com>;
> > > > > > Richard Henderson <rth@twiddle.net>
> > > > > > Subject: Re: [Qemu-block] [PATCH 02/18] xen: introduce new
> > 'XenBus'
> > > > and
> > > > > > 'XenDevice' object hierarchy
> > > > > >
> > > > > > Am 21.11.2018 um 16:11 hat Paul Durrant geschrieben:
> > > > > > > This patch adds the basic boilerplate for a 'XenBus' object
> that
> > > > will
> > > > > > act
> > > > > > > as a parent to 'XenDevice' PV backends.
> > > > > > > A new 'XenBridge' object is also added to connect XenBus to
> the
> > > > system
> > > > > > bus.
> > > > > > >
> > > > > > > The XenBus object is instantiated by a new xen_bus_init()
> > function
> > > > > > called
> > > > > > > from the same sites as the legacy xen_be_init() function.
> > > > > > >
> > > > > > > Subsequent patches will flesh-out the functionality of these
> > > > objects.
> > > > > > >
> > > > > > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > > > > >
> > > > > > > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > > > > > > new file mode 100644
> > > > > > > index 0000000000..dede2d914a
> > > > > > > --- /dev/null
> > > > > > > +++ b/hw/xen/xen-bus.c
> > > > > > > @@ -0,0 +1,125 @@
> > > > > > > +/*
> > > > > > > + * Copyright (c) Citrix Systems Inc.
> > > > > > > + * All rights reserved.
> > > > > > > + */
> > > > > >
> > > > > > This doesn't look very compatible with the GPL. In fact it might
> > even
> > > > > > make it illegal for the QEMU project to distribute this code. :-
> )
> > > > > >
> > > > > > Other files you add throughout the series seem to have the same
> > > > problem.
> > > > > >
> > > > >
> > > > > I was working on the assumption that a lack of explicit license
> > meant
> > > > that the overall project license as described in item 2 in LICENSE.
> > Did I
> > > > misinterpret that text?
> > > >
> > > > It's "All rights reserved." the problem
> > >
> > > Oh, I see. I'm happy to remove that.
> >
> > That would be better at least. I'm not sure about files that have a
> > copyright header, but no license statement. Do such files exist yet in
> > the source tree?
> 
> Yes, there's quite a few... e.g. (first ones I tripped over)
> hw/rdma/rdma_backend.c, hw/virtio/vhost-backend.c, ...

Oh... I see they have a license statement but no boilerplate... is that statement enough?

  Paul

> 
> > To be on the safe side, I'd just stick with the
> > established practice, which is having a license header in every file.
> 
> Ok... if that is established practice. It really wasn't clear.
> 
> >
> > By the way, in a later patch you remove the existing license header,
> > which is different from the default license (because parts of the source
> > file are GPL 2 only). If you can't prove that all such parts (and parts
> > derived from them) have been removed, this is also a problem.
> >
> 
> What should I do? I am duplicating xen_disk, and then heavily modifying
> it. Should I just leave the old boilerplate in place?
> 
>   Paul
> 
> > Kevin

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
  2018-11-28 16:26       ` Paul Durrant
@ 2018-11-28 17:01         ` Eric Blake
  -1 siblings, 0 replies; 157+ messages in thread
From: Eric Blake @ 2018-11-28 17:01 UTC (permalink / raw)
  To: Paul Durrant, 'Kevin Wolf'
  Cc: Stefano Stabellini, Eduardo Habkost, qemu-block,
	Michael S. Tsirkin, qemu-devel, Paolo Bonzini, Anthony Perard,
	xen-devel, Richard Henderson

On 11/28/18 10:26 AM, Paul Durrant wrote:

>>> +++ b/hw/xen/xen-bus.c
>>> @@ -0,0 +1,125 @@
>>> +/*
>>> + * Copyright (c) Citrix Systems Inc.
>>> + * All rights reserved.
>>> + */
>>
>> This doesn't look very compatible with the GPL. In fact it might even
>> make it illegal for the QEMU project to distribute this code. :-)
>>
>> Other files you add throughout the series seem to have the same problem.
>>
> 
> I was working on the assumption that a lack of explicit license meant that the overall project license as described in item 2 in LICENSE. Did I misinterpret that text?

No, but you missed the fact that "All rights reserved" is an explicit 
license (or rather, an explicit anti-license that states you are not 
granting rights that the GPL would normally grant), and an implicit 
license does not apply when an explicit (anti-)license is present.

What's more, relying on implicit licenses is prone to misinterpretation, 
so even though the overall project documentation tries to cover what 
will happen, it's much nicer if you DO use an explicit license mention 
in your file so that we don't HAVE to rely on the implicit license.

Yes, the phrase "All rights reserved" exists in several existing files:

$ git grep -il 'all rights reserved' |wc
     138     138    3557

but we should be striving to clean those up, not adding to the mess.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
@ 2018-11-28 17:01         ` Eric Blake
  0 siblings, 0 replies; 157+ messages in thread
From: Eric Blake @ 2018-11-28 17:01 UTC (permalink / raw)
  To: Paul Durrant, 'Kevin Wolf'
  Cc: Stefano Stabellini, Eduardo Habkost, qemu-block,
	Michael S. Tsirkin, qemu-devel, xen-devel, Anthony Perard,
	Paolo Bonzini, Richard Henderson

On 11/28/18 10:26 AM, Paul Durrant wrote:

>>> +++ b/hw/xen/xen-bus.c
>>> @@ -0,0 +1,125 @@
>>> +/*
>>> + * Copyright (c) Citrix Systems Inc.
>>> + * All rights reserved.
>>> + */
>>
>> This doesn't look very compatible with the GPL. In fact it might even
>> make it illegal for the QEMU project to distribute this code. :-)
>>
>> Other files you add throughout the series seem to have the same problem.
>>
> 
> I was working on the assumption that a lack of explicit license meant that the overall project license as described in item 2 in LICENSE. Did I misinterpret that text?

No, but you missed the fact that "All rights reserved" is an explicit 
license (or rather, an explicit anti-license that states you are not 
granting rights that the GPL would normally grant), and an implicit 
license does not apply when an explicit (anti-)license is present.

What's more, relying on implicit licenses is prone to misinterpretation, 
so even though the overall project documentation tries to cover what 
will happen, it's much nicer if you DO use an explicit license mention 
in your file so that we don't HAVE to rely on the implicit license.

Yes, the phrase "All rights reserved" exists in several existing files:

$ git grep -il 'all rights reserved' |wc
     138     138    3557

but we should be striving to clean those up, not adding to the mess.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
  2018-11-28 17:01         ` Eric Blake
@ 2018-11-28 17:04           ` Paul Durrant
  -1 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-28 17:04 UTC (permalink / raw)
  To: 'Eric Blake', 'Kevin Wolf'
  Cc: Stefano Stabellini, Eduardo Habkost, qemu-block,
	Michael S. Tsirkin, qemu-devel, Paolo Bonzini, Anthony Perard,
	xen-devel, Richard Henderson

> -----Original Message-----
> From: Eric Blake [mailto:eblake@redhat.com]
> Sent: 28 November 2018 17:01
> To: Paul Durrant <Paul.Durrant@citrix.com>; 'Kevin Wolf'
> <kwolf@redhat.com>
> Cc: Stefano Stabellini <sstabellini@kernel.org>; Eduardo Habkost
> <ehabkost@redhat.com>; qemu-block@nongnu.org; Michael S. Tsirkin
> <mst@redhat.com>; qemu-devel@nongnu.org; Paolo Bonzini
> <pbonzini@redhat.com>; Anthony Perard <anthony.perard@citrix.com>; xen-
> devel@lists.xenproject.org; Richard Henderson <rth@twiddle.net>
> Subject: Re: [Qemu-devel] [Qemu-block] [PATCH 02/18] xen: introduce new
> 'XenBus' and 'XenDevice' object hierarchy
> 
> On 11/28/18 10:26 AM, Paul Durrant wrote:
> 
> >>> +++ b/hw/xen/xen-bus.c
> >>> @@ -0,0 +1,125 @@
> >>> +/*
> >>> + * Copyright (c) Citrix Systems Inc.
> >>> + * All rights reserved.
> >>> + */
> >>
> >> This doesn't look very compatible with the GPL. In fact it might even
> >> make it illegal for the QEMU project to distribute this code. :-)
> >>
> >> Other files you add throughout the series seem to have the same
> problem.
> >>
> >
> > I was working on the assumption that a lack of explicit license meant
> that the overall project license as described in item 2 in LICENSE. Did I
> misinterpret that text?
> 
> No, but you missed the fact that "All rights reserved" is an explicit
> license (or rather, an explicit anti-license that states you are not
> granting rights that the GPL would normally grant), and an implicit
> license does not apply when an explicit (anti-)license is present.
> 
> What's more, relying on implicit licenses is prone to misinterpretation,
> so even though the overall project documentation tries to cover what
> will happen, it's much nicer if you DO use an explicit license mention
> in your file so that we don't HAVE to rely on the implicit license.
> 
> Yes, the phrase "All rights reserved" exists in several existing files:
> 
> $ git grep -il 'all rights reserved' |wc
>      138     138    3557
> 
> but we should be striving to clean those up, not adding to the mess.

Ok. I'll send a v2 with the "All rights reserved" removed from and a GPL statement added to all the new files.

  Paul

> 
> --
> Eric Blake, Principal Software Engineer
> Red Hat, Inc.           +1-919-301-3266
> Virtualization:  qemu.org | libvirt.org

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
@ 2018-11-28 17:04           ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-28 17:04 UTC (permalink / raw)
  To: 'Eric Blake', 'Kevin Wolf'
  Cc: Stefano Stabellini, Eduardo Habkost, qemu-block,
	Michael S. Tsirkin, qemu-devel, xen-devel, Anthony Perard,
	Paolo Bonzini, Richard Henderson

> -----Original Message-----
> From: Eric Blake [mailto:eblake@redhat.com]
> Sent: 28 November 2018 17:01
> To: Paul Durrant <Paul.Durrant@citrix.com>; 'Kevin Wolf'
> <kwolf@redhat.com>
> Cc: Stefano Stabellini <sstabellini@kernel.org>; Eduardo Habkost
> <ehabkost@redhat.com>; qemu-block@nongnu.org; Michael S. Tsirkin
> <mst@redhat.com>; qemu-devel@nongnu.org; Paolo Bonzini
> <pbonzini@redhat.com>; Anthony Perard <anthony.perard@citrix.com>; xen-
> devel@lists.xenproject.org; Richard Henderson <rth@twiddle.net>
> Subject: Re: [Qemu-devel] [Qemu-block] [PATCH 02/18] xen: introduce new
> 'XenBus' and 'XenDevice' object hierarchy
> 
> On 11/28/18 10:26 AM, Paul Durrant wrote:
> 
> >>> +++ b/hw/xen/xen-bus.c
> >>> @@ -0,0 +1,125 @@
> >>> +/*
> >>> + * Copyright (c) Citrix Systems Inc.
> >>> + * All rights reserved.
> >>> + */
> >>
> >> This doesn't look very compatible with the GPL. In fact it might even
> >> make it illegal for the QEMU project to distribute this code. :-)
> >>
> >> Other files you add throughout the series seem to have the same
> problem.
> >>
> >
> > I was working on the assumption that a lack of explicit license meant
> that the overall project license as described in item 2 in LICENSE. Did I
> misinterpret that text?
> 
> No, but you missed the fact that "All rights reserved" is an explicit
> license (or rather, an explicit anti-license that states you are not
> granting rights that the GPL would normally grant), and an implicit
> license does not apply when an explicit (anti-)license is present.
> 
> What's more, relying on implicit licenses is prone to misinterpretation,
> so even though the overall project documentation tries to cover what
> will happen, it's much nicer if you DO use an explicit license mention
> in your file so that we don't HAVE to rely on the implicit license.
> 
> Yes, the phrase "All rights reserved" exists in several existing files:
> 
> $ git grep -il 'all rights reserved' |wc
>      138     138    3557
> 
> but we should be striving to clean those up, not adding to the mess.

Ok. I'll send a v2 with the "All rights reserved" removed from and a GPL statement added to all the new files.

  Paul

> 
> --
> Eric Blake, Principal Software Engineer
> Red Hat, Inc.           +1-919-301-3266
> Virtualization:  qemu.org | libvirt.org
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
  2018-11-21 15:11 ` [Qemu-devel] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy Paul Durrant
@ 2018-11-28 17:10     ` Anthony PERARD
  2018-11-28 16:19   ` [Qemu-devel] " Kevin Wolf
  2018-11-28 17:10     ` Anthony PERARD
  2 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-11-28 17:10 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Michael S. Tsirkin, Marcel Apfelbaum, Paolo Bonzini,
	Richard Henderson, Eduardo Habkost

On Wed, Nov 21, 2018 at 03:11:55PM +0000, Paul Durrant wrote:
> diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> new file mode 100644
> index 0000000000..dede2d914a
> --- /dev/null
> +++ b/hw/xen/xen-bus.c
> @@ -0,0 +1,125 @@
> +/*
> + * Copyright (c) Citrix Systems Inc.
> + * All rights reserved.

You probably should include:
  This work is licensed under the terms of the GNU GPL, version 2 or later.
  See the COPYING file in the top-level directory.

As this seems to be a boilerplate used in recent new files, there are
other similair boilerplates.

Also, I think the copyright line should include a year.

> +void xen_bus_init(void)
> +{
> +    DeviceState *dev = qdev_create(NULL, TYPE_XEN_BRIDGE);
> +
> +    qbus_create(TYPE_XEN_BUS, dev, NULL);
> +    qdev_init_nofail(dev);

Will we need a hotplug handler for this bus, like it is done with
TYPE_XENSYSBUS?


The rest looks good,
Thanks,

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
@ 2018-11-28 17:10     ` Anthony PERARD
  0 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-11-28 17:10 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Stefano Stabellini, Eduardo Habkost, qemu-block,
	Michael S. Tsirkin, qemu-devel, Marcel Apfelbaum, Paolo Bonzini,
	xen-devel, Richard Henderson

On Wed, Nov 21, 2018 at 03:11:55PM +0000, Paul Durrant wrote:
> diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> new file mode 100644
> index 0000000000..dede2d914a
> --- /dev/null
> +++ b/hw/xen/xen-bus.c
> @@ -0,0 +1,125 @@
> +/*
> + * Copyright (c) Citrix Systems Inc.
> + * All rights reserved.

You probably should include:
  This work is licensed under the terms of the GNU GPL, version 2 or later.
  See the COPYING file in the top-level directory.

As this seems to be a boilerplate used in recent new files, there are
other similair boilerplates.

Also, I think the copyright line should include a year.

> +void xen_bus_init(void)
> +{
> +    DeviceState *dev = qdev_create(NULL, TYPE_XEN_BRIDGE);
> +
> +    qbus_create(TYPE_XEN_BUS, dev, NULL);
> +    qdev_init_nofail(dev);

Will we need a hotplug handler for this bus, like it is done with
TYPE_XENSYSBUS?


The rest looks good,
Thanks,

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
  2018-11-28 17:10     ` Anthony PERARD
@ 2018-11-28 17:17       ` Paul Durrant
  -1 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-28 17:17 UTC (permalink / raw)
  To: Anthony Perard
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Michael S. Tsirkin, Marcel Apfelbaum, Paolo Bonzini,
	Richard Henderson, Eduardo Habkost

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 28 November 2018 17:10
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> Michael S. Tsirkin <mst@redhat.com>; Marcel Apfelbaum
> <marcel.apfelbaum@gmail.com>; Paolo Bonzini <pbonzini@redhat.com>; Richard
> Henderson <rth@twiddle.net>; Eduardo Habkost <ehabkost@redhat.com>
> Subject: Re: [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice'
> object hierarchy
> 
> On Wed, Nov 21, 2018 at 03:11:55PM +0000, Paul Durrant wrote:
> > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > new file mode 100644
> > index 0000000000..dede2d914a
> > --- /dev/null
> > +++ b/hw/xen/xen-bus.c
> > @@ -0,0 +1,125 @@
> > +/*
> > + * Copyright (c) Citrix Systems Inc.
> > + * All rights reserved.
> 
> You probably should include:
>   This work is licensed under the terms of the GNU GPL, version 2 or
> later.
>   See the COPYING file in the top-level directory.
> 
> As this seems to be a boilerplate used in recent new files, there are
> other similair boilerplates.
> 
> Also, I think the copyright line should include a year.

Ok.

> 
> > +void xen_bus_init(void)
> > +{
> > +    DeviceState *dev = qdev_create(NULL, TYPE_XEN_BRIDGE);
> > +
> > +    qbus_create(TYPE_XEN_BUS, dev, NULL);
> > +    qdev_init_nofail(dev);
> 
> Will we need a hotplug handler for this bus, like it is done with
> TYPE_XENSYSBUS?

I didn't seem to need one even doing 'xl block-attach' after the VM had booted. I'm really not sure what that does.

  Paul

> 
> 
> The rest looks good,
> Thanks,
> 
> --
> Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
@ 2018-11-28 17:17       ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-28 17:17 UTC (permalink / raw)
  To: Anthony Perard
  Cc: Stefano Stabellini, Eduardo Habkost, qemu-block,
	Michael S. Tsirkin, qemu-devel, Marcel Apfelbaum, Paolo Bonzini,
	xen-devel, Richard Henderson

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 28 November 2018 17:10
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> Michael S. Tsirkin <mst@redhat.com>; Marcel Apfelbaum
> <marcel.apfelbaum@gmail.com>; Paolo Bonzini <pbonzini@redhat.com>; Richard
> Henderson <rth@twiddle.net>; Eduardo Habkost <ehabkost@redhat.com>
> Subject: Re: [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice'
> object hierarchy
> 
> On Wed, Nov 21, 2018 at 03:11:55PM +0000, Paul Durrant wrote:
> > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > new file mode 100644
> > index 0000000000..dede2d914a
> > --- /dev/null
> > +++ b/hw/xen/xen-bus.c
> > @@ -0,0 +1,125 @@
> > +/*
> > + * Copyright (c) Citrix Systems Inc.
> > + * All rights reserved.
> 
> You probably should include:
>   This work is licensed under the terms of the GNU GPL, version 2 or
> later.
>   See the COPYING file in the top-level directory.
> 
> As this seems to be a boilerplate used in recent new files, there are
> other similair boilerplates.
> 
> Also, I think the copyright line should include a year.

Ok.

> 
> > +void xen_bus_init(void)
> > +{
> > +    DeviceState *dev = qdev_create(NULL, TYPE_XEN_BRIDGE);
> > +
> > +    qbus_create(TYPE_XEN_BUS, dev, NULL);
> > +    qdev_init_nofail(dev);
> 
> Will we need a hotplug handler for this bus, like it is done with
> TYPE_XENSYSBUS?

I didn't seem to need one even doing 'xl block-attach' after the VM had booted. I'm really not sure what that does.

  Paul

> 
> 
> The rest looks good,
> Thanks,
> 
> --
> Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
  2018-11-28 17:17       ` Paul Durrant
@ 2018-11-28 17:32         ` Anthony PERARD
  -1 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-11-28 17:32 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Michael S. Tsirkin, Marcel Apfelbaum, Paolo Bonzini,
	Richard Henderson, Eduardo Habkost

On Wed, Nov 28, 2018 at 05:17:10PM +0000, Paul Durrant wrote:
> > Will we need a hotplug handler for this bus, like it is done with
> > TYPE_XENSYSBUS?
> 
> I didn't seem to need one even doing 'xl block-attach' after the VM had booted. I'm really not sure what that does.

Indeed, that works fine, and I think I've tested block-detach as well.
Maybe we will need something if we initiate attach of a block device via
QMP instead of xenstore, but we can fix that later.

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
@ 2018-11-28 17:32         ` Anthony PERARD
  0 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-11-28 17:32 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Stefano Stabellini, Eduardo Habkost, qemu-block,
	Michael S. Tsirkin, qemu-devel, Marcel Apfelbaum, Paolo Bonzini,
	xen-devel, Richard Henderson

On Wed, Nov 28, 2018 at 05:17:10PM +0000, Paul Durrant wrote:
> > Will we need a hotplug handler for this bus, like it is done with
> > TYPE_XENSYSBUS?
> 
> I didn't seem to need one even doing 'xl block-attach' after the VM had booted. I'm really not sure what that does.

Indeed, that works fine, and I think I've tested block-detach as well.
Maybe we will need something if we initiate attach of a block device via
QMP instead of xenstore, but we can fix that later.

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 14/18] xen: add implementations of xen-qdisk connect and disconnect functions...
  2018-11-28 16:40       ` Paul Durrant
  (?)
@ 2018-11-29  9:00       ` Kevin Wolf
  2018-11-29  9:33         ` Paul Durrant
  2018-11-29  9:33         ` Paul Durrant
  -1 siblings, 2 replies; 157+ messages in thread
From: Kevin Wolf @ 2018-11-29  9:00 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Anthony Perard, Max Reitz

Am 28.11.2018 um 17:40 hat Paul Durrant geschrieben:
> > -----Original Message-----
> > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > Sent: 28 November 2018 16:35
> > To: Paul Durrant <Paul.Durrant@citrix.com>
> > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> > Anthony Perard <anthony.perard@citrix.com>; Max Reitz <mreitz@redhat.com>
> > Subject: Re: [PATCH 14/18] xen: add implementations of xen-qdisk connect
> > and disconnect functions...
> > 
> > Am 21.11.2018 um 16:12 hat Paul Durrant geschrieben:
> > > ...and wire in the dataplane.
> > >
> > > This patch adds the remaining code to make the xen-qdisk XenDevice
> > > functional. The parameters that a block frontend expects to find are
> > > populated in the backend xenstore area, and the 'ring-ref' and
> > > 'event-channel' values specified in the frontend xenstore area are
> > > mapped/bound and used to set up the dataplane.
> > >
> > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > > ---
> > > Cc: Stefano Stabellini <sstabellini@kernel.org>
> > > Cc: Anthony Perard <anthony.perard@citrix.com>
> > > Cc: Kevin Wolf <kwolf@redhat.com>
> > > Cc: Max Reitz <mreitz@redhat.com>
> > > ---
> > >  hw/block/xen-qdisk.c       | 140
> > +++++++++++++++++++++++++++++++++++++++++++++
> > >  hw/xen/xen-bus.c           |  12 ++--
> > >  include/hw/xen/xen-bus.h   |   8 +++
> > >  include/hw/xen/xen-qdisk.h |  12 ++++
> > >  4 files changed, 166 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> > > index 35f7b70480..8c88393832 100644
> > > --- a/hw/block/xen-qdisk.c
> > > +++ b/hw/block/xen-qdisk.c
> > > @@ -9,6 +9,10 @@
> > >  #include "qapi/visitor.h"
> > >  #include "hw/hw.h"
> > >  #include "hw/xen/xen-qdisk.h"
> > > +#include "sysemu/blockdev.h"
> > > +#include "sysemu/block-backend.h"
> > > +#include "sysemu/iothread.h"
> > > +#include "dataplane/xen-qdisk.h"
> > >  #include "trace.h"
> > >
> > >  static char *xen_qdisk_get_name(XenDevice *xendev, Error **errp)
> > > @@ -23,6 +27,11 @@ static void xen_qdisk_realize(XenDevice *xendev,
> > Error **errp)
> > >  {
> > >      XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
> > >      XenQdiskVdev *vdev = &qdiskdev->vdev;
> > > +    BlockConf *conf = &qdiskdev->conf;
> > > +    DriveInfo *dinfo;
> > > +    bool is_cdrom;
> > > +    unsigned int info;
> > > +    int64_t size;
> > >
> > >      if (!vdev->valid) {
> > >          error_setg(errp, "vdev property not set");
> > > @@ -30,13 +39,134 @@ static void xen_qdisk_realize(XenDevice *xendev,
> > Error **errp)
> > >      }
> > >
> > >      trace_xen_qdisk_realize(vdev->disk, vdev->partition);
> > > +
> > > +    if (!conf->blk) {
> > > +        error_setg(errp, "drive property not set");
> > > +        return;
> > > +    }
> > > +
> > > +    if (!blk_is_inserted(conf->blk)) {
> > > +        error_setg(errp, "device needs media, but drive is empty");
> > > +        return;
> > > +    }
> > 
> > Hm, the code below suggests that you support CD-ROMs. Don't you want to
> > support media change as well then? Which would mean that you need to
> > support empty drives.
> 
> Yes, that's a good point. I should get rid of that check.

Or rather apply it only to hard disks. And for empty CDs, you'll
probably need to create an empty BlockBackend (the !conf->blk case).
Just check the IDE and/or SCSI code for comparison.

> > 
> > > +    if (!blkconf_apply_backend_options(conf, blk_is_read_only(conf-
> > >blk),
> > > +                                       false, errp)) {
> > > +        return;
> > > +    }
> > > +
> > > +    if (!blkconf_geometry(conf, NULL, 65535, 255, 255, errp)) {
> > > +        return;
> > > +    }
> > > +
> > > +    dinfo = blk_legacy_dinfo(conf->blk);
> > > +    is_cdrom = (dinfo && dinfo->media_cd);
> > 
> > It's called legacy for a reason. Don't use this in new devices.
> > 
> > The proper way is to have two different devices for hard disks and CDs
> > (like scsi-hd and scsi-cd).
> 
> ...or presumably I could have a property? The legacy init code could
> then set it based on the drive info.

Technically yes, but why would that be a good way to model things? I
mean, it's true that xen-qdisk is not real hardware, but I've never seen
any hardware that has a switch to decide whether it should behave as a
CD drive or a hard disk.

Both have very different characteristics (read-only with removable
media, or a single read-write disk), and the existing implementations
use two separate devices. So even if you're not convinced that users
will consider them different concepts (I am; and if they weren't
different concepts, you wouldn't need an is_cdrom variable), consistency
is still a good thing.

Kevin

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 14/18] xen: add implementations of xen-qdisk connect and disconnect functions...
  2018-11-28 16:40       ` Paul Durrant
  (?)
  (?)
@ 2018-11-29  9:00       ` Kevin Wolf
  -1 siblings, 0 replies; 157+ messages in thread
From: Kevin Wolf @ 2018-11-29  9:00 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Stefano Stabellini, qemu-block, qemu-devel, Max Reitz,
	Anthony Perard, xen-devel

Am 28.11.2018 um 17:40 hat Paul Durrant geschrieben:
> > -----Original Message-----
> > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > Sent: 28 November 2018 16:35
> > To: Paul Durrant <Paul.Durrant@citrix.com>
> > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> > Anthony Perard <anthony.perard@citrix.com>; Max Reitz <mreitz@redhat.com>
> > Subject: Re: [PATCH 14/18] xen: add implementations of xen-qdisk connect
> > and disconnect functions...
> > 
> > Am 21.11.2018 um 16:12 hat Paul Durrant geschrieben:
> > > ...and wire in the dataplane.
> > >
> > > This patch adds the remaining code to make the xen-qdisk XenDevice
> > > functional. The parameters that a block frontend expects to find are
> > > populated in the backend xenstore area, and the 'ring-ref' and
> > > 'event-channel' values specified in the frontend xenstore area are
> > > mapped/bound and used to set up the dataplane.
> > >
> > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > > ---
> > > Cc: Stefano Stabellini <sstabellini@kernel.org>
> > > Cc: Anthony Perard <anthony.perard@citrix.com>
> > > Cc: Kevin Wolf <kwolf@redhat.com>
> > > Cc: Max Reitz <mreitz@redhat.com>
> > > ---
> > >  hw/block/xen-qdisk.c       | 140
> > +++++++++++++++++++++++++++++++++++++++++++++
> > >  hw/xen/xen-bus.c           |  12 ++--
> > >  include/hw/xen/xen-bus.h   |   8 +++
> > >  include/hw/xen/xen-qdisk.h |  12 ++++
> > >  4 files changed, 166 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> > > index 35f7b70480..8c88393832 100644
> > > --- a/hw/block/xen-qdisk.c
> > > +++ b/hw/block/xen-qdisk.c
> > > @@ -9,6 +9,10 @@
> > >  #include "qapi/visitor.h"
> > >  #include "hw/hw.h"
> > >  #include "hw/xen/xen-qdisk.h"
> > > +#include "sysemu/blockdev.h"
> > > +#include "sysemu/block-backend.h"
> > > +#include "sysemu/iothread.h"
> > > +#include "dataplane/xen-qdisk.h"
> > >  #include "trace.h"
> > >
> > >  static char *xen_qdisk_get_name(XenDevice *xendev, Error **errp)
> > > @@ -23,6 +27,11 @@ static void xen_qdisk_realize(XenDevice *xendev,
> > Error **errp)
> > >  {
> > >      XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
> > >      XenQdiskVdev *vdev = &qdiskdev->vdev;
> > > +    BlockConf *conf = &qdiskdev->conf;
> > > +    DriveInfo *dinfo;
> > > +    bool is_cdrom;
> > > +    unsigned int info;
> > > +    int64_t size;
> > >
> > >      if (!vdev->valid) {
> > >          error_setg(errp, "vdev property not set");
> > > @@ -30,13 +39,134 @@ static void xen_qdisk_realize(XenDevice *xendev,
> > Error **errp)
> > >      }
> > >
> > >      trace_xen_qdisk_realize(vdev->disk, vdev->partition);
> > > +
> > > +    if (!conf->blk) {
> > > +        error_setg(errp, "drive property not set");
> > > +        return;
> > > +    }
> > > +
> > > +    if (!blk_is_inserted(conf->blk)) {
> > > +        error_setg(errp, "device needs media, but drive is empty");
> > > +        return;
> > > +    }
> > 
> > Hm, the code below suggests that you support CD-ROMs. Don't you want to
> > support media change as well then? Which would mean that you need to
> > support empty drives.
> 
> Yes, that's a good point. I should get rid of that check.

Or rather apply it only to hard disks. And for empty CDs, you'll
probably need to create an empty BlockBackend (the !conf->blk case).
Just check the IDE and/or SCSI code for comparison.

> > 
> > > +    if (!blkconf_apply_backend_options(conf, blk_is_read_only(conf-
> > >blk),
> > > +                                       false, errp)) {
> > > +        return;
> > > +    }
> > > +
> > > +    if (!blkconf_geometry(conf, NULL, 65535, 255, 255, errp)) {
> > > +        return;
> > > +    }
> > > +
> > > +    dinfo = blk_legacy_dinfo(conf->blk);
> > > +    is_cdrom = (dinfo && dinfo->media_cd);
> > 
> > It's called legacy for a reason. Don't use this in new devices.
> > 
> > The proper way is to have two different devices for hard disks and CDs
> > (like scsi-hd and scsi-cd).
> 
> ...or presumably I could have a property? The legacy init code could
> then set it based on the drive info.

Technically yes, but why would that be a good way to model things? I
mean, it's true that xen-qdisk is not real hardware, but I've never seen
any hardware that has a switch to decide whether it should behave as a
CD drive or a hard disk.

Both have very different characteristics (read-only with removable
media, or a single read-write disk), and the existing implementations
use two separate devices. So even if you're not convinced that users
will consider them different concepts (I am; and if they weren't
different concepts, you wouldn't need an is_cdrom variable), consistency
is still a good thing.

Kevin

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
  2018-11-28 16:46                 ` Paul Durrant
@ 2018-11-29  9:04                   ` Kevin Wolf
  -1 siblings, 0 replies; 157+ messages in thread
From: Kevin Wolf @ 2018-11-29  9:04 UTC (permalink / raw)
  To: Paul Durrant
  Cc: 'Stefano Stabellini', 'qemu-block@nongnu.org',
	'qemu-devel@nongnu.org',
	'xen-devel@lists.xenproject.org',
	'Eduardo Habkost', 'Michael S. Tsirkin',
	'Marcel Apfelbaum',
	Anthony Perard, 'Paolo Bonzini',
	'Richard Henderson'

Am 28.11.2018 um 17:46 hat Paul Durrant geschrieben:
> > -----Original Message-----
> > From: Paul Durrant
> > Sent: 28 November 2018 16:46
> > To: 'Kevin Wolf' <kwolf@redhat.com>
> > Cc: 'Stefano Stabellini' <sstabellini@kernel.org>; qemu-block@nongnu.org;
> > qemu-devel@nongnu.org; xen-devel@lists.xenproject.org; Eduardo Habkost
> > <ehabkost@redhat.com>; Michael S. Tsirkin <mst@redhat.com>; Marcel
> > Apfelbaum <marcel.apfelbaum@gmail.com>; Anthony Perard
> > <anthony.perard@citrix.com>; Paolo Bonzini <pbonzini@redhat.com>; Richard
> > Henderson <rth@twiddle.net>
> > Subject: RE: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and
> > 'XenDevice' object hierarchy
> > 
> > > -----Original Message-----
> > > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > > Sent: 28 November 2018 16:39
> > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > Cc: 'Stefano Stabellini' <sstabellini@kernel.org>; qemu-
> > block@nongnu.org;
> > > qemu-devel@nongnu.org; xen-devel@lists.xenproject.org; Eduardo Habkost
> > > <ehabkost@redhat.com>; Michael S. Tsirkin <mst@redhat.com>; Marcel
> > > Apfelbaum <marcel.apfelbaum@gmail.com>; Anthony Perard
> > > <anthony.perard@citrix.com>; Paolo Bonzini <pbonzini@redhat.com>;
> > Richard
> > > Henderson <rth@twiddle.net>
> > > Subject: Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and
> > > 'XenDevice' object hierarchy
> > >
> > > Am 28.11.2018 um 17:29 hat Paul Durrant geschrieben:
> > > > > -----Original Message-----
> > > > > From: Stefano Stabellini [mailto:sstabellini@kernel.org]
> > > > > Sent: 28 November 2018 16:28
> > > > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > > > Cc: 'Kevin Wolf' <kwolf@redhat.com>; qemu-block@nongnu.org; qemu-
> > > > > devel@nongnu.org; xen-devel@lists.xenproject.org; Stefano Stabellini
> > > > > <sstabellini@kernel.org>; Eduardo Habkost <ehabkost@redhat.com>;
> > > Michael
> > > > > S. Tsirkin <mst@redhat.com>; Marcel Apfelbaum
> > > > > <marcel.apfelbaum@gmail.com>; Anthony Perard
> > > <anthony.perard@citrix.com>;
> > > > > Paolo Bonzini <pbonzini@redhat.com>; Richard Henderson
> > > <rth@twiddle.net>
> > > > > Subject: RE: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus'
> > > and
> > > > > 'XenDevice' object hierarchy
> > > > >
> > > > > On Wed, 28 Nov 2018, Paul Durrant wrote:
> > > > > > > -----Original Message-----
> > > > > > > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > > > > > > Sent: 28 November 2018 16:19
> > > > > > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > > > > > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > > > > > > devel@lists.xenproject.org; Stefano Stabellini
> > > > > <sstabellini@kernel.org>;
> > > > > > > Eduardo Habkost <ehabkost@redhat.com>; Michael S. Tsirkin
> > > > > > > <mst@redhat.com>; Marcel Apfelbaum <marcel.apfelbaum@gmail.com>;
> > > > > Anthony
> > > > > > > Perard <anthony.perard@citrix.com>; Paolo Bonzini
> > > > > <pbonzini@redhat.com>;
> > > > > > > Richard Henderson <rth@twiddle.net>
> > > > > > > Subject: Re: [Qemu-block] [PATCH 02/18] xen: introduce new
> > > 'XenBus'
> > > > > and
> > > > > > > 'XenDevice' object hierarchy
> > > > > > >
> > > > > > > Am 21.11.2018 um 16:11 hat Paul Durrant geschrieben:
> > > > > > > > This patch adds the basic boilerplate for a 'XenBus' object
> > that
> > > > > will
> > > > > > > act
> > > > > > > > as a parent to 'XenDevice' PV backends.
> > > > > > > > A new 'XenBridge' object is also added to connect XenBus to
> > the
> > > > > system
> > > > > > > bus.
> > > > > > > >
> > > > > > > > The XenBus object is instantiated by a new xen_bus_init()
> > > function
> > > > > > > called
> > > > > > > > from the same sites as the legacy xen_be_init() function.
> > > > > > > >
> > > > > > > > Subsequent patches will flesh-out the functionality of these
> > > > > objects.
> > > > > > > >
> > > > > > > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > > > > > >
> > > > > > > > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > > > > > > > new file mode 100644
> > > > > > > > index 0000000000..dede2d914a
> > > > > > > > --- /dev/null
> > > > > > > > +++ b/hw/xen/xen-bus.c
> > > > > > > > @@ -0,0 +1,125 @@
> > > > > > > > +/*
> > > > > > > > + * Copyright (c) Citrix Systems Inc.
> > > > > > > > + * All rights reserved.
> > > > > > > > + */
> > > > > > >
> > > > > > > This doesn't look very compatible with the GPL. In fact it might
> > > even
> > > > > > > make it illegal for the QEMU project to distribute this code. :-
> > )
> > > > > > >
> > > > > > > Other files you add throughout the series seem to have the same
> > > > > problem.
> > > > > > >
> > > > > >
> > > > > > I was working on the assumption that a lack of explicit license
> > > meant
> > > > > that the overall project license as described in item 2 in LICENSE.
> > > Did I
> > > > > misinterpret that text?
> > > > >
> > > > > It's "All rights reserved." the problem
> > > >
> > > > Oh, I see. I'm happy to remove that.
> > >
> > > That would be better at least. I'm not sure about files that have a
> > > copyright header, but no license statement. Do such files exist yet in
> > > the source tree?
> > 
> > Yes, there's quite a few... e.g. (first ones I tripped over)
> > hw/rdma/rdma_backend.c, hw/virtio/vhost-backend.c, ...
> 
> Oh... I see they have a license statement but no boilerplate... is
> that statement enough?

Yes, this is good enough.

> > > To be on the safe side, I'd just stick with the
> > > established practice, which is having a license header in every file.
> > 
> > Ok... if that is established practice. It really wasn't clear.
> > 
> > >
> > > By the way, in a later patch you remove the existing license header,
> > > which is different from the default license (because parts of the source
> > > file are GPL 2 only). If you can't prove that all such parts (and parts
> > > derived from them) have been removed, this is also a problem.
> > >
> > 
> > What should I do? I am duplicating xen_disk, and then heavily modifying
> > it. Should I just leave the old boilerplate in place?

Yes. Feel free to add your own copyright line right below Gerd's, but
leave the old stuff intact.

Kevin

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
@ 2018-11-29  9:04                   ` Kevin Wolf
  0 siblings, 0 replies; 157+ messages in thread
From: Kevin Wolf @ 2018-11-29  9:04 UTC (permalink / raw)
  To: Paul Durrant
  Cc: 'Stefano Stabellini', 'Eduardo Habkost',
	'qemu-block@nongnu.org', 'Michael S. Tsirkin',
	'qemu-devel@nongnu.org', 'Marcel Apfelbaum',
	'Paolo Bonzini',
	Anthony Perard, 'xen-devel@lists.xenproject.org',
	'Richard Henderson'

Am 28.11.2018 um 17:46 hat Paul Durrant geschrieben:
> > -----Original Message-----
> > From: Paul Durrant
> > Sent: 28 November 2018 16:46
> > To: 'Kevin Wolf' <kwolf@redhat.com>
> > Cc: 'Stefano Stabellini' <sstabellini@kernel.org>; qemu-block@nongnu.org;
> > qemu-devel@nongnu.org; xen-devel@lists.xenproject.org; Eduardo Habkost
> > <ehabkost@redhat.com>; Michael S. Tsirkin <mst@redhat.com>; Marcel
> > Apfelbaum <marcel.apfelbaum@gmail.com>; Anthony Perard
> > <anthony.perard@citrix.com>; Paolo Bonzini <pbonzini@redhat.com>; Richard
> > Henderson <rth@twiddle.net>
> > Subject: RE: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and
> > 'XenDevice' object hierarchy
> > 
> > > -----Original Message-----
> > > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > > Sent: 28 November 2018 16:39
> > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > Cc: 'Stefano Stabellini' <sstabellini@kernel.org>; qemu-
> > block@nongnu.org;
> > > qemu-devel@nongnu.org; xen-devel@lists.xenproject.org; Eduardo Habkost
> > > <ehabkost@redhat.com>; Michael S. Tsirkin <mst@redhat.com>; Marcel
> > > Apfelbaum <marcel.apfelbaum@gmail.com>; Anthony Perard
> > > <anthony.perard@citrix.com>; Paolo Bonzini <pbonzini@redhat.com>;
> > Richard
> > > Henderson <rth@twiddle.net>
> > > Subject: Re: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and
> > > 'XenDevice' object hierarchy
> > >
> > > Am 28.11.2018 um 17:29 hat Paul Durrant geschrieben:
> > > > > -----Original Message-----
> > > > > From: Stefano Stabellini [mailto:sstabellini@kernel.org]
> > > > > Sent: 28 November 2018 16:28
> > > > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > > > Cc: 'Kevin Wolf' <kwolf@redhat.com>; qemu-block@nongnu.org; qemu-
> > > > > devel@nongnu.org; xen-devel@lists.xenproject.org; Stefano Stabellini
> > > > > <sstabellini@kernel.org>; Eduardo Habkost <ehabkost@redhat.com>;
> > > Michael
> > > > > S. Tsirkin <mst@redhat.com>; Marcel Apfelbaum
> > > > > <marcel.apfelbaum@gmail.com>; Anthony Perard
> > > <anthony.perard@citrix.com>;
> > > > > Paolo Bonzini <pbonzini@redhat.com>; Richard Henderson
> > > <rth@twiddle.net>
> > > > > Subject: RE: [Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus'
> > > and
> > > > > 'XenDevice' object hierarchy
> > > > >
> > > > > On Wed, 28 Nov 2018, Paul Durrant wrote:
> > > > > > > -----Original Message-----
> > > > > > > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > > > > > > Sent: 28 November 2018 16:19
> > > > > > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > > > > > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > > > > > > devel@lists.xenproject.org; Stefano Stabellini
> > > > > <sstabellini@kernel.org>;
> > > > > > > Eduardo Habkost <ehabkost@redhat.com>; Michael S. Tsirkin
> > > > > > > <mst@redhat.com>; Marcel Apfelbaum <marcel.apfelbaum@gmail.com>;
> > > > > Anthony
> > > > > > > Perard <anthony.perard@citrix.com>; Paolo Bonzini
> > > > > <pbonzini@redhat.com>;
> > > > > > > Richard Henderson <rth@twiddle.net>
> > > > > > > Subject: Re: [Qemu-block] [PATCH 02/18] xen: introduce new
> > > 'XenBus'
> > > > > and
> > > > > > > 'XenDevice' object hierarchy
> > > > > > >
> > > > > > > Am 21.11.2018 um 16:11 hat Paul Durrant geschrieben:
> > > > > > > > This patch adds the basic boilerplate for a 'XenBus' object
> > that
> > > > > will
> > > > > > > act
> > > > > > > > as a parent to 'XenDevice' PV backends.
> > > > > > > > A new 'XenBridge' object is also added to connect XenBus to
> > the
> > > > > system
> > > > > > > bus.
> > > > > > > >
> > > > > > > > The XenBus object is instantiated by a new xen_bus_init()
> > > function
> > > > > > > called
> > > > > > > > from the same sites as the legacy xen_be_init() function.
> > > > > > > >
> > > > > > > > Subsequent patches will flesh-out the functionality of these
> > > > > objects.
> > > > > > > >
> > > > > > > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > > > > > >
> > > > > > > > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > > > > > > > new file mode 100644
> > > > > > > > index 0000000000..dede2d914a
> > > > > > > > --- /dev/null
> > > > > > > > +++ b/hw/xen/xen-bus.c
> > > > > > > > @@ -0,0 +1,125 @@
> > > > > > > > +/*
> > > > > > > > + * Copyright (c) Citrix Systems Inc.
> > > > > > > > + * All rights reserved.
> > > > > > > > + */
> > > > > > >
> > > > > > > This doesn't look very compatible with the GPL. In fact it might
> > > even
> > > > > > > make it illegal for the QEMU project to distribute this code. :-
> > )
> > > > > > >
> > > > > > > Other files you add throughout the series seem to have the same
> > > > > problem.
> > > > > > >
> > > > > >
> > > > > > I was working on the assumption that a lack of explicit license
> > > meant
> > > > > that the overall project license as described in item 2 in LICENSE.
> > > Did I
> > > > > misinterpret that text?
> > > > >
> > > > > It's "All rights reserved." the problem
> > > >
> > > > Oh, I see. I'm happy to remove that.
> > >
> > > That would be better at least. I'm not sure about files that have a
> > > copyright header, but no license statement. Do such files exist yet in
> > > the source tree?
> > 
> > Yes, there's quite a few... e.g. (first ones I tripped over)
> > hw/rdma/rdma_backend.c, hw/virtio/vhost-backend.c, ...
> 
> Oh... I see they have a license statement but no boilerplate... is
> that statement enough?

Yes, this is good enough.

> > > To be on the safe side, I'd just stick with the
> > > established practice, which is having a license header in every file.
> > 
> > Ok... if that is established practice. It really wasn't clear.
> > 
> > >
> > > By the way, in a later patch you remove the existing license header,
> > > which is different from the default license (because parts of the source
> > > file are GPL 2 only). If you can't prove that all such parts (and parts
> > > derived from them) have been removed, this is also a problem.
> > >
> > 
> > What should I do? I am duplicating xen_disk, and then heavily modifying
> > it. Should I just leave the old boilerplate in place?

Yes. Feel free to add your own copyright line right below Gerd's, but
leave the old stuff intact.

Kevin

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 14/18] xen: add implementations of xen-qdisk connect and disconnect functions...
  2018-11-29  9:00       ` [Qemu-devel] " Kevin Wolf
@ 2018-11-29  9:33         ` Paul Durrant
  2018-11-29 10:46             ` Kevin Wolf
  2018-11-29  9:33         ` Paul Durrant
  1 sibling, 1 reply; 157+ messages in thread
From: Paul Durrant @ 2018-11-29  9:33 UTC (permalink / raw)
  To: 'Kevin Wolf'
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Anthony Perard, Max Reitz

> -----Original Message-----
> From: Kevin Wolf [mailto:kwolf@redhat.com]
> Sent: 29 November 2018 09:01
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> Anthony Perard <anthony.perard@citrix.com>; Max Reitz <mreitz@redhat.com>
> Subject: Re: [PATCH 14/18] xen: add implementations of xen-qdisk connect
> and disconnect functions...
> 
> Am 28.11.2018 um 17:40 hat Paul Durrant geschrieben:
> > > -----Original Message-----
> > > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > > Sent: 28 November 2018 16:35
> > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > > devel@lists.xenproject.org; Stefano Stabellini
> <sstabellini@kernel.org>;
> > > Anthony Perard <anthony.perard@citrix.com>; Max Reitz
> <mreitz@redhat.com>
> > > Subject: Re: [PATCH 14/18] xen: add implementations of xen-qdisk
> connect
> > > and disconnect functions...
> > >
> > > Am 21.11.2018 um 16:12 hat Paul Durrant geschrieben:
> > > > ...and wire in the dataplane.
> > > >
> > > > This patch adds the remaining code to make the xen-qdisk XenDevice
> > > > functional. The parameters that a block frontend expects to find are
> > > > populated in the backend xenstore area, and the 'ring-ref' and
> > > > 'event-channel' values specified in the frontend xenstore area are
> > > > mapped/bound and used to set up the dataplane.
> > > >
> > > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > > > ---
> > > > Cc: Stefano Stabellini <sstabellini@kernel.org>
> > > > Cc: Anthony Perard <anthony.perard@citrix.com>
> > > > Cc: Kevin Wolf <kwolf@redhat.com>
> > > > Cc: Max Reitz <mreitz@redhat.com>
> > > > ---
> > > >  hw/block/xen-qdisk.c       | 140
> > > +++++++++++++++++++++++++++++++++++++++++++++
> > > >  hw/xen/xen-bus.c           |  12 ++--
> > > >  include/hw/xen/xen-bus.h   |   8 +++
> > > >  include/hw/xen/xen-qdisk.h |  12 ++++
> > > >  4 files changed, 166 insertions(+), 6 deletions(-)
> > > >
> > > > diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> > > > index 35f7b70480..8c88393832 100644
> > > > --- a/hw/block/xen-qdisk.c
> > > > +++ b/hw/block/xen-qdisk.c
> > > > @@ -9,6 +9,10 @@
> > > >  #include "qapi/visitor.h"
> > > >  #include "hw/hw.h"
> > > >  #include "hw/xen/xen-qdisk.h"
> > > > +#include "sysemu/blockdev.h"
> > > > +#include "sysemu/block-backend.h"
> > > > +#include "sysemu/iothread.h"
> > > > +#include "dataplane/xen-qdisk.h"
> > > >  #include "trace.h"
> > > >
> > > >  static char *xen_qdisk_get_name(XenDevice *xendev, Error **errp)
> > > > @@ -23,6 +27,11 @@ static void xen_qdisk_realize(XenDevice *xendev,
> > > Error **errp)
> > > >  {
> > > >      XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
> > > >      XenQdiskVdev *vdev = &qdiskdev->vdev;
> > > > +    BlockConf *conf = &qdiskdev->conf;
> > > > +    DriveInfo *dinfo;
> > > > +    bool is_cdrom;
> > > > +    unsigned int info;
> > > > +    int64_t size;
> > > >
> > > >      if (!vdev->valid) {
> > > >          error_setg(errp, "vdev property not set");
> > > > @@ -30,13 +39,134 @@ static void xen_qdisk_realize(XenDevice
> *xendev,
> > > Error **errp)
> > > >      }
> > > >
> > > >      trace_xen_qdisk_realize(vdev->disk, vdev->partition);
> > > > +
> > > > +    if (!conf->blk) {
> > > > +        error_setg(errp, "drive property not set");
> > > > +        return;
> > > > +    }
> > > > +
> > > > +    if (!blk_is_inserted(conf->blk)) {
> > > > +        error_setg(errp, "device needs media, but drive is empty");
> > > > +        return;
> > > > +    }
> > >
> > > Hm, the code below suggests that you support CD-ROMs. Don't you want
> to
> > > support media change as well then? Which would mean that you need to
> > > support empty drives.
> >
> > Yes, that's a good point. I should get rid of that check.
> 
> Or rather apply it only to hard disks. And for empty CDs, you'll
> probably need to create an empty BlockBackend (the !conf->blk case).
> Just check the IDE and/or SCSI code for comparison.
> 
> > >
> > > > +    if (!blkconf_apply_backend_options(conf, blk_is_read_only(conf-
> > > >blk),
> > > > +                                       false, errp)) {
> > > > +        return;
> > > > +    }
> > > > +
> > > > +    if (!blkconf_geometry(conf, NULL, 65535, 255, 255, errp)) {
> > > > +        return;
> > > > +    }
> > > > +
> > > > +    dinfo = blk_legacy_dinfo(conf->blk);
> > > > +    is_cdrom = (dinfo && dinfo->media_cd);
> > >
> > > It's called legacy for a reason. Don't use this in new devices.
> > >
> > > The proper way is to have two different devices for hard disks and CDs
> > > (like scsi-hd and scsi-cd).
> >
> > ...or presumably I could have a property? The legacy init code could
> > then set it based on the drive info.
> 
> Technically yes, but why would that be a good way to model things? I
> mean, it's true that xen-qdisk is not real hardware, but I've never seen
> any hardware that has a switch to decide whether it should behave as a
> CD drive or a hard disk.
> 
> Both have very different characteristics (read-only with removable
> media, or a single read-write disk), and the existing implementations
> use two separate devices. So even if you're not convinced that users
> will consider them different concepts (I am; and if they weren't
> different concepts, you wouldn't need an is_cdrom variable), consistency
> is still a good thing.

Ok. I'll split the device as you suggest... it may mean duplicated code, but the datapath can still be common.

  Paul

> 
> Kevin

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 14/18] xen: add implementations of xen-qdisk connect and disconnect functions...
  2018-11-29  9:00       ` [Qemu-devel] " Kevin Wolf
  2018-11-29  9:33         ` Paul Durrant
@ 2018-11-29  9:33         ` Paul Durrant
  1 sibling, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-29  9:33 UTC (permalink / raw)
  To: 'Kevin Wolf'
  Cc: Stefano Stabellini, qemu-block, qemu-devel, Max Reitz,
	Anthony Perard, xen-devel

> -----Original Message-----
> From: Kevin Wolf [mailto:kwolf@redhat.com]
> Sent: 29 November 2018 09:01
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> Anthony Perard <anthony.perard@citrix.com>; Max Reitz <mreitz@redhat.com>
> Subject: Re: [PATCH 14/18] xen: add implementations of xen-qdisk connect
> and disconnect functions...
> 
> Am 28.11.2018 um 17:40 hat Paul Durrant geschrieben:
> > > -----Original Message-----
> > > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > > Sent: 28 November 2018 16:35
> > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > > devel@lists.xenproject.org; Stefano Stabellini
> <sstabellini@kernel.org>;
> > > Anthony Perard <anthony.perard@citrix.com>; Max Reitz
> <mreitz@redhat.com>
> > > Subject: Re: [PATCH 14/18] xen: add implementations of xen-qdisk
> connect
> > > and disconnect functions...
> > >
> > > Am 21.11.2018 um 16:12 hat Paul Durrant geschrieben:
> > > > ...and wire in the dataplane.
> > > >
> > > > This patch adds the remaining code to make the xen-qdisk XenDevice
> > > > functional. The parameters that a block frontend expects to find are
> > > > populated in the backend xenstore area, and the 'ring-ref' and
> > > > 'event-channel' values specified in the frontend xenstore area are
> > > > mapped/bound and used to set up the dataplane.
> > > >
> > > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > > > ---
> > > > Cc: Stefano Stabellini <sstabellini@kernel.org>
> > > > Cc: Anthony Perard <anthony.perard@citrix.com>
> > > > Cc: Kevin Wolf <kwolf@redhat.com>
> > > > Cc: Max Reitz <mreitz@redhat.com>
> > > > ---
> > > >  hw/block/xen-qdisk.c       | 140
> > > +++++++++++++++++++++++++++++++++++++++++++++
> > > >  hw/xen/xen-bus.c           |  12 ++--
> > > >  include/hw/xen/xen-bus.h   |   8 +++
> > > >  include/hw/xen/xen-qdisk.h |  12 ++++
> > > >  4 files changed, 166 insertions(+), 6 deletions(-)
> > > >
> > > > diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> > > > index 35f7b70480..8c88393832 100644
> > > > --- a/hw/block/xen-qdisk.c
> > > > +++ b/hw/block/xen-qdisk.c
> > > > @@ -9,6 +9,10 @@
> > > >  #include "qapi/visitor.h"
> > > >  #include "hw/hw.h"
> > > >  #include "hw/xen/xen-qdisk.h"
> > > > +#include "sysemu/blockdev.h"
> > > > +#include "sysemu/block-backend.h"
> > > > +#include "sysemu/iothread.h"
> > > > +#include "dataplane/xen-qdisk.h"
> > > >  #include "trace.h"
> > > >
> > > >  static char *xen_qdisk_get_name(XenDevice *xendev, Error **errp)
> > > > @@ -23,6 +27,11 @@ static void xen_qdisk_realize(XenDevice *xendev,
> > > Error **errp)
> > > >  {
> > > >      XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
> > > >      XenQdiskVdev *vdev = &qdiskdev->vdev;
> > > > +    BlockConf *conf = &qdiskdev->conf;
> > > > +    DriveInfo *dinfo;
> > > > +    bool is_cdrom;
> > > > +    unsigned int info;
> > > > +    int64_t size;
> > > >
> > > >      if (!vdev->valid) {
> > > >          error_setg(errp, "vdev property not set");
> > > > @@ -30,13 +39,134 @@ static void xen_qdisk_realize(XenDevice
> *xendev,
> > > Error **errp)
> > > >      }
> > > >
> > > >      trace_xen_qdisk_realize(vdev->disk, vdev->partition);
> > > > +
> > > > +    if (!conf->blk) {
> > > > +        error_setg(errp, "drive property not set");
> > > > +        return;
> > > > +    }
> > > > +
> > > > +    if (!blk_is_inserted(conf->blk)) {
> > > > +        error_setg(errp, "device needs media, but drive is empty");
> > > > +        return;
> > > > +    }
> > >
> > > Hm, the code below suggests that you support CD-ROMs. Don't you want
> to
> > > support media change as well then? Which would mean that you need to
> > > support empty drives.
> >
> > Yes, that's a good point. I should get rid of that check.
> 
> Or rather apply it only to hard disks. And for empty CDs, you'll
> probably need to create an empty BlockBackend (the !conf->blk case).
> Just check the IDE and/or SCSI code for comparison.
> 
> > >
> > > > +    if (!blkconf_apply_backend_options(conf, blk_is_read_only(conf-
> > > >blk),
> > > > +                                       false, errp)) {
> > > > +        return;
> > > > +    }
> > > > +
> > > > +    if (!blkconf_geometry(conf, NULL, 65535, 255, 255, errp)) {
> > > > +        return;
> > > > +    }
> > > > +
> > > > +    dinfo = blk_legacy_dinfo(conf->blk);
> > > > +    is_cdrom = (dinfo && dinfo->media_cd);
> > >
> > > It's called legacy for a reason. Don't use this in new devices.
> > >
> > > The proper way is to have two different devices for hard disks and CDs
> > > (like scsi-hd and scsi-cd).
> >
> > ...or presumably I could have a property? The legacy init code could
> > then set it based on the drive info.
> 
> Technically yes, but why would that be a good way to model things? I
> mean, it's true that xen-qdisk is not real hardware, but I've never seen
> any hardware that has a switch to decide whether it should behave as a
> CD drive or a hard disk.
> 
> Both have very different characteristics (read-only with removable
> media, or a single read-write disk), and the existing implementations
> use two separate devices. So even if you're not convinced that users
> will consider them different concepts (I am; and if they weren't
> different concepts, you wouldn't need an is_cdrom variable), consistency
> is still a good thing.

Ok. I'll split the device as you suggest... it may mean duplicated code, but the datapath can still be common.

  Paul

> 
> Kevin

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 14/18] xen: add implementations of xen-qdisk connect and disconnect functions...
  2018-11-29  9:33         ` Paul Durrant
@ 2018-11-29 10:46             ` Kevin Wolf
  0 siblings, 0 replies; 157+ messages in thread
From: Kevin Wolf @ 2018-11-29 10:46 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Anthony Perard, Max Reitz

Am 29.11.2018 um 10:33 hat Paul Durrant geschrieben:
> > -----Original Message-----
> > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > Sent: 29 November 2018 09:01
> > To: Paul Durrant <Paul.Durrant@citrix.com>
> > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> > Anthony Perard <anthony.perard@citrix.com>; Max Reitz <mreitz@redhat.com>
> > Subject: Re: [PATCH 14/18] xen: add implementations of xen-qdisk connect
> > and disconnect functions...
> > 
> > Am 28.11.2018 um 17:40 hat Paul Durrant geschrieben:
> > > > -----Original Message-----
> > > > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > > > Sent: 28 November 2018 16:35
> > > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > > > devel@lists.xenproject.org; Stefano Stabellini
> > <sstabellini@kernel.org>;
> > > > Anthony Perard <anthony.perard@citrix.com>; Max Reitz
> > <mreitz@redhat.com>
> > > > Subject: Re: [PATCH 14/18] xen: add implementations of xen-qdisk
> > connect
> > > > and disconnect functions...
> > > >
> > > > Am 21.11.2018 um 16:12 hat Paul Durrant geschrieben:
> > > > > ...and wire in the dataplane.
> > > > >
> > > > > This patch adds the remaining code to make the xen-qdisk XenDevice
> > > > > functional. The parameters that a block frontend expects to find are
> > > > > populated in the backend xenstore area, and the 'ring-ref' and
> > > > > 'event-channel' values specified in the frontend xenstore area are
> > > > > mapped/bound and used to set up the dataplane.
> > > > >
> > > > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > > > > ---
> > > > > Cc: Stefano Stabellini <sstabellini@kernel.org>
> > > > > Cc: Anthony Perard <anthony.perard@citrix.com>
> > > > > Cc: Kevin Wolf <kwolf@redhat.com>
> > > > > Cc: Max Reitz <mreitz@redhat.com>
> > > > > ---
> > > > >  hw/block/xen-qdisk.c       | 140
> > > > +++++++++++++++++++++++++++++++++++++++++++++
> > > > >  hw/xen/xen-bus.c           |  12 ++--
> > > > >  include/hw/xen/xen-bus.h   |   8 +++
> > > > >  include/hw/xen/xen-qdisk.h |  12 ++++
> > > > >  4 files changed, 166 insertions(+), 6 deletions(-)
> > > > >
> > > > > diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> > > > > index 35f7b70480..8c88393832 100644
> > > > > --- a/hw/block/xen-qdisk.c
> > > > > +++ b/hw/block/xen-qdisk.c
> > > > > @@ -9,6 +9,10 @@
> > > > >  #include "qapi/visitor.h"
> > > > >  #include "hw/hw.h"
> > > > >  #include "hw/xen/xen-qdisk.h"
> > > > > +#include "sysemu/blockdev.h"
> > > > > +#include "sysemu/block-backend.h"
> > > > > +#include "sysemu/iothread.h"
> > > > > +#include "dataplane/xen-qdisk.h"
> > > > >  #include "trace.h"
> > > > >
> > > > >  static char *xen_qdisk_get_name(XenDevice *xendev, Error **errp)
> > > > > @@ -23,6 +27,11 @@ static void xen_qdisk_realize(XenDevice *xendev,
> > > > Error **errp)
> > > > >  {
> > > > >      XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
> > > > >      XenQdiskVdev *vdev = &qdiskdev->vdev;
> > > > > +    BlockConf *conf = &qdiskdev->conf;
> > > > > +    DriveInfo *dinfo;
> > > > > +    bool is_cdrom;
> > > > > +    unsigned int info;
> > > > > +    int64_t size;
> > > > >
> > > > >      if (!vdev->valid) {
> > > > >          error_setg(errp, "vdev property not set");
> > > > > @@ -30,13 +39,134 @@ static void xen_qdisk_realize(XenDevice
> > *xendev,
> > > > Error **errp)
> > > > >      }
> > > > >
> > > > >      trace_xen_qdisk_realize(vdev->disk, vdev->partition);
> > > > > +
> > > > > +    if (!conf->blk) {
> > > > > +        error_setg(errp, "drive property not set");
> > > > > +        return;
> > > > > +    }
> > > > > +
> > > > > +    if (!blk_is_inserted(conf->blk)) {
> > > > > +        error_setg(errp, "device needs media, but drive is empty");
> > > > > +        return;
> > > > > +    }
> > > >
> > > > Hm, the code below suggests that you support CD-ROMs. Don't you want
> > to
> > > > support media change as well then? Which would mean that you need to
> > > > support empty drives.
> > >
> > > Yes, that's a good point. I should get rid of that check.
> > 
> > Or rather apply it only to hard disks. And for empty CDs, you'll
> > probably need to create an empty BlockBackend (the !conf->blk case).
> > Just check the IDE and/or SCSI code for comparison.
> > 
> > > >
> > > > > +    if (!blkconf_apply_backend_options(conf, blk_is_read_only(conf-
> > > > >blk),
> > > > > +                                       false, errp)) {
> > > > > +        return;
> > > > > +    }
> > > > > +
> > > > > +    if (!blkconf_geometry(conf, NULL, 65535, 255, 255, errp)) {
> > > > > +        return;
> > > > > +    }
> > > > > +
> > > > > +    dinfo = blk_legacy_dinfo(conf->blk);
> > > > > +    is_cdrom = (dinfo && dinfo->media_cd);
> > > >
> > > > It's called legacy for a reason. Don't use this in new devices.
> > > >
> > > > The proper way is to have two different devices for hard disks and CDs
> > > > (like scsi-hd and scsi-cd).
> > >
> > > ...or presumably I could have a property? The legacy init code could
> > > then set it based on the drive info.
> > 
> > Technically yes, but why would that be a good way to model things? I
> > mean, it's true that xen-qdisk is not real hardware, but I've never seen
> > any hardware that has a switch to decide whether it should behave as a
> > CD drive or a hard disk.
> > 
> > Both have very different characteristics (read-only with removable
> > media, or a single read-write disk), and the existing implementations
> > use two separate devices. So even if you're not convinced that users
> > will consider them different concepts (I am; and if they weren't
> > different concepts, you wouldn't need an is_cdrom variable), consistency
> > is still a good thing.
> 
> Ok. I'll split the device as you suggest... it may mean duplicated
> code, but the datapath can still be common.

If you have a look at IDE and SCSI, they don't really duplicate a lot of
code. Basically it's just a second QOM class definition, the rest is
shared. Even the realize functions are essentially shared, with just two
small wrappers for each device type around the common code.

Kevin

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 14/18] xen: add implementations of xen-qdisk connect and disconnect functions...
@ 2018-11-29 10:46             ` Kevin Wolf
  0 siblings, 0 replies; 157+ messages in thread
From: Kevin Wolf @ 2018-11-29 10:46 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Stefano Stabellini, qemu-block, qemu-devel, Max Reitz,
	Anthony Perard, xen-devel

Am 29.11.2018 um 10:33 hat Paul Durrant geschrieben:
> > -----Original Message-----
> > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > Sent: 29 November 2018 09:01
> > To: Paul Durrant <Paul.Durrant@citrix.com>
> > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> > Anthony Perard <anthony.perard@citrix.com>; Max Reitz <mreitz@redhat.com>
> > Subject: Re: [PATCH 14/18] xen: add implementations of xen-qdisk connect
> > and disconnect functions...
> > 
> > Am 28.11.2018 um 17:40 hat Paul Durrant geschrieben:
> > > > -----Original Message-----
> > > > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > > > Sent: 28 November 2018 16:35
> > > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > > > devel@lists.xenproject.org; Stefano Stabellini
> > <sstabellini@kernel.org>;
> > > > Anthony Perard <anthony.perard@citrix.com>; Max Reitz
> > <mreitz@redhat.com>
> > > > Subject: Re: [PATCH 14/18] xen: add implementations of xen-qdisk
> > connect
> > > > and disconnect functions...
> > > >
> > > > Am 21.11.2018 um 16:12 hat Paul Durrant geschrieben:
> > > > > ...and wire in the dataplane.
> > > > >
> > > > > This patch adds the remaining code to make the xen-qdisk XenDevice
> > > > > functional. The parameters that a block frontend expects to find are
> > > > > populated in the backend xenstore area, and the 'ring-ref' and
> > > > > 'event-channel' values specified in the frontend xenstore area are
> > > > > mapped/bound and used to set up the dataplane.
> > > > >
> > > > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > > > > ---
> > > > > Cc: Stefano Stabellini <sstabellini@kernel.org>
> > > > > Cc: Anthony Perard <anthony.perard@citrix.com>
> > > > > Cc: Kevin Wolf <kwolf@redhat.com>
> > > > > Cc: Max Reitz <mreitz@redhat.com>
> > > > > ---
> > > > >  hw/block/xen-qdisk.c       | 140
> > > > +++++++++++++++++++++++++++++++++++++++++++++
> > > > >  hw/xen/xen-bus.c           |  12 ++--
> > > > >  include/hw/xen/xen-bus.h   |   8 +++
> > > > >  include/hw/xen/xen-qdisk.h |  12 ++++
> > > > >  4 files changed, 166 insertions(+), 6 deletions(-)
> > > > >
> > > > > diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> > > > > index 35f7b70480..8c88393832 100644
> > > > > --- a/hw/block/xen-qdisk.c
> > > > > +++ b/hw/block/xen-qdisk.c
> > > > > @@ -9,6 +9,10 @@
> > > > >  #include "qapi/visitor.h"
> > > > >  #include "hw/hw.h"
> > > > >  #include "hw/xen/xen-qdisk.h"
> > > > > +#include "sysemu/blockdev.h"
> > > > > +#include "sysemu/block-backend.h"
> > > > > +#include "sysemu/iothread.h"
> > > > > +#include "dataplane/xen-qdisk.h"
> > > > >  #include "trace.h"
> > > > >
> > > > >  static char *xen_qdisk_get_name(XenDevice *xendev, Error **errp)
> > > > > @@ -23,6 +27,11 @@ static void xen_qdisk_realize(XenDevice *xendev,
> > > > Error **errp)
> > > > >  {
> > > > >      XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
> > > > >      XenQdiskVdev *vdev = &qdiskdev->vdev;
> > > > > +    BlockConf *conf = &qdiskdev->conf;
> > > > > +    DriveInfo *dinfo;
> > > > > +    bool is_cdrom;
> > > > > +    unsigned int info;
> > > > > +    int64_t size;
> > > > >
> > > > >      if (!vdev->valid) {
> > > > >          error_setg(errp, "vdev property not set");
> > > > > @@ -30,13 +39,134 @@ static void xen_qdisk_realize(XenDevice
> > *xendev,
> > > > Error **errp)
> > > > >      }
> > > > >
> > > > >      trace_xen_qdisk_realize(vdev->disk, vdev->partition);
> > > > > +
> > > > > +    if (!conf->blk) {
> > > > > +        error_setg(errp, "drive property not set");
> > > > > +        return;
> > > > > +    }
> > > > > +
> > > > > +    if (!blk_is_inserted(conf->blk)) {
> > > > > +        error_setg(errp, "device needs media, but drive is empty");
> > > > > +        return;
> > > > > +    }
> > > >
> > > > Hm, the code below suggests that you support CD-ROMs. Don't you want
> > to
> > > > support media change as well then? Which would mean that you need to
> > > > support empty drives.
> > >
> > > Yes, that's a good point. I should get rid of that check.
> > 
> > Or rather apply it only to hard disks. And for empty CDs, you'll
> > probably need to create an empty BlockBackend (the !conf->blk case).
> > Just check the IDE and/or SCSI code for comparison.
> > 
> > > >
> > > > > +    if (!blkconf_apply_backend_options(conf, blk_is_read_only(conf-
> > > > >blk),
> > > > > +                                       false, errp)) {
> > > > > +        return;
> > > > > +    }
> > > > > +
> > > > > +    if (!blkconf_geometry(conf, NULL, 65535, 255, 255, errp)) {
> > > > > +        return;
> > > > > +    }
> > > > > +
> > > > > +    dinfo = blk_legacy_dinfo(conf->blk);
> > > > > +    is_cdrom = (dinfo && dinfo->media_cd);
> > > >
> > > > It's called legacy for a reason. Don't use this in new devices.
> > > >
> > > > The proper way is to have two different devices for hard disks and CDs
> > > > (like scsi-hd and scsi-cd).
> > >
> > > ...or presumably I could have a property? The legacy init code could
> > > then set it based on the drive info.
> > 
> > Technically yes, but why would that be a good way to model things? I
> > mean, it's true that xen-qdisk is not real hardware, but I've never seen
> > any hardware that has a switch to decide whether it should behave as a
> > CD drive or a hard disk.
> > 
> > Both have very different characteristics (read-only with removable
> > media, or a single read-write disk), and the existing implementations
> > use two separate devices. So even if you're not convinced that users
> > will consider them different concepts (I am; and if they weren't
> > different concepts, you wouldn't need an is_cdrom variable), consistency
> > is still a good thing.
> 
> Ok. I'll split the device as you suggest... it may mean duplicated
> code, but the datapath can still be common.

If you have a look at IDE and SCSI, they don't really duplicate a lot of
code. Basically it's just a second QOM class definition, the rest is
shared. Even the realize functions are essentially shared, with just two
small wrappers for each device type around the common code.

Kevin

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 14/18] xen: add implementations of xen-qdisk connect and disconnect functions...
  2018-11-29 10:46             ` Kevin Wolf
  (?)
  (?)
@ 2018-11-29 10:47             ` Paul Durrant
  -1 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-29 10:47 UTC (permalink / raw)
  To: 'Kevin Wolf'
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Anthony Perard, Max Reitz

> -----Original Message-----
> From: Kevin Wolf [mailto:kwolf@redhat.com]
> Sent: 29 November 2018 10:46
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> Anthony Perard <anthony.perard@citrix.com>; Max Reitz <mreitz@redhat.com>
> Subject: Re: [PATCH 14/18] xen: add implementations of xen-qdisk connect
> and disconnect functions...
> 
> Am 29.11.2018 um 10:33 hat Paul Durrant geschrieben:
> > > -----Original Message-----
> > > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > > Sent: 29 November 2018 09:01
> > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > > devel@lists.xenproject.org; Stefano Stabellini
> <sstabellini@kernel.org>;
> > > Anthony Perard <anthony.perard@citrix.com>; Max Reitz
> <mreitz@redhat.com>
> > > Subject: Re: [PATCH 14/18] xen: add implementations of xen-qdisk
> connect
> > > and disconnect functions...
> > >
> > > Am 28.11.2018 um 17:40 hat Paul Durrant geschrieben:
> > > > > -----Original Message-----
> > > > > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > > > > Sent: 28 November 2018 16:35
> > > > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > > > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > > > > devel@lists.xenproject.org; Stefano Stabellini
> > > <sstabellini@kernel.org>;
> > > > > Anthony Perard <anthony.perard@citrix.com>; Max Reitz
> > > <mreitz@redhat.com>
> > > > > Subject: Re: [PATCH 14/18] xen: add implementations of xen-qdisk
> > > connect
> > > > > and disconnect functions...
> > > > >
> > > > > Am 21.11.2018 um 16:12 hat Paul Durrant geschrieben:
> > > > > > ...and wire in the dataplane.
> > > > > >
> > > > > > This patch adds the remaining code to make the xen-qdisk
> XenDevice
> > > > > > functional. The parameters that a block frontend expects to find
> are
> > > > > > populated in the backend xenstore area, and the 'ring-ref' and
> > > > > > 'event-channel' values specified in the frontend xenstore area
> are
> > > > > > mapped/bound and used to set up the dataplane.
> > > > > >
> > > > > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > > > > > ---
> > > > > > Cc: Stefano Stabellini <sstabellini@kernel.org>
> > > > > > Cc: Anthony Perard <anthony.perard@citrix.com>
> > > > > > Cc: Kevin Wolf <kwolf@redhat.com>
> > > > > > Cc: Max Reitz <mreitz@redhat.com>
> > > > > > ---
> > > > > >  hw/block/xen-qdisk.c       | 140
> > > > > +++++++++++++++++++++++++++++++++++++++++++++
> > > > > >  hw/xen/xen-bus.c           |  12 ++--
> > > > > >  include/hw/xen/xen-bus.h   |   8 +++
> > > > > >  include/hw/xen/xen-qdisk.h |  12 ++++
> > > > > >  4 files changed, 166 insertions(+), 6 deletions(-)
> > > > > >
> > > > > > diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> > > > > > index 35f7b70480..8c88393832 100644
> > > > > > --- a/hw/block/xen-qdisk.c
> > > > > > +++ b/hw/block/xen-qdisk.c
> > > > > > @@ -9,6 +9,10 @@
> > > > > >  #include "qapi/visitor.h"
> > > > > >  #include "hw/hw.h"
> > > > > >  #include "hw/xen/xen-qdisk.h"
> > > > > > +#include "sysemu/blockdev.h"
> > > > > > +#include "sysemu/block-backend.h"
> > > > > > +#include "sysemu/iothread.h"
> > > > > > +#include "dataplane/xen-qdisk.h"
> > > > > >  #include "trace.h"
> > > > > >
> > > > > >  static char *xen_qdisk_get_name(XenDevice *xendev, Error
> **errp)
> > > > > > @@ -23,6 +27,11 @@ static void xen_qdisk_realize(XenDevice
> *xendev,
> > > > > Error **errp)
> > > > > >  {
> > > > > >      XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
> > > > > >      XenQdiskVdev *vdev = &qdiskdev->vdev;
> > > > > > +    BlockConf *conf = &qdiskdev->conf;
> > > > > > +    DriveInfo *dinfo;
> > > > > > +    bool is_cdrom;
> > > > > > +    unsigned int info;
> > > > > > +    int64_t size;
> > > > > >
> > > > > >      if (!vdev->valid) {
> > > > > >          error_setg(errp, "vdev property not set");
> > > > > > @@ -30,13 +39,134 @@ static void xen_qdisk_realize(XenDevice
> > > *xendev,
> > > > > Error **errp)
> > > > > >      }
> > > > > >
> > > > > >      trace_xen_qdisk_realize(vdev->disk, vdev->partition);
> > > > > > +
> > > > > > +    if (!conf->blk) {
> > > > > > +        error_setg(errp, "drive property not set");
> > > > > > +        return;
> > > > > > +    }
> > > > > > +
> > > > > > +    if (!blk_is_inserted(conf->blk)) {
> > > > > > +        error_setg(errp, "device needs media, but drive is
> empty");
> > > > > > +        return;
> > > > > > +    }
> > > > >
> > > > > Hm, the code below suggests that you support CD-ROMs. Don't you
> want
> > > to
> > > > > support media change as well then? Which would mean that you need
> to
> > > > > support empty drives.
> > > >
> > > > Yes, that's a good point. I should get rid of that check.
> > >
> > > Or rather apply it only to hard disks. And for empty CDs, you'll
> > > probably need to create an empty BlockBackend (the !conf->blk case).
> > > Just check the IDE and/or SCSI code for comparison.
> > >
> > > > >
> > > > > > +    if (!blkconf_apply_backend_options(conf,
> blk_is_read_only(conf-
> > > > > >blk),
> > > > > > +                                       false, errp)) {
> > > > > > +        return;
> > > > > > +    }
> > > > > > +
> > > > > > +    if (!blkconf_geometry(conf, NULL, 65535, 255, 255, errp)) {
> > > > > > +        return;
> > > > > > +    }
> > > > > > +
> > > > > > +    dinfo = blk_legacy_dinfo(conf->blk);
> > > > > > +    is_cdrom = (dinfo && dinfo->media_cd);
> > > > >
> > > > > It's called legacy for a reason. Don't use this in new devices.
> > > > >
> > > > > The proper way is to have two different devices for hard disks and
> CDs
> > > > > (like scsi-hd and scsi-cd).
> > > >
> > > > ...or presumably I could have a property? The legacy init code could
> > > > then set it based on the drive info.
> > >
> > > Technically yes, but why would that be a good way to model things? I
> > > mean, it's true that xen-qdisk is not real hardware, but I've never
> seen
> > > any hardware that has a switch to decide whether it should behave as a
> > > CD drive or a hard disk.
> > >
> > > Both have very different characteristics (read-only with removable
> > > media, or a single read-write disk), and the existing implementations
> > > use two separate devices. So even if you're not convinced that users
> > > will consider them different concepts (I am; and if they weren't
> > > different concepts, you wouldn't need an is_cdrom variable),
> consistency
> > > is still a good thing.
> >
> > Ok. I'll split the device as you suggest... it may mean duplicated
> > code, but the datapath can still be common.
> 
> If you have a look at IDE and SCSI, they don't really duplicate a lot of
> code. Basically it's just a second QOM class definition, the rest is
> shared. Even the realize functions are essentially shared, with just two
> small wrappers for each device type around the common code.

Ok, I was hoping the duplication would be limited to something like that :-) I'll try to follow suit.

  Paul

> 
> Kevin

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 14/18] xen: add implementations of xen-qdisk connect and disconnect functions...
  2018-11-29 10:46             ` Kevin Wolf
  (?)
@ 2018-11-29 10:47             ` Paul Durrant
  -1 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-29 10:47 UTC (permalink / raw)
  To: 'Kevin Wolf'
  Cc: Stefano Stabellini, qemu-block, qemu-devel, Max Reitz,
	Anthony Perard, xen-devel

> -----Original Message-----
> From: Kevin Wolf [mailto:kwolf@redhat.com]
> Sent: 29 November 2018 10:46
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> Anthony Perard <anthony.perard@citrix.com>; Max Reitz <mreitz@redhat.com>
> Subject: Re: [PATCH 14/18] xen: add implementations of xen-qdisk connect
> and disconnect functions...
> 
> Am 29.11.2018 um 10:33 hat Paul Durrant geschrieben:
> > > -----Original Message-----
> > > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > > Sent: 29 November 2018 09:01
> > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > > devel@lists.xenproject.org; Stefano Stabellini
> <sstabellini@kernel.org>;
> > > Anthony Perard <anthony.perard@citrix.com>; Max Reitz
> <mreitz@redhat.com>
> > > Subject: Re: [PATCH 14/18] xen: add implementations of xen-qdisk
> connect
> > > and disconnect functions...
> > >
> > > Am 28.11.2018 um 17:40 hat Paul Durrant geschrieben:
> > > > > -----Original Message-----
> > > > > From: Kevin Wolf [mailto:kwolf@redhat.com]
> > > > > Sent: 28 November 2018 16:35
> > > > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > > > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > > > > devel@lists.xenproject.org; Stefano Stabellini
> > > <sstabellini@kernel.org>;
> > > > > Anthony Perard <anthony.perard@citrix.com>; Max Reitz
> > > <mreitz@redhat.com>
> > > > > Subject: Re: [PATCH 14/18] xen: add implementations of xen-qdisk
> > > connect
> > > > > and disconnect functions...
> > > > >
> > > > > Am 21.11.2018 um 16:12 hat Paul Durrant geschrieben:
> > > > > > ...and wire in the dataplane.
> > > > > >
> > > > > > This patch adds the remaining code to make the xen-qdisk
> XenDevice
> > > > > > functional. The parameters that a block frontend expects to find
> are
> > > > > > populated in the backend xenstore area, and the 'ring-ref' and
> > > > > > 'event-channel' values specified in the frontend xenstore area
> are
> > > > > > mapped/bound and used to set up the dataplane.
> > > > > >
> > > > > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > > > > > ---
> > > > > > Cc: Stefano Stabellini <sstabellini@kernel.org>
> > > > > > Cc: Anthony Perard <anthony.perard@citrix.com>
> > > > > > Cc: Kevin Wolf <kwolf@redhat.com>
> > > > > > Cc: Max Reitz <mreitz@redhat.com>
> > > > > > ---
> > > > > >  hw/block/xen-qdisk.c       | 140
> > > > > +++++++++++++++++++++++++++++++++++++++++++++
> > > > > >  hw/xen/xen-bus.c           |  12 ++--
> > > > > >  include/hw/xen/xen-bus.h   |   8 +++
> > > > > >  include/hw/xen/xen-qdisk.h |  12 ++++
> > > > > >  4 files changed, 166 insertions(+), 6 deletions(-)
> > > > > >
> > > > > > diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> > > > > > index 35f7b70480..8c88393832 100644
> > > > > > --- a/hw/block/xen-qdisk.c
> > > > > > +++ b/hw/block/xen-qdisk.c
> > > > > > @@ -9,6 +9,10 @@
> > > > > >  #include "qapi/visitor.h"
> > > > > >  #include "hw/hw.h"
> > > > > >  #include "hw/xen/xen-qdisk.h"
> > > > > > +#include "sysemu/blockdev.h"
> > > > > > +#include "sysemu/block-backend.h"
> > > > > > +#include "sysemu/iothread.h"
> > > > > > +#include "dataplane/xen-qdisk.h"
> > > > > >  #include "trace.h"
> > > > > >
> > > > > >  static char *xen_qdisk_get_name(XenDevice *xendev, Error
> **errp)
> > > > > > @@ -23,6 +27,11 @@ static void xen_qdisk_realize(XenDevice
> *xendev,
> > > > > Error **errp)
> > > > > >  {
> > > > > >      XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
> > > > > >      XenQdiskVdev *vdev = &qdiskdev->vdev;
> > > > > > +    BlockConf *conf = &qdiskdev->conf;
> > > > > > +    DriveInfo *dinfo;
> > > > > > +    bool is_cdrom;
> > > > > > +    unsigned int info;
> > > > > > +    int64_t size;
> > > > > >
> > > > > >      if (!vdev->valid) {
> > > > > >          error_setg(errp, "vdev property not set");
> > > > > > @@ -30,13 +39,134 @@ static void xen_qdisk_realize(XenDevice
> > > *xendev,
> > > > > Error **errp)
> > > > > >      }
> > > > > >
> > > > > >      trace_xen_qdisk_realize(vdev->disk, vdev->partition);
> > > > > > +
> > > > > > +    if (!conf->blk) {
> > > > > > +        error_setg(errp, "drive property not set");
> > > > > > +        return;
> > > > > > +    }
> > > > > > +
> > > > > > +    if (!blk_is_inserted(conf->blk)) {
> > > > > > +        error_setg(errp, "device needs media, but drive is
> empty");
> > > > > > +        return;
> > > > > > +    }
> > > > >
> > > > > Hm, the code below suggests that you support CD-ROMs. Don't you
> want
> > > to
> > > > > support media change as well then? Which would mean that you need
> to
> > > > > support empty drives.
> > > >
> > > > Yes, that's a good point. I should get rid of that check.
> > >
> > > Or rather apply it only to hard disks. And for empty CDs, you'll
> > > probably need to create an empty BlockBackend (the !conf->blk case).
> > > Just check the IDE and/or SCSI code for comparison.
> > >
> > > > >
> > > > > > +    if (!blkconf_apply_backend_options(conf,
> blk_is_read_only(conf-
> > > > > >blk),
> > > > > > +                                       false, errp)) {
> > > > > > +        return;
> > > > > > +    }
> > > > > > +
> > > > > > +    if (!blkconf_geometry(conf, NULL, 65535, 255, 255, errp)) {
> > > > > > +        return;
> > > > > > +    }
> > > > > > +
> > > > > > +    dinfo = blk_legacy_dinfo(conf->blk);
> > > > > > +    is_cdrom = (dinfo && dinfo->media_cd);
> > > > >
> > > > > It's called legacy for a reason. Don't use this in new devices.
> > > > >
> > > > > The proper way is to have two different devices for hard disks and
> CDs
> > > > > (like scsi-hd and scsi-cd).
> > > >
> > > > ...or presumably I could have a property? The legacy init code could
> > > > then set it based on the drive info.
> > >
> > > Technically yes, but why would that be a good way to model things? I
> > > mean, it's true that xen-qdisk is not real hardware, but I've never
> seen
> > > any hardware that has a switch to decide whether it should behave as a
> > > CD drive or a hard disk.
> > >
> > > Both have very different characteristics (read-only with removable
> > > media, or a single read-write disk), and the existing implementations
> > > use two separate devices. So even if you're not convinced that users
> > > will consider them different concepts (I am; and if they weren't
> > > different concepts, you wouldn't need an is_cdrom variable),
> consistency
> > > is still a good thing.
> >
> > Ok. I'll split the device as you suggest... it may mean duplicated
> > code, but the datapath can still be common.
> 
> If you have a look at IDE and SCSI, they don't really duplicate a lot of
> code. Basically it's just a second QOM class definition, the rest is
> shared. Even the realize functions are essentially shared, with just two
> small wrappers for each device type around the common code.

Ok, I was hoping the duplication would be limited to something like that :-) I'll try to follow suit.

  Paul

> 
> Kevin

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 17/18] MAINTAINERS: add myself as a Xen maintainer
  2018-11-21 15:12   ` Paul Durrant
                     ` (2 preceding siblings ...)
  (?)
@ 2018-11-29 14:00   ` Philippe Mathieu-Daudé
  2018-11-29 14:01     ` Paul Durrant
  2018-11-29 14:01     ` Paul Durrant
  -1 siblings, 2 replies; 157+ messages in thread
From: Philippe Mathieu-Daudé @ 2018-11-29 14:00 UTC (permalink / raw)
  To: Paul Durrant, qemu-block, qemu-devel, xen-devel
  Cc: Anthony Perard, Paolo Bonzini, Stefano Stabellini

On 21/11/18 16:12, Paul Durrant wrote:
> I have made many significant contributions to the Xen code in QEMU,
> particularly the recent patches introducing a new PV device framework.
> I intend to make further significant contributions, porting other PV back-
> ends to the new framework with the intent of eventually removing the
> legacy code. It therefore seems reasonable that I become a maintiner of

"a maintainer of"

> the Xen code.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> ---
> Cc: Stefano Stabellini <sstabellini@kernel.org>
> Cc: Anthony Perard <anthony.perard@citrix.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  MAINTAINERS | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 5871f035c3..0b668dd205 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -382,6 +382,7 @@ Guest CPU Cores (Xen):
>  X86
>  M: Stefano Stabellini <sstabellini@kernel.org>
>  M: Anthony Perard <anthony.perard@citrix.com>
> +M: Paul Durrant <paul.durrant@citrix.com>
>  L: xen-devel@lists.xenproject.org
>  S: Supported
>  F: */xen*
> 

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 17/18] MAINTAINERS: add myself as a Xen maintainer
  2018-11-21 15:12   ` Paul Durrant
                     ` (3 preceding siblings ...)
  (?)
@ 2018-11-29 14:00   ` Philippe Mathieu-Daudé
  -1 siblings, 0 replies; 157+ messages in thread
From: Philippe Mathieu-Daudé @ 2018-11-29 14:00 UTC (permalink / raw)
  To: Paul Durrant, qemu-block, qemu-devel, xen-devel
  Cc: Anthony Perard, Paolo Bonzini, Stefano Stabellini

On 21/11/18 16:12, Paul Durrant wrote:
> I have made many significant contributions to the Xen code in QEMU,
> particularly the recent patches introducing a new PV device framework.
> I intend to make further significant contributions, porting other PV back-
> ends to the new framework with the intent of eventually removing the
> legacy code. It therefore seems reasonable that I become a maintiner of

"a maintainer of"

> the Xen code.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> ---
> Cc: Stefano Stabellini <sstabellini@kernel.org>
> Cc: Anthony Perard <anthony.perard@citrix.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  MAINTAINERS | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 5871f035c3..0b668dd205 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -382,6 +382,7 @@ Guest CPU Cores (Xen):
>  X86
>  M: Stefano Stabellini <sstabellini@kernel.org>
>  M: Anthony Perard <anthony.perard@citrix.com>
> +M: Paul Durrant <paul.durrant@citrix.com>
>  L: xen-devel@lists.xenproject.org
>  S: Supported
>  F: */xen*
> 

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 17/18] MAINTAINERS: add myself as a Xen maintainer
  2018-11-29 14:00   ` Philippe Mathieu-Daudé
  2018-11-29 14:01     ` Paul Durrant
@ 2018-11-29 14:01     ` Paul Durrant
  1 sibling, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-29 14:01 UTC (permalink / raw)
  To: 'Philippe Mathieu-Daudé', qemu-block, qemu-devel, xen-devel
  Cc: Anthony Perard, Paolo Bonzini, Stefano Stabellini

> -----Original Message-----
> From: Philippe Mathieu-Daudé [mailto:philmd@redhat.com]
> Sent: 29 November 2018 14:01
> To: Paul Durrant <Paul.Durrant@citrix.com>; qemu-block@nongnu.org; qemu-
> devel@nongnu.org; xen-devel@lists.xenproject.org
> Cc: Anthony Perard <anthony.perard@citrix.com>; Paolo Bonzini
> <pbonzini@redhat.com>; Stefano Stabellini <sstabellini@kernel.org>
> Subject: Re: [Qemu-devel] [PATCH 17/18] MAINTAINERS: add myself as a Xen
> maintainer
> 
> On 21/11/18 16:12, Paul Durrant wrote:
> > I have made many significant contributions to the Xen code in QEMU,
> > particularly the recent patches introducing a new PV device framework.
> > I intend to make further significant contributions, porting other PV
> back-
> > ends to the new framework with the intent of eventually removing the
> > legacy code. It therefore seems reasonable that I become a maintiner of
> 
> "a maintainer of"

Yes, of course. I'll correct it in v2.

  Paul

> 
> > the Xen code.
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > ---
> > Cc: Stefano Stabellini <sstabellini@kernel.org>
> > Cc: Anthony Perard <anthony.perard@citrix.com>
> > Cc: Paolo Bonzini <pbonzini@redhat.com>
> > ---
> >  MAINTAINERS | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 5871f035c3..0b668dd205 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -382,6 +382,7 @@ Guest CPU Cores (Xen):
> >  X86
> >  M: Stefano Stabellini <sstabellini@kernel.org>
> >  M: Anthony Perard <anthony.perard@citrix.com>
> > +M: Paul Durrant <paul.durrant@citrix.com>
> >  L: xen-devel@lists.xenproject.org
> >  S: Supported
> >  F: */xen*
> >

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 17/18] MAINTAINERS: add myself as a Xen maintainer
  2018-11-29 14:00   ` Philippe Mathieu-Daudé
@ 2018-11-29 14:01     ` Paul Durrant
  2018-11-29 14:01     ` Paul Durrant
  1 sibling, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-11-29 14:01 UTC (permalink / raw)
  To: 'Philippe Mathieu-Daudé', qemu-block, qemu-devel, xen-devel
  Cc: Anthony Perard, Paolo Bonzini, Stefano Stabellini

> -----Original Message-----
> From: Philippe Mathieu-Daudé [mailto:philmd@redhat.com]
> Sent: 29 November 2018 14:01
> To: Paul Durrant <Paul.Durrant@citrix.com>; qemu-block@nongnu.org; qemu-
> devel@nongnu.org; xen-devel@lists.xenproject.org
> Cc: Anthony Perard <anthony.perard@citrix.com>; Paolo Bonzini
> <pbonzini@redhat.com>; Stefano Stabellini <sstabellini@kernel.org>
> Subject: Re: [Qemu-devel] [PATCH 17/18] MAINTAINERS: add myself as a Xen
> maintainer
> 
> On 21/11/18 16:12, Paul Durrant wrote:
> > I have made many significant contributions to the Xen code in QEMU,
> > particularly the recent patches introducing a new PV device framework.
> > I intend to make further significant contributions, porting other PV
> back-
> > ends to the new framework with the intent of eventually removing the
> > legacy code. It therefore seems reasonable that I become a maintiner of
> 
> "a maintainer of"

Yes, of course. I'll correct it in v2.

  Paul

> 
> > the Xen code.
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > ---
> > Cc: Stefano Stabellini <sstabellini@kernel.org>
> > Cc: Anthony Perard <anthony.perard@citrix.com>
> > Cc: Paolo Bonzini <pbonzini@redhat.com>
> > ---
> >  MAINTAINERS | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 5871f035c3..0b668dd205 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -382,6 +382,7 @@ Guest CPU Cores (Xen):
> >  X86
> >  M: Stefano Stabellini <sstabellini@kernel.org>
> >  M: Anthony Perard <anthony.perard@citrix.com>
> > +M: Paul Durrant <paul.durrant@citrix.com>
> >  L: xen-devel@lists.xenproject.org
> >  S: Supported
> >  F: */xen*
> >
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 03/18] xen: introduce 'xen-qdisk'
  2018-11-21 15:11 ` [Qemu-devel] " Paul Durrant
  2018-11-29 16:05   ` Anthony PERARD
@ 2018-11-29 16:05   ` Anthony PERARD
  2018-12-04 15:20     ` Paul Durrant
  2018-12-04 15:20     ` Paul Durrant
  1 sibling, 2 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-11-29 16:05 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Kevin Wolf, Max Reitz,
	Stefano Stabellini

On Wed, Nov 21, 2018 at 03:11:56PM +0000, Paul Durrant wrote:
> This patch adds a new XenDevice: 'xen-qdisk' [1]. This will eventually
> replace the 'xen_disk' legacy PV backend but it is illustrative to build
> up the implementation incrementally, along with the XenBus/XenDevice
> framework. Subsequent patches will therefore add to this device's
> implementation as new features are added to the framework.
> 
> After this patch has been applied it is possible to instantiate a new
> 'xen-qdisk' device with a single 'vdev' parameter, which accepts values
> adhering to the Xen VBD naming scheme [2]. For example, a command-line
> instantiation of a xen-qdisk can be done with an argument similar to the
> following:
> 
> -device xen-qdisk,vdev=hda

That works when QEMU boot, but doing the same thing once the guest have
booted, via QMP, doesn't. Here is the result (tested in qmp-shell):

(QEMU) device_add driver=xen-qdisk vdev=hda
{
    "error": {
        "class": "GenericError", 
        "desc": "Bus 'xen-bus.0' does not support hotplugging"
    }
}

That's probably why I've asked about the hotplug capability on the
previous patch.

> The implementation of the vdev parameter formulates the appropriate VBD
> number for use in the PV protocol.
> 
> [1] The name 'qdisk' as always been the name given to the QEMU
>     implementation of the Xen PV block protocol backend implementation
> [2] http://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=docs/man/xen-vbd-interface.markdown.7

Maybe a link to the generated docs would be better:
https://xenbits.xen.org/docs/unstable/man/xen-vbd-interface.7.html

Also, it would be useful to have the same link in the source code.

> diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> new file mode 100644
> index 0000000000..72122073f7
> --- /dev/null
> +++ b/hw/block/xen-qdisk.c
[...]
> +static char *disk_to_vbd_name(unsigned int disk)
> +{
> +    unsigned int len = DIV_ROUND_UP(disk, 26);
> +    char *name = g_malloc0(len + 1);
> +
> +    do {
> +        name[len--] = 'a' + (disk % 26);
> +        disk /= 26;
> +    } while (disk != 0);
> +    assert(len == 0);
> +
> +    return name;
> +}

That function doesn't work.

For a simple xvdp, (so disk==15), it return "", I mean "\0p".

For a more complicated 'xvdbhwza', we have len == 22901. And the assert failed.

Maybe the recursing algo in libxl would be fine, with a buffer that is
big enough, and could probably be on the stack (in _get_vdev).

> +
> +    switch (vdev->type) {
> +    case XEN_QDISK_VDEV_TYPE_DP:
> +    case XEN_QDISK_VDEV_TYPE_XVD:
> +        if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) {
> +            vdev->number = (202 << 8) | (vdev->disk << 4) |
> +                vdev->partition;
> +        } else if (vdev->disk < (1 << 20) && vdev->partition < (1 << 8)) {
> +            vdev->number = (1 << 28) | (vdev->disk << 8) |
> +                vdev->partition;
> +        } else {
> +            goto invalid;
> +        }
> +        break;
> +
> +    case XEN_QDISK_VDEV_TYPE_HD:
> +        if ((vdev->disk == 0 || vdev->disk == 1) &&
> +            vdev->partition < (1 << 4)) {

I think that should be:

    vdev->partition < (1 << 6)

Because hd disk have 0..63 partitions.

> +            vdev->number = (3 << 8) | (vdev->disk << 6) | vdev->partition;
> +        } else if ((vdev->disk == 2 || vdev->disk == 3) &&
> +                   vdev->partition < (1 << 4)) {

same here.

> +            vdev->number = (22 << 8) | ((vdev->disk - 2) << 6) |
> +                vdev->partition;
> +        } else {
> +            goto invalid;
> +        }
> +        break;
> +
> +    case XEN_QDISK_VDEV_TYPE_SD:
> +        if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) {
> +            vdev->number = (8 << 8) | (vdev->disk << 4) | vdev->partition;
> +        } else {
> +            goto invalid;
> +        }
> +        break;
> +
> +    default:
> +        goto invalid;
> +    }
> +
> +    g_free(str);
> +    vdev->valid = true;
> +    return;
> +
> +invalid:
> +    error_setg(errp, "invalid virtual disk specifier");
> +    g_free(str);

:(, g_free is called twice.

maybe we could have:
    vdev->valid=true;
    out:
      if (!vdev->valid)
        error_setg(...);
      g_free;

> diff --git a/include/hw/xen/xen-qdisk.h b/include/hw/xen/xen-qdisk.h
> new file mode 100644
> index 0000000000..ade0866037
> --- /dev/null
> +++ b/include/hw/xen/xen-qdisk.h
> @@ -0,0 +1,38 @@
> +/*
> + * Copyright (c) Citrix Systems Inc.
> + * All rights reserved.
> + */
> +
> +#ifndef HW_XEN_QDISK_H
> +#define HW_XEN_QDISK_H
> +
> +#include "hw/xen/xen-bus.h"
> +
> +typedef enum XenQdiskVdevType {
> +    XEN_QDISK_VDEV_TYPE_DP,

Maybe we could set type_dp value to 1, so that, when vdev->type isn't
set, we can detect it later.


> +    XEN_QDISK_VDEV_TYPE_XVD,
> +    XEN_QDISK_VDEV_TYPE_HD,
> +    XEN_QDISK_VDEV_TYPE_SD,
> +    XEN_QDISK_VDEV_TYPE__MAX
> +} XenQdiskVdevType;

Thanks,

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 03/18] xen: introduce 'xen-qdisk'
  2018-11-21 15:11 ` [Qemu-devel] " Paul Durrant
@ 2018-11-29 16:05   ` Anthony PERARD
  2018-11-29 16:05   ` [Qemu-devel] " Anthony PERARD
  1 sibling, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-11-29 16:05 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, xen-devel

On Wed, Nov 21, 2018 at 03:11:56PM +0000, Paul Durrant wrote:
> This patch adds a new XenDevice: 'xen-qdisk' [1]. This will eventually
> replace the 'xen_disk' legacy PV backend but it is illustrative to build
> up the implementation incrementally, along with the XenBus/XenDevice
> framework. Subsequent patches will therefore add to this device's
> implementation as new features are added to the framework.
> 
> After this patch has been applied it is possible to instantiate a new
> 'xen-qdisk' device with a single 'vdev' parameter, which accepts values
> adhering to the Xen VBD naming scheme [2]. For example, a command-line
> instantiation of a xen-qdisk can be done with an argument similar to the
> following:
> 
> -device xen-qdisk,vdev=hda

That works when QEMU boot, but doing the same thing once the guest have
booted, via QMP, doesn't. Here is the result (tested in qmp-shell):

(QEMU) device_add driver=xen-qdisk vdev=hda
{
    "error": {
        "class": "GenericError", 
        "desc": "Bus 'xen-bus.0' does not support hotplugging"
    }
}

That's probably why I've asked about the hotplug capability on the
previous patch.

> The implementation of the vdev parameter formulates the appropriate VBD
> number for use in the PV protocol.
> 
> [1] The name 'qdisk' as always been the name given to the QEMU
>     implementation of the Xen PV block protocol backend implementation
> [2] http://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=docs/man/xen-vbd-interface.markdown.7

Maybe a link to the generated docs would be better:
https://xenbits.xen.org/docs/unstable/man/xen-vbd-interface.7.html

Also, it would be useful to have the same link in the source code.

> diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> new file mode 100644
> index 0000000000..72122073f7
> --- /dev/null
> +++ b/hw/block/xen-qdisk.c
[...]
> +static char *disk_to_vbd_name(unsigned int disk)
> +{
> +    unsigned int len = DIV_ROUND_UP(disk, 26);
> +    char *name = g_malloc0(len + 1);
> +
> +    do {
> +        name[len--] = 'a' + (disk % 26);
> +        disk /= 26;
> +    } while (disk != 0);
> +    assert(len == 0);
> +
> +    return name;
> +}

That function doesn't work.

For a simple xvdp, (so disk==15), it return "", I mean "\0p".

For a more complicated 'xvdbhwza', we have len == 22901. And the assert failed.

Maybe the recursing algo in libxl would be fine, with a buffer that is
big enough, and could probably be on the stack (in _get_vdev).

> +
> +    switch (vdev->type) {
> +    case XEN_QDISK_VDEV_TYPE_DP:
> +    case XEN_QDISK_VDEV_TYPE_XVD:
> +        if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) {
> +            vdev->number = (202 << 8) | (vdev->disk << 4) |
> +                vdev->partition;
> +        } else if (vdev->disk < (1 << 20) && vdev->partition < (1 << 8)) {
> +            vdev->number = (1 << 28) | (vdev->disk << 8) |
> +                vdev->partition;
> +        } else {
> +            goto invalid;
> +        }
> +        break;
> +
> +    case XEN_QDISK_VDEV_TYPE_HD:
> +        if ((vdev->disk == 0 || vdev->disk == 1) &&
> +            vdev->partition < (1 << 4)) {

I think that should be:

    vdev->partition < (1 << 6)

Because hd disk have 0..63 partitions.

> +            vdev->number = (3 << 8) | (vdev->disk << 6) | vdev->partition;
> +        } else if ((vdev->disk == 2 || vdev->disk == 3) &&
> +                   vdev->partition < (1 << 4)) {

same here.

> +            vdev->number = (22 << 8) | ((vdev->disk - 2) << 6) |
> +                vdev->partition;
> +        } else {
> +            goto invalid;
> +        }
> +        break;
> +
> +    case XEN_QDISK_VDEV_TYPE_SD:
> +        if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) {
> +            vdev->number = (8 << 8) | (vdev->disk << 4) | vdev->partition;
> +        } else {
> +            goto invalid;
> +        }
> +        break;
> +
> +    default:
> +        goto invalid;
> +    }
> +
> +    g_free(str);
> +    vdev->valid = true;
> +    return;
> +
> +invalid:
> +    error_setg(errp, "invalid virtual disk specifier");
> +    g_free(str);

:(, g_free is called twice.

maybe we could have:
    vdev->valid=true;
    out:
      if (!vdev->valid)
        error_setg(...);
      g_free;

> diff --git a/include/hw/xen/xen-qdisk.h b/include/hw/xen/xen-qdisk.h
> new file mode 100644
> index 0000000000..ade0866037
> --- /dev/null
> +++ b/include/hw/xen/xen-qdisk.h
> @@ -0,0 +1,38 @@
> +/*
> + * Copyright (c) Citrix Systems Inc.
> + * All rights reserved.
> + */
> +
> +#ifndef HW_XEN_QDISK_H
> +#define HW_XEN_QDISK_H
> +
> +#include "hw/xen/xen-bus.h"
> +
> +typedef enum XenQdiskVdevType {
> +    XEN_QDISK_VDEV_TYPE_DP,

Maybe we could set type_dp value to 1, so that, when vdev->type isn't
set, we can detect it later.


> +    XEN_QDISK_VDEV_TYPE_XVD,
> +    XEN_QDISK_VDEV_TYPE_HD,
> +    XEN_QDISK_VDEV_TYPE_SD,
> +    XEN_QDISK_VDEV_TYPE__MAX
> +} XenQdiskVdevType;

Thanks,

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 04/18] xen: create xenstore areas for XenDevice-s
  2018-11-21 15:11 ` [Qemu-devel] [PATCH 04/18] xen: create xenstore areas for XenDevice-s Paul Durrant
  2018-11-29 18:48   ` Anthony PERARD
@ 2018-11-29 18:48   ` Anthony PERARD
  2018-12-05 12:05     ` Paul Durrant
  2018-12-05 12:05     ` Paul Durrant
  1 sibling, 2 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-11-29 18:48 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Kevin Wolf, Max Reitz

On Wed, Nov 21, 2018 at 03:11:57PM +0000, Paul Durrant wrote:
> This patch adds a new source module, xen-bus-helper.c, which builds on
> basic libxenstore primitives to provide functions to create (setting
> permissions appropriately) and destroy xenstore areas, and functions to
> 'printf' and 'scanf' nodes therein. The main xen-bus code then uses
> these primitives [1] to initialize and destroy the frontend and backend
> areas for a XenDevice during realize and unrealize respectively.
> 
> The 'xen-qdisk' implementation is extended with a 'get_name' method that
> returns the VBD number. This number is reqired to 'name' the xenstore

                                         ^ required

> diff --git a/hw/xen/xen-bus-helper.c b/hw/xen/xen-bus-helper.c
> new file mode 100644
> index 0000000000..d9ee2ed6a0
> --- /dev/null
> +++ b/hw/xen/xen-bus-helper.c
[...]
> +void xs_node_destroy(struct xs_handle *xsh, const char *node)
> +{
> +    xs_rm(xsh, XBT_NULL, node);

We should check for error, and grab errno.

> +}
> +
> +void xs_node_vprintf(struct xs_handle *xsh, const char *node,
> +                     const char *key, const char *fmt, va_list ap)
> +{
> +    char *path, *value;
> +
> +    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
> +        g_strdup(key);

A comment would be helpful to findout how to use that function,
especialy the fact that with node="", we write to $key instead of
$node/$key.

> +    value = g_strdup_vprintf(fmt, ap);

Looks like g_vasprintf() would be better, since it returns the lenght as
well.

> +
> +    xs_write(xsh, XBT_NULL, path, value, strlen(value));

You should check for failures, and grab errno.

> +    g_free(value);
> +    g_free(path);
> +}
> +
> +int xs_node_vscanf(struct xs_handle *xsh, const char *node, const char *key,
> +                   const char *fmt, va_list ap)
> +{
> +    char *path, *value;
> +    int rc;
> +
> +    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
> +        g_strdup(key);
> +
> +    value = xs_read(xsh, XBT_NULL, path, NULL);

The xenstore.h isn't clear about failure of this function, it is
supposed to return a malloced value. Do we actually need to check if value
is NULL?

> +
> +    rc = value ? vsscanf(value, fmt, ap) : EOF;
> +
> +    free(value);
> +    g_free(path);
> +
> +    return rc;
> +}
> +
> diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> index dede2d914a..663aa8e117 100644
> --- a/hw/xen/xen-bus.c
> +++ b/hw/xen/xen-bus.c
[...]

> +static void xen_device_backend_destroy(XenDevice *xendev)
> +{
> +    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
> +
> +    if (!xendev->backend_path) {
> +        return;
> +    }
> +
> +    g_assert(xenbus->xsh);
> +
> +    xs_node_destroy(xenbus->xsh, xendev->backend_path);
> +    g_free(xendev->backend_path);

It would be nice to also set backend_path to NULL.

> diff --git a/include/hw/xen/xen-bus-helper.h b/include/hw/xen/xen-bus-helper.h
> new file mode 100644
> index 0000000000..53570650db
> --- /dev/null
> +++ b/include/hw/xen/xen-bus-helper.h
> @@ -0,0 +1,26 @@
> +/*
> + * Copyright (c) Citrix Systems Inc.
> + * All rights reserved.
> + */
> +
> +#ifndef HW_XEN_BUS_HELPER_H
> +#define HW_XEN_BUS_HELPER_H

That should probably include xen_common.h, to have `enum xenbus_state`,
`struct xs_handle`, ..

> +const char *xs_strstate(enum xenbus_state state);
> +
> +void xs_node_create(struct xs_handle *xsh, const char *node,
> +                    struct xs_permissions perms[],
> +                    unsigned int nr_perms, Error **errp);
> +void xs_node_destroy(struct xs_handle *xsh, const char *node);
> +
> +void xs_node_vprintf(struct xs_handle *xsh, const char *node,
> +                     const char *key, const char *fmt, va_list ap);
> +void xs_node_printf(struct xs_handle *xsh, const char *node, const char *key,
> +                    const char *fmt, ...);

This prototype needs GCC_FMT_ATTR(), that's the printf format
__attribute__.

> +
> +int xs_node_vscanf(struct xs_handle *xsh, const char *node, const char *key,
> +                   const char *fmt, va_list ap);
> +int xs_node_scanf(struct xs_handle *xsh, const char *node, const char *key,
> +                  const char *fmt, ...);

Maybe here as well.


-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 04/18] xen: create xenstore areas for XenDevice-s
  2018-11-21 15:11 ` [Qemu-devel] [PATCH 04/18] xen: create xenstore areas for XenDevice-s Paul Durrant
@ 2018-11-29 18:48   ` Anthony PERARD
  2018-11-29 18:48   ` [Qemu-devel] " Anthony PERARD
  1 sibling, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-11-29 18:48 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, xen-devel

On Wed, Nov 21, 2018 at 03:11:57PM +0000, Paul Durrant wrote:
> This patch adds a new source module, xen-bus-helper.c, which builds on
> basic libxenstore primitives to provide functions to create (setting
> permissions appropriately) and destroy xenstore areas, and functions to
> 'printf' and 'scanf' nodes therein. The main xen-bus code then uses
> these primitives [1] to initialize and destroy the frontend and backend
> areas for a XenDevice during realize and unrealize respectively.
> 
> The 'xen-qdisk' implementation is extended with a 'get_name' method that
> returns the VBD number. This number is reqired to 'name' the xenstore

                                         ^ required

> diff --git a/hw/xen/xen-bus-helper.c b/hw/xen/xen-bus-helper.c
> new file mode 100644
> index 0000000000..d9ee2ed6a0
> --- /dev/null
> +++ b/hw/xen/xen-bus-helper.c
[...]
> +void xs_node_destroy(struct xs_handle *xsh, const char *node)
> +{
> +    xs_rm(xsh, XBT_NULL, node);

We should check for error, and grab errno.

> +}
> +
> +void xs_node_vprintf(struct xs_handle *xsh, const char *node,
> +                     const char *key, const char *fmt, va_list ap)
> +{
> +    char *path, *value;
> +
> +    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
> +        g_strdup(key);

A comment would be helpful to findout how to use that function,
especialy the fact that with node="", we write to $key instead of
$node/$key.

> +    value = g_strdup_vprintf(fmt, ap);

Looks like g_vasprintf() would be better, since it returns the lenght as
well.

> +
> +    xs_write(xsh, XBT_NULL, path, value, strlen(value));

You should check for failures, and grab errno.

> +    g_free(value);
> +    g_free(path);
> +}
> +
> +int xs_node_vscanf(struct xs_handle *xsh, const char *node, const char *key,
> +                   const char *fmt, va_list ap)
> +{
> +    char *path, *value;
> +    int rc;
> +
> +    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
> +        g_strdup(key);
> +
> +    value = xs_read(xsh, XBT_NULL, path, NULL);

The xenstore.h isn't clear about failure of this function, it is
supposed to return a malloced value. Do we actually need to check if value
is NULL?

> +
> +    rc = value ? vsscanf(value, fmt, ap) : EOF;
> +
> +    free(value);
> +    g_free(path);
> +
> +    return rc;
> +}
> +
> diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> index dede2d914a..663aa8e117 100644
> --- a/hw/xen/xen-bus.c
> +++ b/hw/xen/xen-bus.c
[...]

> +static void xen_device_backend_destroy(XenDevice *xendev)
> +{
> +    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
> +
> +    if (!xendev->backend_path) {
> +        return;
> +    }
> +
> +    g_assert(xenbus->xsh);
> +
> +    xs_node_destroy(xenbus->xsh, xendev->backend_path);
> +    g_free(xendev->backend_path);

It would be nice to also set backend_path to NULL.

> diff --git a/include/hw/xen/xen-bus-helper.h b/include/hw/xen/xen-bus-helper.h
> new file mode 100644
> index 0000000000..53570650db
> --- /dev/null
> +++ b/include/hw/xen/xen-bus-helper.h
> @@ -0,0 +1,26 @@
> +/*
> + * Copyright (c) Citrix Systems Inc.
> + * All rights reserved.
> + */
> +
> +#ifndef HW_XEN_BUS_HELPER_H
> +#define HW_XEN_BUS_HELPER_H

That should probably include xen_common.h, to have `enum xenbus_state`,
`struct xs_handle`, ..

> +const char *xs_strstate(enum xenbus_state state);
> +
> +void xs_node_create(struct xs_handle *xsh, const char *node,
> +                    struct xs_permissions perms[],
> +                    unsigned int nr_perms, Error **errp);
> +void xs_node_destroy(struct xs_handle *xsh, const char *node);
> +
> +void xs_node_vprintf(struct xs_handle *xsh, const char *node,
> +                     const char *key, const char *fmt, va_list ap);
> +void xs_node_printf(struct xs_handle *xsh, const char *node, const char *key,
> +                    const char *fmt, ...);

This prototype needs GCC_FMT_ATTR(), that's the printf format
__attribute__.

> +
> +int xs_node_vscanf(struct xs_handle *xsh, const char *node, const char *key,
> +                   const char *fmt, va_list ap);
> +int xs_node_scanf(struct xs_handle *xsh, const char *node, const char *key,
> +                  const char *fmt, ...);

Maybe here as well.


-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 05/18] xen: add xenstore watcher infratructure
  2018-11-21 15:11 ` [Qemu-devel] [PATCH 05/18] xen: add xenstore watcher infratructure Paul Durrant
@ 2018-12-03 14:42   ` Anthony PERARD
  2018-12-05 15:24     ` Paul Durrant
  2018-12-05 15:24     ` Paul Durrant
  2018-12-03 14:42   ` Anthony PERARD
  1 sibling, 2 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-03 14:42 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Kevin Wolf, Max Reitz,
	Stefano Stabellini

On Wed, Nov 21, 2018 at 03:11:58PM +0000, Paul Durrant wrote:
> A Xen PV frontend communicates its state to the PV backend by writing to
> the 'state' key in the frontend area in xenstore. It is therefore
> necessary for a XenDevice implementation to be notified whenever the
> value of this key changes.
> 
> This patch adds code to do this as follows:
> 
> - an 'fd handler' is registered on the libxenstore handle which will be
>   triggered whenever a 'watch' event occurs
> - primitives are added to xen-bus-helper to add or remove watch events
> - a list of Notifier objects is added to XenBus to provide a mechanism
>   to call the appropriate 'watch handler' when its associated event
>   occurs
> 
> The xen-qisk implementation is extended with a 'frontend_changed' method,

"The xen-qdisk"

> which calls as-yet stub 'connect' and 'disconnect' functions when the
> relevant frontend state transitions occur. A subsequent patch will supply
> a full implementation for these functions.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> ---
> diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> index 0859643f7d..35f7b70480 100644
> --- a/hw/block/xen-qdisk.c
> +++ b/hw/block/xen-qdisk.c
> +static void xen_qdisk_frontend_changed(XenDevice *xendev,
> +                                       enum xenbus_state frontend_state,
> +                                       Error **errp)
> +{
> +    XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
> +    enum xenbus_state backend_state = xen_device_backend_get_state(xendev);
> +    Error *local_err = NULL;
> +
> +    switch (frontend_state) {
> +    case XenbusStateInitialised:
> +    case XenbusStateConnected:
> +        if (backend_state == XenbusStateConnected) {
> +            break;
> +        }
> +
> +        xen_qdisk_disconnect(qdiskdev, &error_fatal);

Do we want to crash (actually exit) QEMU when disconnect failed?

> +        xen_qdisk_connect(qdiskdev, &local_err);
> +        if (local_err) {
> +            error_propagate(errp, local_err);
> +            break;
> +        }
> +
> +        xen_device_backend_set_state(xendev, XenbusStateConnected);
> +        break;
> +
> +    case XenbusStateClosing:
> +        xen_device_backend_set_state(xendev, XenbusStateClosing);
> +        break;
> +
> +    case XenbusStateClosed:
> +        xen_qdisk_disconnect(qdiskdev, &error_fatal);
> +        xen_device_backend_set_state(xendev, XenbusStateClosed);
> +        break;
> +
> +    default:
> +        break;
> +    }
> +}
> +
> diff --git a/hw/xen/xen-bus-helper.c b/hw/xen/xen-bus-helper.c
> index d9ee2ed6a0..b44acc8047 100644
> --- a/hw/xen/xen-bus-helper.c
> +++ b/hw/xen/xen-bus-helper.c
> @@ -122,3 +122,31 @@ int xs_node_scanf(struct xs_handle *xsh, const char *node, const char *key,
>  
>      return rc;
>  }
> +
> +void xs_node_watch(struct xs_handle *xsh, const char *node, const char *key,
> +                   char *token, Error **errp)
> +{
> +    char *path;
> +
> +    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
> +        g_strdup(key);
> +
> +    if (!xs_watch(xsh, path, token)) {
> +        error_setg_errno(errp, errno, "failed to watch path '%s'", path);
> +    }
> +
> +    g_free(path);
> +}
> +
> +void xs_node_unwatch(struct xs_handle *xsh, const char *node,
> +                     const char *key, const char *token)
> +{
> +    char *path;
> +
> +    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
> +        g_strdup(key);
> +
> +    xs_unwatch(xsh, path, token);

I think we should check for error from xs_unwatch as well.

> +
> +    g_free(path);
> +}
> diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> index 663aa8e117..99988f8568 100644
> --- a/hw/xen/xen-bus.c
> +++ b/hw/xen/xen-bus.c
> +static XenWatch *xen_bus_add_watch(XenBus *xenbus, const char *node,
> +                                   const char *key, XenWatchHandler handler,
> +                                   void *opaque, Error **errp)
> +{
> +    XenWatch *watch = g_new0(XenWatch, 1);
> +    QemuUUID uuid;
> +    Error *local_err = NULL;
> +
> +    qemu_uuid_generate(&uuid);
> +    watch->token = qemu_uuid_unparse_strdup(&uuid);
> +
> +    trace_xen_bus_add_watch(node, key, watch->token);
> +
> +    watch->node = g_strdup(node);
> +    watch->key = g_strdup(key);
> +    watch->handler = handler;
> +    watch->opaque = opaque;
> +    watch->notifier.notify = watch_notify;
> +
> +    notifier_list_add(&xenbus->watch_notifiers, &watch->notifier);
> +
> +    xs_node_watch(xenbus->xsh, node, key, watch->token, &local_err);
> +
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +
> +        notifier_remove(&watch->notifier);
> +
> +        g_free(watch->token);
> +        g_free(watch->key);
> +        g_free(watch->node);
> +
> +        g_free(watch);

It would be better to have a function that will free/dispose of a
XenWatch, or maybe simply calling xen_bus_remove_watch here might be
enough.

> +        watch = NULL;

You could return NULL instead.

> +    }
> +
> +    return watch;
> +}
> +
> +static void xen_bus_remove_watch(XenBus *xenbus, XenWatch *watch)
> +{
> +    trace_xen_bus_remove_watch(watch->node, watch->key, watch->token);
> +
> +    xs_node_unwatch(xenbus->xsh, watch->node, watch->key, watch->token);
> +
> +    notifier_remove(&watch->notifier);
> +
> +    g_free(watch->token);
> +    g_free(watch->key);
> +    g_free(watch->node);
> +
> +    g_free(watch);
> +}

> +static void xen_bus_watch(void *opaque)
> +{
> +    XenBus *xenbus = opaque;
> +    char **v;
> +    const char *token;
> +    unsigned int n;
> +
> +    g_assert(xenbus->xsh);
> +
> +    v = xs_read_watch(xenbus->xsh, &n);

What is the n for?
Also, maybe you wanted to call xs_check_watch instead? (In a loop, until
EGAIN)

> +    if (!v) {
> +        return;
> +    }
> +
> +    token = v[XS_WATCH_TOKEN];
> +
> +    trace_xen_bus_watch(token);
> +
> +    notifier_list_notify(&xenbus->watch_notifiers, (void *)token);
> +
> +    free(v);
> +}
> +
>  static void xen_bus_realize(BusState *bus, Error **errp)
>  {
>      XenBus *xenbus = XEN_BUS(bus);
> @@ -230,12 +419,24 @@ static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
>          error_propagate(errp, local_err);
>          error_prepend(errp, "failed to create frontend: ");
>      }
> +
> +    xendev->frontend_state_watch =
> +        xen_bus_add_watch(xenbus, xendev->frontend_path, "state",
> +                          xen_device_frontend_changed, xendev, &local_err);

You can't reuse local_err here, *local_err must be null (It isn't
exactly written like this, but that what I understand from reading
qapi/error.h).

Maybe you meant to return when the previous function failed (call of
xs_node_create)?

> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        error_prepend(errp, "failed to watch frontend state: ");
> +    }
>  }

Thanks,

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 05/18] xen: add xenstore watcher infratructure
  2018-11-21 15:11 ` [Qemu-devel] [PATCH 05/18] xen: add xenstore watcher infratructure Paul Durrant
  2018-12-03 14:42   ` Anthony PERARD
@ 2018-12-03 14:42   ` Anthony PERARD
  1 sibling, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-03 14:42 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, xen-devel

On Wed, Nov 21, 2018 at 03:11:58PM +0000, Paul Durrant wrote:
> A Xen PV frontend communicates its state to the PV backend by writing to
> the 'state' key in the frontend area in xenstore. It is therefore
> necessary for a XenDevice implementation to be notified whenever the
> value of this key changes.
> 
> This patch adds code to do this as follows:
> 
> - an 'fd handler' is registered on the libxenstore handle which will be
>   triggered whenever a 'watch' event occurs
> - primitives are added to xen-bus-helper to add or remove watch events
> - a list of Notifier objects is added to XenBus to provide a mechanism
>   to call the appropriate 'watch handler' when its associated event
>   occurs
> 
> The xen-qisk implementation is extended with a 'frontend_changed' method,

"The xen-qdisk"

> which calls as-yet stub 'connect' and 'disconnect' functions when the
> relevant frontend state transitions occur. A subsequent patch will supply
> a full implementation for these functions.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> ---
> diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> index 0859643f7d..35f7b70480 100644
> --- a/hw/block/xen-qdisk.c
> +++ b/hw/block/xen-qdisk.c
> +static void xen_qdisk_frontend_changed(XenDevice *xendev,
> +                                       enum xenbus_state frontend_state,
> +                                       Error **errp)
> +{
> +    XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
> +    enum xenbus_state backend_state = xen_device_backend_get_state(xendev);
> +    Error *local_err = NULL;
> +
> +    switch (frontend_state) {
> +    case XenbusStateInitialised:
> +    case XenbusStateConnected:
> +        if (backend_state == XenbusStateConnected) {
> +            break;
> +        }
> +
> +        xen_qdisk_disconnect(qdiskdev, &error_fatal);

Do we want to crash (actually exit) QEMU when disconnect failed?

> +        xen_qdisk_connect(qdiskdev, &local_err);
> +        if (local_err) {
> +            error_propagate(errp, local_err);
> +            break;
> +        }
> +
> +        xen_device_backend_set_state(xendev, XenbusStateConnected);
> +        break;
> +
> +    case XenbusStateClosing:
> +        xen_device_backend_set_state(xendev, XenbusStateClosing);
> +        break;
> +
> +    case XenbusStateClosed:
> +        xen_qdisk_disconnect(qdiskdev, &error_fatal);
> +        xen_device_backend_set_state(xendev, XenbusStateClosed);
> +        break;
> +
> +    default:
> +        break;
> +    }
> +}
> +
> diff --git a/hw/xen/xen-bus-helper.c b/hw/xen/xen-bus-helper.c
> index d9ee2ed6a0..b44acc8047 100644
> --- a/hw/xen/xen-bus-helper.c
> +++ b/hw/xen/xen-bus-helper.c
> @@ -122,3 +122,31 @@ int xs_node_scanf(struct xs_handle *xsh, const char *node, const char *key,
>  
>      return rc;
>  }
> +
> +void xs_node_watch(struct xs_handle *xsh, const char *node, const char *key,
> +                   char *token, Error **errp)
> +{
> +    char *path;
> +
> +    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
> +        g_strdup(key);
> +
> +    if (!xs_watch(xsh, path, token)) {
> +        error_setg_errno(errp, errno, "failed to watch path '%s'", path);
> +    }
> +
> +    g_free(path);
> +}
> +
> +void xs_node_unwatch(struct xs_handle *xsh, const char *node,
> +                     const char *key, const char *token)
> +{
> +    char *path;
> +
> +    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
> +        g_strdup(key);
> +
> +    xs_unwatch(xsh, path, token);

I think we should check for error from xs_unwatch as well.

> +
> +    g_free(path);
> +}
> diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> index 663aa8e117..99988f8568 100644
> --- a/hw/xen/xen-bus.c
> +++ b/hw/xen/xen-bus.c
> +static XenWatch *xen_bus_add_watch(XenBus *xenbus, const char *node,
> +                                   const char *key, XenWatchHandler handler,
> +                                   void *opaque, Error **errp)
> +{
> +    XenWatch *watch = g_new0(XenWatch, 1);
> +    QemuUUID uuid;
> +    Error *local_err = NULL;
> +
> +    qemu_uuid_generate(&uuid);
> +    watch->token = qemu_uuid_unparse_strdup(&uuid);
> +
> +    trace_xen_bus_add_watch(node, key, watch->token);
> +
> +    watch->node = g_strdup(node);
> +    watch->key = g_strdup(key);
> +    watch->handler = handler;
> +    watch->opaque = opaque;
> +    watch->notifier.notify = watch_notify;
> +
> +    notifier_list_add(&xenbus->watch_notifiers, &watch->notifier);
> +
> +    xs_node_watch(xenbus->xsh, node, key, watch->token, &local_err);
> +
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +
> +        notifier_remove(&watch->notifier);
> +
> +        g_free(watch->token);
> +        g_free(watch->key);
> +        g_free(watch->node);
> +
> +        g_free(watch);

It would be better to have a function that will free/dispose of a
XenWatch, or maybe simply calling xen_bus_remove_watch here might be
enough.

> +        watch = NULL;

You could return NULL instead.

> +    }
> +
> +    return watch;
> +}
> +
> +static void xen_bus_remove_watch(XenBus *xenbus, XenWatch *watch)
> +{
> +    trace_xen_bus_remove_watch(watch->node, watch->key, watch->token);
> +
> +    xs_node_unwatch(xenbus->xsh, watch->node, watch->key, watch->token);
> +
> +    notifier_remove(&watch->notifier);
> +
> +    g_free(watch->token);
> +    g_free(watch->key);
> +    g_free(watch->node);
> +
> +    g_free(watch);
> +}

> +static void xen_bus_watch(void *opaque)
> +{
> +    XenBus *xenbus = opaque;
> +    char **v;
> +    const char *token;
> +    unsigned int n;
> +
> +    g_assert(xenbus->xsh);
> +
> +    v = xs_read_watch(xenbus->xsh, &n);

What is the n for?
Also, maybe you wanted to call xs_check_watch instead? (In a loop, until
EGAIN)

> +    if (!v) {
> +        return;
> +    }
> +
> +    token = v[XS_WATCH_TOKEN];
> +
> +    trace_xen_bus_watch(token);
> +
> +    notifier_list_notify(&xenbus->watch_notifiers, (void *)token);
> +
> +    free(v);
> +}
> +
>  static void xen_bus_realize(BusState *bus, Error **errp)
>  {
>      XenBus *xenbus = XEN_BUS(bus);
> @@ -230,12 +419,24 @@ static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
>          error_propagate(errp, local_err);
>          error_prepend(errp, "failed to create frontend: ");
>      }
> +
> +    xendev->frontend_state_watch =
> +        xen_bus_add_watch(xenbus, xendev->frontend_path, "state",
> +                          xen_device_frontend_changed, xendev, &local_err);

You can't reuse local_err here, *local_err must be null (It isn't
exactly written like this, but that what I understand from reading
qapi/error.h).

Maybe you meant to return when the previous function failed (call of
xs_node_create)?

> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        error_prepend(errp, "failed to watch frontend state: ");
> +    }
>  }

Thanks,

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 06/18] xen: add grant table interface for XenDevice-s
  2018-11-21 15:11   ` Paul Durrant
@ 2018-12-03 15:45     ` Anthony PERARD
  -1 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-03 15:45 UTC (permalink / raw)
  To: Paul Durrant; +Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini

On Wed, Nov 21, 2018 at 03:11:59PM +0000, Paul Durrant wrote:
> The legacy PV backend infrastructure provides functions to map, unmap and
> copy pages granted by frontends. Similar functionality will be required
> by XenDevice implementations so this patch adds the necessary support.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> ---
> +typedef struct XenDeviceGrantCopySegment {
> +    union {
> +        void *virt;
> +        struct {
> +            uint32_t ref;
> +            off_t offset;
> +        } foreign;
> +    } source, dest;

Why is there a union between `source` and `dest`, I don't see any way
(another field) to distinguish which is which. Can't we have a
segment without `source`/`dest`? It mimic the
xengnttab_grant_copy_segment_t but that doesn't seems very useful as it
doesn't really prevent mistake.

> +    size_t len;
> +} XenDeviceGrantCopySegment;

Anyway, it's not very important:

Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>

Thanks,

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 06/18] xen: add grant table interface for XenDevice-s
@ 2018-12-03 15:45     ` Anthony PERARD
  0 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-03 15:45 UTC (permalink / raw)
  To: Paul Durrant; +Cc: xen-devel, Stefano Stabellini, qemu-devel, qemu-block

On Wed, Nov 21, 2018 at 03:11:59PM +0000, Paul Durrant wrote:
> The legacy PV backend infrastructure provides functions to map, unmap and
> copy pages granted by frontends. Similar functionality will be required
> by XenDevice implementations so this patch adds the necessary support.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> ---
> +typedef struct XenDeviceGrantCopySegment {
> +    union {
> +        void *virt;
> +        struct {
> +            uint32_t ref;
> +            off_t offset;
> +        } foreign;
> +    } source, dest;

Why is there a union between `source` and `dest`, I don't see any way
(another field) to distinguish which is which. Can't we have a
segment without `source`/`dest`? It mimic the
xengnttab_grant_copy_segment_t but that doesn't seems very useful as it
doesn't really prevent mistake.

> +    size_t len;
> +} XenDeviceGrantCopySegment;

Anyway, it's not very important:

Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>

Thanks,

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 07/18] xen: add event channel interface for XenDevice-s
  2018-11-21 15:12 ` [Qemu-devel] " Paul Durrant
@ 2018-12-03 16:24     ` Anthony PERARD
  0 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-03 16:24 UTC (permalink / raw)
  To: Paul Durrant; +Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini

On Wed, Nov 21, 2018 at 03:12:00PM +0000, Paul Durrant wrote:
> The legacy PV backend infrastructure provides functions to bind, unbind
> and send notifications to event channnels. Similar functionality will be
> required by XenDevice implementations so this patch adds the necessary
> support.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> ---
> +void xen_device_notify_event_channel(XenDevice *xendev,
> +                                     XenEventChannel *channel)
> +{
> +    xenevtchn_notify(xendev->xeh, channel->local_port);

Since xenevtchn_notify and xenevtchn_unbind below can fail, it will be
nice to check for error and grab the errno.

Users of xen_device_notify_event_channel could simply ignore the error,
or just print a warning/error and continue
(warn_report_err/error_report_err).

> +}
> +
> +void xen_device_unbind_event_channel(XenDevice *xendev,
> +                                     XenEventChannel *channel)
> +{
> +    notifier_remove(&channel->notifier);
> +
> +    xenevtchn_unbind(xendev->xeh, channel->local_port);
> +
> +    g_free(channel);
> +}
> +


> +static void xen_device_event(void *opaque)
> +{
> +    XenDevice *xendev = opaque;
> +    unsigned long port = xenevtchn_pending(xendev->xeh);
> +
> +    notifier_list_notify(&xendev->event_notifiers, (void *)port);

I wonder if a Notifier is a good fit for XenDevice, like here for the
events or the xenstore watches in previous patches, as NotifierLists are
normaly used when every Notifiers want to do something, but here there
is only one that is going to do something. But I guess it might not be
much better to write a loop in here rather than use the one in
notifier_list_notify.

> +
> +    xenevtchn_unmask(xendev->xeh, port);
> +}
> +

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 07/18] xen: add event channel interface for XenDevice-s
@ 2018-12-03 16:24     ` Anthony PERARD
  0 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-03 16:24 UTC (permalink / raw)
  To: Paul Durrant; +Cc: xen-devel, Stefano Stabellini, qemu-devel, qemu-block

On Wed, Nov 21, 2018 at 03:12:00PM +0000, Paul Durrant wrote:
> The legacy PV backend infrastructure provides functions to bind, unbind
> and send notifications to event channnels. Similar functionality will be
> required by XenDevice implementations so this patch adds the necessary
> support.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> ---
> +void xen_device_notify_event_channel(XenDevice *xendev,
> +                                     XenEventChannel *channel)
> +{
> +    xenevtchn_notify(xendev->xeh, channel->local_port);

Since xenevtchn_notify and xenevtchn_unbind below can fail, it will be
nice to check for error and grab the errno.

Users of xen_device_notify_event_channel could simply ignore the error,
or just print a warning/error and continue
(warn_report_err/error_report_err).

> +}
> +
> +void xen_device_unbind_event_channel(XenDevice *xendev,
> +                                     XenEventChannel *channel)
> +{
> +    notifier_remove(&channel->notifier);
> +
> +    xenevtchn_unbind(xendev->xeh, channel->local_port);
> +
> +    g_free(channel);
> +}
> +


> +static void xen_device_event(void *opaque)
> +{
> +    XenDevice *xendev = opaque;
> +    unsigned long port = xenevtchn_pending(xendev->xeh);
> +
> +    notifier_list_notify(&xendev->event_notifiers, (void *)port);

I wonder if a Notifier is a good fit for XenDevice, like here for the
events or the xenstore watches in previous patches, as NotifierLists are
normaly used when every Notifiers want to do something, but here there
is only one that is going to do something. But I guess it might not be
much better to write a loop in here rather than use the one in
notifier_list_notify.

> +
> +    xenevtchn_unmask(xendev->xeh, port);
> +}
> +

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 08/18] xen: duplicate xen_disk.c as basis of dataplane/xen-qdisk.c
  2018-11-21 15:12   ` Paul Durrant
@ 2018-12-03 16:35     ` Anthony PERARD
  -1 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-03 16:35 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Stefan Hajnoczi, Kevin Wolf, Max Reitz

On Wed, Nov 21, 2018 at 03:12:01PM +0000, Paul Durrant wrote:
> The new xen-qdisk XenDevice implementation requires the same core dataplane
> as the legacy xen_disk implementation it will eventually replace. This
> patch therefore copies the legacy xen_disk.c source module into a new
> dataplane/xen-qdisk.c source module as the basis for the new dataplane and
> adjusts the MAINTAINERS file accordingly.
> 
> NOTE: The duplicated code is not yet built. It is simply put into place by
>       this patch (just fixing style violations) such that the
>       modifications that will need to be made to the code are not
>       conflated with code movement, thus making review harder.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

Acked-by: Anthony PERARD <anthony.perard@citrix.com>

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 08/18] xen: duplicate xen_disk.c as basis of dataplane/xen-qdisk.c
@ 2018-12-03 16:35     ` Anthony PERARD
  0 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-03 16:35 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, Stefan Hajnoczi, xen-devel

On Wed, Nov 21, 2018 at 03:12:01PM +0000, Paul Durrant wrote:
> The new xen-qdisk XenDevice implementation requires the same core dataplane
> as the legacy xen_disk implementation it will eventually replace. This
> patch therefore copies the legacy xen_disk.c source module into a new
> dataplane/xen-qdisk.c source module as the basis for the new dataplane and
> adjusts the MAINTAINERS file accordingly.
> 
> NOTE: The duplicated code is not yet built. It is simply put into place by
>       this patch (just fixing style violations) such that the
>       modifications that will need to be made to the code are not
>       conflated with code movement, thus making review harder.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

Acked-by: Anthony PERARD <anthony.perard@citrix.com>

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 08/18] xen: duplicate xen_disk.c as basis of dataplane/xen-qdisk.c
  2018-12-03 16:35     ` Anthony PERARD
@ 2018-12-03 16:42       ` Anthony PERARD
  -1 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-03 16:42 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Stefan Hajnoczi, Kevin Wolf, Max Reitz

On Mon, Dec 03, 2018 at 04:35:39PM +0000, Anthony PERARD wrote:
> On Wed, Nov 21, 2018 at 03:12:01PM +0000, Paul Durrant wrote:
> > The new xen-qdisk XenDevice implementation requires the same core dataplane
> > as the legacy xen_disk implementation it will eventually replace. This
> > patch therefore copies the legacy xen_disk.c source module into a new
> > dataplane/xen-qdisk.c source module as the basis for the new dataplane and
> > adjusts the MAINTAINERS file accordingly.
> > 
> > NOTE: The duplicated code is not yet built. It is simply put into place by
> >       this patch (just fixing style violations) such that the
> >       modifications that will need to be made to the code are not
> >       conflated with code movement, thus making review harder.
> > 
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> 
> Acked-by: Anthony PERARD <anthony.perard@citrix.com>

FYI, You can use --find-copies-harder when sending this kind of patch,
it will show the diff between the old file and the new file, even if the
old file is still around ;-).

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 08/18] xen: duplicate xen_disk.c as basis of dataplane/xen-qdisk.c
@ 2018-12-03 16:42       ` Anthony PERARD
  0 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-03 16:42 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, Stefan Hajnoczi, xen-devel

On Mon, Dec 03, 2018 at 04:35:39PM +0000, Anthony PERARD wrote:
> On Wed, Nov 21, 2018 at 03:12:01PM +0000, Paul Durrant wrote:
> > The new xen-qdisk XenDevice implementation requires the same core dataplane
> > as the legacy xen_disk implementation it will eventually replace. This
> > patch therefore copies the legacy xen_disk.c source module into a new
> > dataplane/xen-qdisk.c source module as the basis for the new dataplane and
> > adjusts the MAINTAINERS file accordingly.
> > 
> > NOTE: The duplicated code is not yet built. It is simply put into place by
> >       this patch (just fixing style violations) such that the
> >       modifications that will need to be made to the code are not
> >       conflated with code movement, thus making review harder.
> > 
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> 
> Acked-by: Anthony PERARD <anthony.perard@citrix.com>

FYI, You can use --find-copies-harder when sending this kind of patch,
it will show the diff between the old file and the new file, even if the
old file is still around ;-).

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 09/18] xen: remove unnecessary code from dataplane/xen-qdisk.c
  2018-11-21 15:12   ` Paul Durrant
@ 2018-12-03 16:58     ` Anthony PERARD
  -1 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-03 16:58 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Stefan Hajnoczi, Kevin Wolf, Max Reitz

On Wed, Nov 21, 2018 at 03:12:02PM +0000, Paul Durrant wrote:
> Not all of the code duplicated from xen_disk.c is required as the basis for
> the new dataplane implementation so this patch removes extraneous code,
> along with the legacy #includes and calls to the legacy xen_pv_printf()
> function. Error messages are changed to be reported using error_report().
> 
> NOTE: The code is still not yet built. Further transformations will be
>       required to make it correctly interface to the new XenBus/XenDevice
>       framework. They will be delivered in a subsequent patch.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> ---
> diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-qdisk.c
> index 9fae50534e..8e4368e7af 100644
> --- a/hw/block/dataplane/xen-qdisk.c
> +++ b/hw/block/dataplane/xen-qdisk.c
> @@ -1,45 +1,10 @@
>  /*
> - *  xen paravirt block device backend
> + * Copyright (c) Citrix Systems Inc.
> + * All rights reserved.
>   *
> - *  (c) Gerd Hoffmann <kraxel@redhat.com>
> - *
> - *  This program is free software; you can redistribute it and/or modify
> - *  it under the terms of the GNU General Public License as published by
> - *  the Free Software Foundation; under version 2 of the License.
> - *
> - *  This program is distributed in the hope that it will be useful,
> - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - *  GNU General Public License for more details.
> - *
> - *  You should have received a copy of the GNU General Public License along
> - *  with this program; if not, see <http://www.gnu.org/licenses/>.
> - *
> - *  Contributions after 2012-01-13 are licensed under the terms of the
> - *  GNU GPL, version 2 or (at your option) any later version.
> + * Based on original code (c) Gerd Hoffmann <kraxel@redhat.com>
>   */

Once this license boilerplate is kept unchange, beside the extra
Copyright line, then:

Acked-by: Anthony PERARD <anthony.perard@citrix.com>

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 09/18] xen: remove unnecessary code from dataplane/xen-qdisk.c
@ 2018-12-03 16:58     ` Anthony PERARD
  0 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-03 16:58 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, Stefan Hajnoczi, xen-devel

On Wed, Nov 21, 2018 at 03:12:02PM +0000, Paul Durrant wrote:
> Not all of the code duplicated from xen_disk.c is required as the basis for
> the new dataplane implementation so this patch removes extraneous code,
> along with the legacy #includes and calls to the legacy xen_pv_printf()
> function. Error messages are changed to be reported using error_report().
> 
> NOTE: The code is still not yet built. Further transformations will be
>       required to make it correctly interface to the new XenBus/XenDevice
>       framework. They will be delivered in a subsequent patch.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> ---
> diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-qdisk.c
> index 9fae50534e..8e4368e7af 100644
> --- a/hw/block/dataplane/xen-qdisk.c
> +++ b/hw/block/dataplane/xen-qdisk.c
> @@ -1,45 +1,10 @@
>  /*
> - *  xen paravirt block device backend
> + * Copyright (c) Citrix Systems Inc.
> + * All rights reserved.
>   *
> - *  (c) Gerd Hoffmann <kraxel@redhat.com>
> - *
> - *  This program is free software; you can redistribute it and/or modify
> - *  it under the terms of the GNU General Public License as published by
> - *  the Free Software Foundation; under version 2 of the License.
> - *
> - *  This program is distributed in the hope that it will be useful,
> - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - *  GNU General Public License for more details.
> - *
> - *  You should have received a copy of the GNU General Public License along
> - *  with this program; if not, see <http://www.gnu.org/licenses/>.
> - *
> - *  Contributions after 2012-01-13 are licensed under the terms of the
> - *  GNU GPL, version 2 or (at your option) any later version.
> + * Based on original code (c) Gerd Hoffmann <kraxel@redhat.com>
>   */

Once this license boilerplate is kept unchange, beside the extra
Copyright line, then:

Acked-by: Anthony PERARD <anthony.perard@citrix.com>

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 10/18] xen: add header and build dataplane/xen-qdisk.c
  2018-11-21 15:12   ` Paul Durrant
  (?)
  (?)
@ 2018-12-03 18:09   ` Anthony PERARD
  2018-12-05 17:31     ` Paul Durrant
  2018-12-05 17:31     ` [Qemu-devel] " Paul Durrant
  -1 siblings, 2 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-03 18:09 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Stefan Hajnoczi, Kevin Wolf,
	Max Reitz, Stefano Stabellini

On Wed, Nov 21, 2018 at 03:12:03PM +0000, Paul Durrant wrote:
> This patch adds the transformations necessary to get dataplane/xen-qdisk.c
> to build against the new XenBus/XenDevice framework. MAINTAINERS is also
> updated due to the introduction of dataplane/xen-qdisk.h.
> 
> NOTE: Existing data structure names are retained for the moment. These will
>       be modified by subsequent patches. A typedef for XenQdiskDataPlane
>       has been added to the header (based on the old struct XenBlkDev name
>       for the moment) so that the old names don't need to leak out of the
>       dataplane code.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> ---
> diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-qdisk.c
> index 8e4368e7af..b075aa975d 100644
> --- a/hw/block/dataplane/xen-qdisk.c
> +++ b/hw/block/dataplane/xen-qdisk.c
> @@ -5,65 +5,56 @@
>   * Based on original code (c) Gerd Hoffmann <kraxel@redhat.com>
>   */
>  
> +#include "qemu/osdep.h"
> +#include "qemu/error-report.h"
> +#include "qapi/error.h"
> +#include "hw/hw.h"
> +#include "hw/xen/xen.h"

xen.h isn't needed, xen_common.h should be enough.

> +#include "hw/xen/xen_common.h"
> +#include "hw/block/block.h"

block.h isn't needed, block-backend.h should be enough.

> +#include "hw/block/xen_blkif.h"
> +#include "sysemu/blockdev.h"

blockdev.h doesn't seems to be used.

> +#include "sysemu/block-backend.h"
> +#include "sysemu/iothread.h"
> +#include "xen-qdisk.h"
> +
> @@ -227,20 +219,24 @@ static int ioreq_grant_copy(struct ioreq *ioreq)
>                  file_blk;
>              segs[i].dest.virt = virt;
>          }
> -        segs[i].len = (ioreq->req.seg[i].last_sect
> -                       - ioreq->req.seg[i].first_sect + 1) * file_blk;
> +        segs[i].len = (ioreq->req.seg[i].last_sect -
> +                       ioreq->req.seg[i].first_sect + 1) * file_blk;
>          virt += segs[i].len;
>      }
>  
> -    rc = xen_be_copy_grant_refs(xendev, to_domain, segs, count);
> +    xen_device_copy_grant_refs(xendev, to_domain, segs, count, &local_err);
> +
> +    if (local_err) {
> +        const char *msg = error_get_pretty(local_err);
> +
> +        error_report("failed to copy data: %s", msg);
> +        error_free(local_err);

You can do the  following instead:
    error_prepend(local_err, "failed to copy data: ")
    error_report_err(local_err);

> +void xen_qdisk_dataplane_start(struct XenBlkDev *blkdev,
> +                               const unsigned int ring_ref[],
> +                               unsigned int nr_ring_ref,
> +                               unsigned int event_channel,
> +                               unsigned int protocol)
>  {
> -    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
> +    XenDevice *xendev = blkdev->xendev;
> +    unsigned int ring_size;
> +    unsigned int i;
>  
> -    qemu_bh_schedule(blkdev->bh);
> +    blkdev->nr_ring_ref = nr_ring_ref;
> +    blkdev->ring_ref = g_new(unsigned int, nr_ring_ref);
> +
> +    for (i = 0; i < nr_ring_ref; i++) {
> +        blkdev->ring_ref[i] = ring_ref[i];
> +    }
> +
> +    blkdev->protocol = protocol;
> +
> +    ring_size = XC_PAGE_SIZE * blkdev->nr_ring_ref;
> +    switch (blkdev->protocol) {
> +    case BLKIF_PROTOCOL_NATIVE:
> +    {
> +        blkdev->max_requests = __CONST_RING_SIZE(blkif, ring_size);
> +        break;
> +    }
> +    case BLKIF_PROTOCOL_X86_32:
> +    {
> +        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_32, ring_size);
> +        break;
> +    }
> +    case BLKIF_PROTOCOL_X86_64:
> +    {
> +        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_64, ring_size);
> +        break;
> +    }
> +    default:
> +        assert(false);
> +        break;

This should return rather than keep going.
And maybe set an Error that could be added to the parameter of the
function.

> +    }
> +
> +    xen_device_set_max_grant_refs(xendev, blkdev->nr_ring_ref,
> +                                  &error_fatal);

Do we really want to exit() here if an error happen, rather than let the
caller know? (Same question for other uses of error_fatal.)

> diff --git a/hw/block/dataplane/xen-qdisk.h b/hw/block/dataplane/xen-qdisk.h
> new file mode 100644
> index 0000000000..16bcd500bf
> --- /dev/null
> +++ b/hw/block/dataplane/xen-qdisk.h
> @@ -0,0 +1,25 @@
> +/*
> + * Copyright (c) Citrix Systems Inc.
> + * All rights reserved.
> + */
> +
> +#ifndef HW_BLOCK_DATAPLANE_QDISK_H
> +#define HW_BLOCK_DATAPLANE_QDISK_H
> +
> +#include "hw/xen/xen-bus.h"
> +#include "sysemu/iothread.h"

I would add #include "hw/block/block.h" since it includes the definition
of BlockConf.

> +
> +typedef struct XenBlkDev XenQdiskDataPlane;
> +
> +XenQdiskDataPlane *xen_qdisk_dataplane_create(XenDevice *xendev,
> +                                              BlockConf *conf,
> +                                              IOThread *iothread);

Thanks,

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 10/18] xen: add header and build dataplane/xen-qdisk.c
  2018-11-21 15:12   ` Paul Durrant
  (?)
@ 2018-12-03 18:09   ` Anthony PERARD
  -1 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-03 18:09 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, Stefan Hajnoczi, xen-devel

On Wed, Nov 21, 2018 at 03:12:03PM +0000, Paul Durrant wrote:
> This patch adds the transformations necessary to get dataplane/xen-qdisk.c
> to build against the new XenBus/XenDevice framework. MAINTAINERS is also
> updated due to the introduction of dataplane/xen-qdisk.h.
> 
> NOTE: Existing data structure names are retained for the moment. These will
>       be modified by subsequent patches. A typedef for XenQdiskDataPlane
>       has been added to the header (based on the old struct XenBlkDev name
>       for the moment) so that the old names don't need to leak out of the
>       dataplane code.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> ---
> diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-qdisk.c
> index 8e4368e7af..b075aa975d 100644
> --- a/hw/block/dataplane/xen-qdisk.c
> +++ b/hw/block/dataplane/xen-qdisk.c
> @@ -5,65 +5,56 @@
>   * Based on original code (c) Gerd Hoffmann <kraxel@redhat.com>
>   */
>  
> +#include "qemu/osdep.h"
> +#include "qemu/error-report.h"
> +#include "qapi/error.h"
> +#include "hw/hw.h"
> +#include "hw/xen/xen.h"

xen.h isn't needed, xen_common.h should be enough.

> +#include "hw/xen/xen_common.h"
> +#include "hw/block/block.h"

block.h isn't needed, block-backend.h should be enough.

> +#include "hw/block/xen_blkif.h"
> +#include "sysemu/blockdev.h"

blockdev.h doesn't seems to be used.

> +#include "sysemu/block-backend.h"
> +#include "sysemu/iothread.h"
> +#include "xen-qdisk.h"
> +
> @@ -227,20 +219,24 @@ static int ioreq_grant_copy(struct ioreq *ioreq)
>                  file_blk;
>              segs[i].dest.virt = virt;
>          }
> -        segs[i].len = (ioreq->req.seg[i].last_sect
> -                       - ioreq->req.seg[i].first_sect + 1) * file_blk;
> +        segs[i].len = (ioreq->req.seg[i].last_sect -
> +                       ioreq->req.seg[i].first_sect + 1) * file_blk;
>          virt += segs[i].len;
>      }
>  
> -    rc = xen_be_copy_grant_refs(xendev, to_domain, segs, count);
> +    xen_device_copy_grant_refs(xendev, to_domain, segs, count, &local_err);
> +
> +    if (local_err) {
> +        const char *msg = error_get_pretty(local_err);
> +
> +        error_report("failed to copy data: %s", msg);
> +        error_free(local_err);

You can do the  following instead:
    error_prepend(local_err, "failed to copy data: ")
    error_report_err(local_err);

> +void xen_qdisk_dataplane_start(struct XenBlkDev *blkdev,
> +                               const unsigned int ring_ref[],
> +                               unsigned int nr_ring_ref,
> +                               unsigned int event_channel,
> +                               unsigned int protocol)
>  {
> -    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
> +    XenDevice *xendev = blkdev->xendev;
> +    unsigned int ring_size;
> +    unsigned int i;
>  
> -    qemu_bh_schedule(blkdev->bh);
> +    blkdev->nr_ring_ref = nr_ring_ref;
> +    blkdev->ring_ref = g_new(unsigned int, nr_ring_ref);
> +
> +    for (i = 0; i < nr_ring_ref; i++) {
> +        blkdev->ring_ref[i] = ring_ref[i];
> +    }
> +
> +    blkdev->protocol = protocol;
> +
> +    ring_size = XC_PAGE_SIZE * blkdev->nr_ring_ref;
> +    switch (blkdev->protocol) {
> +    case BLKIF_PROTOCOL_NATIVE:
> +    {
> +        blkdev->max_requests = __CONST_RING_SIZE(blkif, ring_size);
> +        break;
> +    }
> +    case BLKIF_PROTOCOL_X86_32:
> +    {
> +        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_32, ring_size);
> +        break;
> +    }
> +    case BLKIF_PROTOCOL_X86_64:
> +    {
> +        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_64, ring_size);
> +        break;
> +    }
> +    default:
> +        assert(false);
> +        break;

This should return rather than keep going.
And maybe set an Error that could be added to the parameter of the
function.

> +    }
> +
> +    xen_device_set_max_grant_refs(xendev, blkdev->nr_ring_ref,
> +                                  &error_fatal);

Do we really want to exit() here if an error happen, rather than let the
caller know? (Same question for other uses of error_fatal.)

> diff --git a/hw/block/dataplane/xen-qdisk.h b/hw/block/dataplane/xen-qdisk.h
> new file mode 100644
> index 0000000000..16bcd500bf
> --- /dev/null
> +++ b/hw/block/dataplane/xen-qdisk.h
> @@ -0,0 +1,25 @@
> +/*
> + * Copyright (c) Citrix Systems Inc.
> + * All rights reserved.
> + */
> +
> +#ifndef HW_BLOCK_DATAPLANE_QDISK_H
> +#define HW_BLOCK_DATAPLANE_QDISK_H
> +
> +#include "hw/xen/xen-bus.h"
> +#include "sysemu/iothread.h"

I would add #include "hw/block/block.h" since it includes the definition
of BlockConf.

> +
> +typedef struct XenBlkDev XenQdiskDataPlane;
> +
> +XenQdiskDataPlane *xen_qdisk_dataplane_create(XenDevice *xendev,
> +                                              BlockConf *conf,
> +                                              IOThread *iothread);

Thanks,

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 11/18] xen: remove 'XenBlkDev' and 'blkdev' names from dataplane/xen-qdisk
  2018-11-21 15:12 ` [Qemu-devel] " Paul Durrant
  2018-12-04 11:05   ` Anthony PERARD
@ 2018-12-04 11:05   ` Anthony PERARD
  1 sibling, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-04 11:05 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Stefan Hajnoczi, Kevin Wolf, Max Reitz

On Wed, Nov 21, 2018 at 03:12:04PM +0000, Paul Durrant wrote:
> This is a purely cosmetic patch that substitutes the old 'struct XenBlkDev'
> name with 'XenQdiskDataPlane' and 'blkdev' field/variable names with
> 'dataplane', and then does necessary fix-up to adhere to coding style.
> 
> No functional change.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

Acked-by: Anthony PERARD <anthony.perard@citrix.com>

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 11/18] xen: remove 'XenBlkDev' and 'blkdev' names from dataplane/xen-qdisk
  2018-11-21 15:12 ` [Qemu-devel] " Paul Durrant
@ 2018-12-04 11:05   ` Anthony PERARD
  2018-12-04 11:05   ` [Qemu-devel] " Anthony PERARD
  1 sibling, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-04 11:05 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, Stefan Hajnoczi, xen-devel

On Wed, Nov 21, 2018 at 03:12:04PM +0000, Paul Durrant wrote:
> This is a purely cosmetic patch that substitutes the old 'struct XenBlkDev'
> name with 'XenQdiskDataPlane' and 'blkdev' field/variable names with
> 'dataplane', and then does necessary fix-up to adhere to coding style.
> 
> No functional change.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

Acked-by: Anthony PERARD <anthony.perard@citrix.com>

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 12/18] xen: remove 'ioreq' struct/varable/field names from dataplane/xen-qdisk.c
  2018-11-21 15:12   ` Paul Durrant
  (?)
  (?)
@ 2018-12-04 11:34   ` Anthony PERARD
  -1 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-04 11:34 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Stefan Hajnoczi,
	Stefano Stabellini, Kevin Wolf, Max Reitz

On Wed, Nov 21, 2018 at 03:12:05PM +0000, Paul Durrant wrote:
> This is a purely cosmetic patch that purges the name 'ioreq' from struct,
> variable and field names. (This name has been problematic for a long time
> as 'ioreq' is the name used for generic I/O requests coming from Xen).
> The patch replaces 'struct ioreq' with a new 'XenQdiskRequest' type and
> 'ioreq' field/variable names with 'request', and then does necessary
> fix-up to adhere to coding style.
> 
> Function names are not modified by this patch. Yhey will be dealt with in

s/Yhey/They/

> a subsequent patch.
> 
> No functional change.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

Acked-by: Anthony PERARD <anthony.perard@citrix.com>

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 12/18] xen: remove 'ioreq' struct/varable/field names from dataplane/xen-qdisk.c
  2018-11-21 15:12   ` Paul Durrant
  (?)
@ 2018-12-04 11:34   ` Anthony PERARD
  -1 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-04 11:34 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, Stefan Hajnoczi, xen-devel

On Wed, Nov 21, 2018 at 03:12:05PM +0000, Paul Durrant wrote:
> This is a purely cosmetic patch that purges the name 'ioreq' from struct,
> variable and field names. (This name has been problematic for a long time
> as 'ioreq' is the name used for generic I/O requests coming from Xen).
> The patch replaces 'struct ioreq' with a new 'XenQdiskRequest' type and
> 'ioreq' field/variable names with 'request', and then does necessary
> fix-up to adhere to coding style.
> 
> Function names are not modified by this patch. Yhey will be dealt with in

s/Yhey/They/

> a subsequent patch.
> 
> No functional change.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

Acked-by: Anthony PERARD <anthony.perard@citrix.com>

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 13/18] xen: purge 'blk' and 'ioreq' from function names in dataplane/xen-qdisk.c
  2018-11-21 15:12   ` Paul Durrant
@ 2018-12-04 12:10     ` Anthony PERARD
  -1 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-04 12:10 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Stefan Hajnoczi, Kevin Wolf, Max Reitz

On Wed, Nov 21, 2018 at 03:12:06PM +0000, Paul Durrant wrote:
> This is a purely cosmetic patch that purges remaining use of 'blk' and
> 'ioreq' in local function names.
> 
> No functional change.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

I don't think it's a good idee to use function names that could be use
elsewhere, don't have a namespace. It makes it more difficult to figure
out which function is called by just searching for the function name.

Could you had a prefix?
Maybe xendisk_ or xen_disk or xen_qdisk or xen_block or ..., so we can
have xendisk_start_request, or xendisk_request_start. I don't have a
preference beside staying away from generic names.

Thanks,

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 13/18] xen: purge 'blk' and 'ioreq' from function names in dataplane/xen-qdisk.c
@ 2018-12-04 12:10     ` Anthony PERARD
  0 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-04 12:10 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, Stefan Hajnoczi, xen-devel

On Wed, Nov 21, 2018 at 03:12:06PM +0000, Paul Durrant wrote:
> This is a purely cosmetic patch that purges remaining use of 'blk' and
> 'ioreq' in local function names.
> 
> No functional change.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

I don't think it's a good idee to use function names that could be use
elsewhere, don't have a namespace. It makes it more difficult to figure
out which function is called by just searching for the function name.

Could you had a prefix?
Maybe xendisk_ or xen_disk or xen_qdisk or xen_block or ..., so we can
have xendisk_start_request, or xendisk_request_start. I don't have a
preference beside staying away from generic names.

Thanks,

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 14/18] xen: add implementations of xen-qdisk connect and disconnect functions...
  2018-11-21 15:12 ` [Qemu-devel] " Paul Durrant
  2018-11-28 16:34     ` Kevin Wolf
  2018-12-04 12:33   ` Anthony PERARD
@ 2018-12-04 12:33   ` Anthony PERARD
  2018-12-06 12:27       ` Paul Durrant
  2 siblings, 1 reply; 157+ messages in thread
From: Anthony PERARD @ 2018-12-04 12:33 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Kevin Wolf, Max Reitz

On Wed, Nov 21, 2018 at 03:12:07PM +0000, Paul Durrant wrote:
> diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> index 35f7b70480..8c88393832 100644
> --- a/hw/block/xen-qdisk.c
> +++ b/hw/block/xen-qdisk.c
>  static void xen_qdisk_connect(XenQdiskDevice *qdiskdev, Error **errp)
>  {
>      XenQdiskVdev *vdev = &qdiskdev->vdev;
> +    XenDevice *xendev = XEN_DEVICE(qdiskdev);
> +    unsigned int order, nr_ring_ref, *ring_ref, event_channel, protocol;
> +    char *str;
>  
>      trace_xen_qdisk_connect(vdev->disk, vdev->partition);
> +
> +    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");

Don't you need to free `ring_ref`?

> +            return;
> +        }
[...]

> diff --git a/include/hw/xen/xen-qdisk.h b/include/hw/xen/xen-qdisk.h
> index ade0866037..d7dd2bf0ee 100644
> --- a/include/hw/xen/xen-qdisk.h
> +++ b/include/hw/xen/xen-qdisk.h
> @@ -6,7 +6,15 @@
>  #ifndef HW_XEN_QDISK_H
>  #define HW_XEN_QDISK_H
>  
> +#include "hw/xen/xen.h"
>  #include "hw/xen/xen-bus.h"
> +#include "hw/block/block.h"
> +#include "hw/block/xen_blkif.h"
> +#include "hw/block/dataplane/xen-qdisk.h"
> +#include "sysemu/blockdev.h"
> +#include "sysemu/iothread.h"
> +#include "sysemu/block-backend.h"
> +#include "sysemu/iothread.h"

You don't need that many includes, especially not iothread.h twice ;-).

I think those new includes would be enough:
#include "hw/block/block.h"; for BlockConf
#include "sysemu/iothread.h"
#include "hw/block/dataplane/xen-qdisk.h"

>  
>  typedef enum XenQdiskVdevType {
>      XEN_QDISK_VDEV_TYPE_DP,
> @@ -33,6 +41,10 @@ typedef struct XenQdiskDevice XenQdiskDevice;
>  struct XenQdiskDevice {
>      XenDevice xendev;
>      XenQdiskVdev vdev;
> +    BlockConf conf;
> +    unsigned int max_ring_page_order;
> +    IOThread *iothread;
> +    XenQdiskDataPlane *dataplane;
>  };
>  
>  #endif /* HW_XEN_QDISK_H */

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 14/18] xen: add implementations of xen-qdisk connect and disconnect functions...
  2018-11-21 15:12 ` [Qemu-devel] " Paul Durrant
  2018-11-28 16:34     ` Kevin Wolf
@ 2018-12-04 12:33   ` Anthony PERARD
  2018-12-04 12:33   ` [Qemu-devel] " Anthony PERARD
  2 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-04 12:33 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, xen-devel

On Wed, Nov 21, 2018 at 03:12:07PM +0000, Paul Durrant wrote:
> diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> index 35f7b70480..8c88393832 100644
> --- a/hw/block/xen-qdisk.c
> +++ b/hw/block/xen-qdisk.c
>  static void xen_qdisk_connect(XenQdiskDevice *qdiskdev, Error **errp)
>  {
>      XenQdiskVdev *vdev = &qdiskdev->vdev;
> +    XenDevice *xendev = XEN_DEVICE(qdiskdev);
> +    unsigned int order, nr_ring_ref, *ring_ref, event_channel, protocol;
> +    char *str;
>  
>      trace_xen_qdisk_connect(vdev->disk, vdev->partition);
> +
> +    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");

Don't you need to free `ring_ref`?

> +            return;
> +        }
[...]

> diff --git a/include/hw/xen/xen-qdisk.h b/include/hw/xen/xen-qdisk.h
> index ade0866037..d7dd2bf0ee 100644
> --- a/include/hw/xen/xen-qdisk.h
> +++ b/include/hw/xen/xen-qdisk.h
> @@ -6,7 +6,15 @@
>  #ifndef HW_XEN_QDISK_H
>  #define HW_XEN_QDISK_H
>  
> +#include "hw/xen/xen.h"
>  #include "hw/xen/xen-bus.h"
> +#include "hw/block/block.h"
> +#include "hw/block/xen_blkif.h"
> +#include "hw/block/dataplane/xen-qdisk.h"
> +#include "sysemu/blockdev.h"
> +#include "sysemu/iothread.h"
> +#include "sysemu/block-backend.h"
> +#include "sysemu/iothread.h"

You don't need that many includes, especially not iothread.h twice ;-).

I think those new includes would be enough:
#include "hw/block/block.h"; for BlockConf
#include "sysemu/iothread.h"
#include "hw/block/dataplane/xen-qdisk.h"

>  
>  typedef enum XenQdiskVdevType {
>      XEN_QDISK_VDEV_TYPE_DP,
> @@ -33,6 +41,10 @@ typedef struct XenQdiskDevice XenQdiskDevice;
>  struct XenQdiskDevice {
>      XenDevice xendev;
>      XenQdiskVdev vdev;
> +    BlockConf conf;
> +    unsigned int max_ring_page_order;
> +    IOThread *iothread;
> +    XenQdiskDataPlane *dataplane;
>  };
>  
>  #endif /* HW_XEN_QDISK_H */

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 07/18] xen: add event channel interface for XenDevice-s
  2018-12-03 16:24     ` Anthony PERARD
@ 2018-12-04 14:24       ` Anthony PERARD
  -1 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-04 14:24 UTC (permalink / raw)
  To: Paul Durrant; +Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini

On Mon, Dec 03, 2018 at 04:24:24PM +0000, Anthony PERARD wrote:
> On Wed, Nov 21, 2018 at 03:12:00PM +0000, Paul Durrant wrote:
> > +static void xen_device_event(void *opaque)
> > +{
> > +    XenDevice *xendev = opaque;
> > +    unsigned long port = xenevtchn_pending(xendev->xeh);
> > +
> > +    notifier_list_notify(&xendev->event_notifiers, (void *)port);
> 
> I wonder if a Notifier is a good fit for XenDevice, like here for the
> events or the xenstore watches in previous patches, as NotifierLists are
> normaly used when every Notifiers want to do something, but here there
> is only one that is going to do something. But I guess it might not be
> much better to write a loop in here rather than use the one in
> notifier_list_notify.

I've seen that you use GHashTable in a following patch, wouldn't that be
useful to use for xenstore watches and evtchn events as well?


-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 07/18] xen: add event channel interface for XenDevice-s
@ 2018-12-04 14:24       ` Anthony PERARD
  0 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-04 14:24 UTC (permalink / raw)
  To: Paul Durrant; +Cc: xen-devel, Stefano Stabellini, qemu-devel, qemu-block

On Mon, Dec 03, 2018 at 04:24:24PM +0000, Anthony PERARD wrote:
> On Wed, Nov 21, 2018 at 03:12:00PM +0000, Paul Durrant wrote:
> > +static void xen_device_event(void *opaque)
> > +{
> > +    XenDevice *xendev = opaque;
> > +    unsigned long port = xenevtchn_pending(xendev->xeh);
> > +
> > +    notifier_list_notify(&xendev->event_notifiers, (void *)port);
> 
> I wonder if a Notifier is a good fit for XenDevice, like here for the
> events or the xenstore watches in previous patches, as NotifierLists are
> normaly used when every Notifiers want to do something, but here there
> is only one that is going to do something. But I guess it might not be
> much better to write a loop in here rather than use the one in
> notifier_list_notify.

I've seen that you use GHashTable in a following patch, wouldn't that be
useful to use for xenstore watches and evtchn events as well?


-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 03/18] xen: introduce 'xen-qdisk'
  2018-11-29 16:05   ` [Qemu-devel] " Anthony PERARD
@ 2018-12-04 15:20     ` Paul Durrant
  2018-12-04 15:49       ` Anthony PERARD
                         ` (3 more replies)
  2018-12-04 15:20     ` Paul Durrant
  1 sibling, 4 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-04 15:20 UTC (permalink / raw)
  To: Anthony Perard
  Cc: qemu-block, qemu-devel, xen-devel, Kevin Wolf, Max Reitz,
	Stefano Stabellini

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 29 November 2018 16:06
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Kevin Wolf <kwolf@redhat.com>; Max Reitz
> <mreitz@redhat.com>; Stefano Stabellini <sstabellini@kernel.org>
> Subject: Re: [PATCH 03/18] xen: introduce 'xen-qdisk'
> 
> On Wed, Nov 21, 2018 at 03:11:56PM +0000, Paul Durrant wrote:
> > This patch adds a new XenDevice: 'xen-qdisk' [1]. This will eventually
> > replace the 'xen_disk' legacy PV backend but it is illustrative to build
> > up the implementation incrementally, along with the XenBus/XenDevice
> > framework. Subsequent patches will therefore add to this device's
> > implementation as new features are added to the framework.
> >
> > After this patch has been applied it is possible to instantiate a new
> > 'xen-qdisk' device with a single 'vdev' parameter, which accepts values
> > adhering to the Xen VBD naming scheme [2]. For example, a command-line
> > instantiation of a xen-qdisk can be done with an argument similar to the
> > following:
> >
> > -device xen-qdisk,vdev=hda
> 
> That works when QEMU boot, but doing the same thing once the guest have
> booted, via QMP, doesn't. Here is the result (tested in qmp-shell):
> 
> (QEMU) device_add driver=xen-qdisk vdev=hda
> {
>     "error": {
>         "class": "GenericError",
>         "desc": "Bus 'xen-bus.0' does not support hotplugging"
>     }
> }
> 
> That's probably why I've asked about the hotplug capability on the
> previous patch.
> 

Ok. I've added the hotplug now so I'll make sure QMP DTRT.

> > The implementation of the vdev parameter formulates the appropriate VBD
> > number for use in the PV protocol.
> >
> > [1] The name 'qdisk' as always been the name given to the QEMU
> >     implementation of the Xen PV block protocol backend implementation
> > [2] http://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=docs/man/xen-vbd-
> interface.markdown.7
> 
> Maybe a link to the generated docs would be better:
> https://xenbits.xen.org/docs/unstable/man/xen-vbd-interface.7.html
> 

Ok.

> Also, it would be useful to have the same link in the source code.
> 

Yes, I'll add a comment.

> > diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> > new file mode 100644
> > index 0000000000..72122073f7
> > --- /dev/null
> > +++ b/hw/block/xen-qdisk.c
> [...]
> > +static char *disk_to_vbd_name(unsigned int disk)
> > +{
> > +    unsigned int len = DIV_ROUND_UP(disk, 26);
> > +    char *name = g_malloc0(len + 1);
> > +
> > +    do {
> > +        name[len--] = 'a' + (disk % 26);
> > +        disk /= 26;
> > +    } while (disk != 0);
> > +    assert(len == 0);
> > +
> > +    return name;
> > +}
> 
> That function doesn't work.
> 
> For a simple xvdp, (so disk==15), it return "", I mean "\0p".
> 
> For a more complicated 'xvdbhwza', we have len == 22901. And the assert
> failed.
> 
> Maybe the recursing algo in libxl would be fine, with a buffer that is
> big enough, and could probably be on the stack (in _get_vdev).

I used libxl__device_disk_dev_number() as my model (as well as cross-checking with the spec), but I guess a recursing algorithm would be neater.

> 
> > +
> > +    switch (vdev->type) {
> > +    case XEN_QDISK_VDEV_TYPE_DP:
> > +    case XEN_QDISK_VDEV_TYPE_XVD:
> > +        if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) {
> > +            vdev->number = (202 << 8) | (vdev->disk << 4) |
> > +                vdev->partition;
> > +        } else if (vdev->disk < (1 << 20) && vdev->partition < (1 <<
> 8)) {
> > +            vdev->number = (1 << 28) | (vdev->disk << 8) |
> > +                vdev->partition;
> > +        } else {
> > +            goto invalid;
> > +        }
> > +        break;
> > +
> > +    case XEN_QDISK_VDEV_TYPE_HD:
> > +        if ((vdev->disk == 0 || vdev->disk == 1) &&
> > +            vdev->partition < (1 << 4)) {
> 
> I think that should be:
> 
>     vdev->partition < (1 << 6)
> 
> Because hd disk have 0..63 partitions.

Yes, I must have typo-ed it...

> 
> > +            vdev->number = (3 << 8) | (vdev->disk << 6) | vdev-
> >partition;
> > +        } else if ((vdev->disk == 2 || vdev->disk == 3) &&
> > +                   vdev->partition < (1 << 4)) {
> 
> same here.

...and then cut'n'pasted.

> 
> > +            vdev->number = (22 << 8) | ((vdev->disk - 2) << 6) |
> > +                vdev->partition;
> > +        } else {
> > +            goto invalid;
> > +        }
> > +        break;
> > +
> > +    case XEN_QDISK_VDEV_TYPE_SD:
> > +        if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) {
> > +            vdev->number = (8 << 8) | (vdev->disk << 4) | vdev-
> >partition;
> > +        } else {
> > +            goto invalid;
> > +        }
> > +        break;
> > +
> > +    default:
> > +        goto invalid;
> > +    }
> > +
> > +    g_free(str);
> > +    vdev->valid = true;
> > +    return;
> > +
> > +invalid:
> > +    error_setg(errp, "invalid virtual disk specifier");
> > +    g_free(str);
> 
> :(, g_free is called twice.

Oops. Good catch.

> 
> maybe we could have:
>     vdev->valid=true;
>     out:
>       if (!vdev->valid)
>         error_setg(...);
>       g_free;
> 
> > diff --git a/include/hw/xen/xen-qdisk.h b/include/hw/xen/xen-qdisk.h
> > new file mode 100644
> > index 0000000000..ade0866037
> > --- /dev/null
> > +++ b/include/hw/xen/xen-qdisk.h
> > @@ -0,0 +1,38 @@
> > +/*
> > + * Copyright (c) Citrix Systems Inc.
> > + * All rights reserved.
> > + */
> > +
> > +#ifndef HW_XEN_QDISK_H
> > +#define HW_XEN_QDISK_H
> > +
> > +#include "hw/xen/xen-bus.h"
> > +
> > +typedef enum XenQdiskVdevType {
> > +    XEN_QDISK_VDEV_TYPE_DP,
> 
> Maybe we could set type_dp value to 1, so that, when vdev->type isn't
> set, we can detect it later.

Rather than having the 'valid' bool? Yes, that would work.

  Paul

> 
> 
> > +    XEN_QDISK_VDEV_TYPE_XVD,
> > +    XEN_QDISK_VDEV_TYPE_HD,
> > +    XEN_QDISK_VDEV_TYPE_SD,
> > +    XEN_QDISK_VDEV_TYPE__MAX
> > +} XenQdiskVdevType;
> 
> Thanks,
> 
> --
> Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 03/18] xen: introduce 'xen-qdisk'
  2018-11-29 16:05   ` [Qemu-devel] " Anthony PERARD
  2018-12-04 15:20     ` Paul Durrant
@ 2018-12-04 15:20     ` Paul Durrant
  1 sibling, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-04 15:20 UTC (permalink / raw)
  To: Anthony Perard
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, xen-devel

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 29 November 2018 16:06
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Kevin Wolf <kwolf@redhat.com>; Max Reitz
> <mreitz@redhat.com>; Stefano Stabellini <sstabellini@kernel.org>
> Subject: Re: [PATCH 03/18] xen: introduce 'xen-qdisk'
> 
> On Wed, Nov 21, 2018 at 03:11:56PM +0000, Paul Durrant wrote:
> > This patch adds a new XenDevice: 'xen-qdisk' [1]. This will eventually
> > replace the 'xen_disk' legacy PV backend but it is illustrative to build
> > up the implementation incrementally, along with the XenBus/XenDevice
> > framework. Subsequent patches will therefore add to this device's
> > implementation as new features are added to the framework.
> >
> > After this patch has been applied it is possible to instantiate a new
> > 'xen-qdisk' device with a single 'vdev' parameter, which accepts values
> > adhering to the Xen VBD naming scheme [2]. For example, a command-line
> > instantiation of a xen-qdisk can be done with an argument similar to the
> > following:
> >
> > -device xen-qdisk,vdev=hda
> 
> That works when QEMU boot, but doing the same thing once the guest have
> booted, via QMP, doesn't. Here is the result (tested in qmp-shell):
> 
> (QEMU) device_add driver=xen-qdisk vdev=hda
> {
>     "error": {
>         "class": "GenericError",
>         "desc": "Bus 'xen-bus.0' does not support hotplugging"
>     }
> }
> 
> That's probably why I've asked about the hotplug capability on the
> previous patch.
> 

Ok. I've added the hotplug now so I'll make sure QMP DTRT.

> > The implementation of the vdev parameter formulates the appropriate VBD
> > number for use in the PV protocol.
> >
> > [1] The name 'qdisk' as always been the name given to the QEMU
> >     implementation of the Xen PV block protocol backend implementation
> > [2] http://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=docs/man/xen-vbd-
> interface.markdown.7
> 
> Maybe a link to the generated docs would be better:
> https://xenbits.xen.org/docs/unstable/man/xen-vbd-interface.7.html
> 

Ok.

> Also, it would be useful to have the same link in the source code.
> 

Yes, I'll add a comment.

> > diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> > new file mode 100644
> > index 0000000000..72122073f7
> > --- /dev/null
> > +++ b/hw/block/xen-qdisk.c
> [...]
> > +static char *disk_to_vbd_name(unsigned int disk)
> > +{
> > +    unsigned int len = DIV_ROUND_UP(disk, 26);
> > +    char *name = g_malloc0(len + 1);
> > +
> > +    do {
> > +        name[len--] = 'a' + (disk % 26);
> > +        disk /= 26;
> > +    } while (disk != 0);
> > +    assert(len == 0);
> > +
> > +    return name;
> > +}
> 
> That function doesn't work.
> 
> For a simple xvdp, (so disk==15), it return "", I mean "\0p".
> 
> For a more complicated 'xvdbhwza', we have len == 22901. And the assert
> failed.
> 
> Maybe the recursing algo in libxl would be fine, with a buffer that is
> big enough, and could probably be on the stack (in _get_vdev).

I used libxl__device_disk_dev_number() as my model (as well as cross-checking with the spec), but I guess a recursing algorithm would be neater.

> 
> > +
> > +    switch (vdev->type) {
> > +    case XEN_QDISK_VDEV_TYPE_DP:
> > +    case XEN_QDISK_VDEV_TYPE_XVD:
> > +        if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) {
> > +            vdev->number = (202 << 8) | (vdev->disk << 4) |
> > +                vdev->partition;
> > +        } else if (vdev->disk < (1 << 20) && vdev->partition < (1 <<
> 8)) {
> > +            vdev->number = (1 << 28) | (vdev->disk << 8) |
> > +                vdev->partition;
> > +        } else {
> > +            goto invalid;
> > +        }
> > +        break;
> > +
> > +    case XEN_QDISK_VDEV_TYPE_HD:
> > +        if ((vdev->disk == 0 || vdev->disk == 1) &&
> > +            vdev->partition < (1 << 4)) {
> 
> I think that should be:
> 
>     vdev->partition < (1 << 6)
> 
> Because hd disk have 0..63 partitions.

Yes, I must have typo-ed it...

> 
> > +            vdev->number = (3 << 8) | (vdev->disk << 6) | vdev-
> >partition;
> > +        } else if ((vdev->disk == 2 || vdev->disk == 3) &&
> > +                   vdev->partition < (1 << 4)) {
> 
> same here.

...and then cut'n'pasted.

> 
> > +            vdev->number = (22 << 8) | ((vdev->disk - 2) << 6) |
> > +                vdev->partition;
> > +        } else {
> > +            goto invalid;
> > +        }
> > +        break;
> > +
> > +    case XEN_QDISK_VDEV_TYPE_SD:
> > +        if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) {
> > +            vdev->number = (8 << 8) | (vdev->disk << 4) | vdev-
> >partition;
> > +        } else {
> > +            goto invalid;
> > +        }
> > +        break;
> > +
> > +    default:
> > +        goto invalid;
> > +    }
> > +
> > +    g_free(str);
> > +    vdev->valid = true;
> > +    return;
> > +
> > +invalid:
> > +    error_setg(errp, "invalid virtual disk specifier");
> > +    g_free(str);
> 
> :(, g_free is called twice.

Oops. Good catch.

> 
> maybe we could have:
>     vdev->valid=true;
>     out:
>       if (!vdev->valid)
>         error_setg(...);
>       g_free;
> 
> > diff --git a/include/hw/xen/xen-qdisk.h b/include/hw/xen/xen-qdisk.h
> > new file mode 100644
> > index 0000000000..ade0866037
> > --- /dev/null
> > +++ b/include/hw/xen/xen-qdisk.h
> > @@ -0,0 +1,38 @@
> > +/*
> > + * Copyright (c) Citrix Systems Inc.
> > + * All rights reserved.
> > + */
> > +
> > +#ifndef HW_XEN_QDISK_H
> > +#define HW_XEN_QDISK_H
> > +
> > +#include "hw/xen/xen-bus.h"
> > +
> > +typedef enum XenQdiskVdevType {
> > +    XEN_QDISK_VDEV_TYPE_DP,
> 
> Maybe we could set type_dp value to 1, so that, when vdev->type isn't
> set, we can detect it later.

Rather than having the 'valid' bool? Yes, that would work.

  Paul

> 
> 
> > +    XEN_QDISK_VDEV_TYPE_XVD,
> > +    XEN_QDISK_VDEV_TYPE_HD,
> > +    XEN_QDISK_VDEV_TYPE_SD,
> > +    XEN_QDISK_VDEV_TYPE__MAX
> > +} XenQdiskVdevType;
> 
> Thanks,
> 
> --
> Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 15/18] xen: add a mechanism to automatically create XenDevice-s...
  2018-11-21 15:12   ` Paul Durrant
@ 2018-12-04 15:35     ` Anthony PERARD
  -1 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-04 15:35 UTC (permalink / raw)
  To: Paul Durrant; +Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini

On Wed, Nov 21, 2018 at 03:12:08PM +0000, Paul Durrant wrote:
> +    xen_backend_device_create(BUS(xenbus), type, name, opts, &local_err);
> +    qobject_unref(opts);
> +
> +    if (local_err) {
> +        const char *msg = error_get_pretty(local_err);
> +
> +        error_report("failed to create '%s' device '%s': %s", type, name,
> +                     msg);
> +        error_free(local_err);

You can use error_reportf_err() instead of those three calls. I may have
only suggest error_report_err in a previous patch, but error_reportf_err
does the error_prepend as well.

> +    }
> +}
> +
> +static void xen_bus_type_enumerate(XenBus *xenbus, const char *type)
> +{
> +    char *domain_path = g_strdup_printf("backend/%s/%u", type, xen_domid);
> +    char **backend;
> +    unsigned int i, n;
> +
> +    trace_xen_bus_type_enumerate(type);
> +
> +    backend = xs_directory(xenbus->xsh, XBT_NULL, domain_path, &n);
> +    if (!backend) {

domain_path isn't free here, you probably want a `goto out` which would
free everything.

> +        return;
> +    }
> +
> @@ -193,6 +302,17 @@ static void xen_bus_realize(BusState *bus, Error **errp)
>      notifier_list_init(&xenbus->watch_notifiers);
>      qemu_set_fd_handler(xs_fileno(xenbus->xsh), xen_bus_watch, NULL,
>                          xenbus);
> +
> +    module_call_init(MODULE_INIT_XEN_BACKEND);
> +
> +    xenbus->backend_watch =
> +        xen_bus_add_watch(xenbus, "", /* domain root node */
> +                          "backend", xen_bus_enumerate, xenbus, &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        error_prepend(errp, "failed to set up enumeration watch: ");

You should use error_propagate_prepend instead
error_propagate;error_prepend. And it looks like there is the same
mistake in other patches that I haven't notice.

Also you probably want goto fail here.


> +static void xen_device_backend_changed(void *opaque)
> +{
> +    XenDevice *xendev = opaque;
> +    const char *type = object_get_typename(OBJECT(xendev));
> +    enum xenbus_state state;
> +    unsigned int online;
> +
> +    trace_xen_device_backend_changed(type, xendev->name);
> +
> +    if (xen_device_backend_scanf(xendev, "state", "%u", &state) != 1) {
> +        state = XenbusStateUnknown;
> +    }
> +
> +    xen_device_backend_set_state(xendev, state);

It's kind of weird to set the internal state base on the external one
that something else may have modified. Shouldn't we check that it is
fine for something else to modify the state and that it is a correct
transition?

Also aren't we going in a loop by having QEMU set the state, then the
watch fires again? (Not really a loop since the function _set_state
check for changes.

Also maybe we should watch for the state changes only when something
else like libxl creates (ask for) the backend, and ignore changes when
QEMU did it itself.

> +
> +    if (xen_device_backend_scanf(xendev, "online", "%u", &online) != 1) {
> +        online = 0;
> +    }
> +
> +    xen_device_backend_set_online(xendev, !!online);
> +
> +    /*
> +     * If a backend is still 'online' then its state should be cycled
> +     * back round to InitWait in order for a new frontend instance to
> +     * connect. This may happen when, for example, a frontend driver is
> +     * re-installed or updated.
> +     * If a backend id not 'online' then the device should be destroyed.

s/id/is/

> +     */
> +    if (xendev->backend_online &&
> +        xendev->backend_state == XenbusStateClosed) {
> +        xen_device_backend_set_state(xendev, XenbusStateInitWait);
> +    } else if (!xendev->backend_online &&
> +               (xendev->backend_state == XenbusStateClosed ||
> +                xendev->backend_state == XenbusStateInitialising ||
> +                xendev->backend_state == XenbusStateInitWait ||
> +                xendev->backend_state == XenbusStateUnknown)) {
> +        object_unparent(OBJECT(xendev));
> +    }
> +}
> +
>  static void xen_device_backend_create(XenDevice *xendev, Error **errp)
>  {
>      XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
> @@ -289,12 +463,38 @@ static void xen_device_backend_create(XenDevice *xendev, Error **errp)
>          error_propagate(errp, local_err);
>          error_prepend(errp, "failed to create backend: ");

It looks like there is a missing return here.

>      }
> +
> +    xendev->backend_state_watch =
> +        xen_bus_add_watch(xenbus, xendev->backend_path,
> +                          "state", xen_device_backend_changed,
> +                          xendev, &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        error_prepend(errp, "failed to watch backend state: ");

You should return here, as local_err mustn't be reused.

> +    }
> +
> +    xendev->backend_online_watch =
> +        xen_bus_add_watch(xenbus, xendev->backend_path,
> +                          "online", xen_device_backend_changed,
> +                          xendev, &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        error_prepend(errp, "failed to watch backend online: ");

You probably want a return here, in case there is more code added after.

> +    }

Other instances of error_propagate;error_prepend to be replaced by
error_propagate_prepend.

>  }
>  

Thanks,

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 15/18] xen: add a mechanism to automatically create XenDevice-s...
@ 2018-12-04 15:35     ` Anthony PERARD
  0 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-04 15:35 UTC (permalink / raw)
  To: Paul Durrant; +Cc: xen-devel, Stefano Stabellini, qemu-devel, qemu-block

On Wed, Nov 21, 2018 at 03:12:08PM +0000, Paul Durrant wrote:
> +    xen_backend_device_create(BUS(xenbus), type, name, opts, &local_err);
> +    qobject_unref(opts);
> +
> +    if (local_err) {
> +        const char *msg = error_get_pretty(local_err);
> +
> +        error_report("failed to create '%s' device '%s': %s", type, name,
> +                     msg);
> +        error_free(local_err);

You can use error_reportf_err() instead of those three calls. I may have
only suggest error_report_err in a previous patch, but error_reportf_err
does the error_prepend as well.

> +    }
> +}
> +
> +static void xen_bus_type_enumerate(XenBus *xenbus, const char *type)
> +{
> +    char *domain_path = g_strdup_printf("backend/%s/%u", type, xen_domid);
> +    char **backend;
> +    unsigned int i, n;
> +
> +    trace_xen_bus_type_enumerate(type);
> +
> +    backend = xs_directory(xenbus->xsh, XBT_NULL, domain_path, &n);
> +    if (!backend) {

domain_path isn't free here, you probably want a `goto out` which would
free everything.

> +        return;
> +    }
> +
> @@ -193,6 +302,17 @@ static void xen_bus_realize(BusState *bus, Error **errp)
>      notifier_list_init(&xenbus->watch_notifiers);
>      qemu_set_fd_handler(xs_fileno(xenbus->xsh), xen_bus_watch, NULL,
>                          xenbus);
> +
> +    module_call_init(MODULE_INIT_XEN_BACKEND);
> +
> +    xenbus->backend_watch =
> +        xen_bus_add_watch(xenbus, "", /* domain root node */
> +                          "backend", xen_bus_enumerate, xenbus, &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        error_prepend(errp, "failed to set up enumeration watch: ");

You should use error_propagate_prepend instead
error_propagate;error_prepend. And it looks like there is the same
mistake in other patches that I haven't notice.

Also you probably want goto fail here.


> +static void xen_device_backend_changed(void *opaque)
> +{
> +    XenDevice *xendev = opaque;
> +    const char *type = object_get_typename(OBJECT(xendev));
> +    enum xenbus_state state;
> +    unsigned int online;
> +
> +    trace_xen_device_backend_changed(type, xendev->name);
> +
> +    if (xen_device_backend_scanf(xendev, "state", "%u", &state) != 1) {
> +        state = XenbusStateUnknown;
> +    }
> +
> +    xen_device_backend_set_state(xendev, state);

It's kind of weird to set the internal state base on the external one
that something else may have modified. Shouldn't we check that it is
fine for something else to modify the state and that it is a correct
transition?

Also aren't we going in a loop by having QEMU set the state, then the
watch fires again? (Not really a loop since the function _set_state
check for changes.

Also maybe we should watch for the state changes only when something
else like libxl creates (ask for) the backend, and ignore changes when
QEMU did it itself.

> +
> +    if (xen_device_backend_scanf(xendev, "online", "%u", &online) != 1) {
> +        online = 0;
> +    }
> +
> +    xen_device_backend_set_online(xendev, !!online);
> +
> +    /*
> +     * If a backend is still 'online' then its state should be cycled
> +     * back round to InitWait in order for a new frontend instance to
> +     * connect. This may happen when, for example, a frontend driver is
> +     * re-installed or updated.
> +     * If a backend id not 'online' then the device should be destroyed.

s/id/is/

> +     */
> +    if (xendev->backend_online &&
> +        xendev->backend_state == XenbusStateClosed) {
> +        xen_device_backend_set_state(xendev, XenbusStateInitWait);
> +    } else if (!xendev->backend_online &&
> +               (xendev->backend_state == XenbusStateClosed ||
> +                xendev->backend_state == XenbusStateInitialising ||
> +                xendev->backend_state == XenbusStateInitWait ||
> +                xendev->backend_state == XenbusStateUnknown)) {
> +        object_unparent(OBJECT(xendev));
> +    }
> +}
> +
>  static void xen_device_backend_create(XenDevice *xendev, Error **errp)
>  {
>      XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
> @@ -289,12 +463,38 @@ static void xen_device_backend_create(XenDevice *xendev, Error **errp)
>          error_propagate(errp, local_err);
>          error_prepend(errp, "failed to create backend: ");

It looks like there is a missing return here.

>      }
> +
> +    xendev->backend_state_watch =
> +        xen_bus_add_watch(xenbus, xendev->backend_path,
> +                          "state", xen_device_backend_changed,
> +                          xendev, &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        error_prepend(errp, "failed to watch backend state: ");

You should return here, as local_err mustn't be reused.

> +    }
> +
> +    xendev->backend_online_watch =
> +        xen_bus_add_watch(xenbus, xendev->backend_path,
> +                          "online", xen_device_backend_changed,
> +                          xendev, &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        error_prepend(errp, "failed to watch backend online: ");

You probably want a return here, in case there is more code added after.

> +    }

Other instances of error_propagate;error_prepend to be replaced by
error_propagate_prepend.

>  }
>  

Thanks,

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 03/18] xen: introduce 'xen-qdisk'
  2018-12-04 15:20     ` Paul Durrant
@ 2018-12-04 15:49       ` Anthony PERARD
  2018-12-04 15:50         ` Paul Durrant
  2018-12-04 15:50         ` Paul Durrant
  2018-12-04 15:49       ` Anthony PERARD
                         ` (2 subsequent siblings)
  3 siblings, 2 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-04 15:49 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Kevin Wolf, Max Reitz,
	Stefano Stabellini

On Tue, Dec 04, 2018 at 03:20:04PM +0000, Paul Durrant wrote:
> > > +static char *disk_to_vbd_name(unsigned int disk)
> > > +{
> > > +    unsigned int len = DIV_ROUND_UP(disk, 26);
> > > +    char *name = g_malloc0(len + 1);
> > > +
> > > +    do {
> > > +        name[len--] = 'a' + (disk % 26);
> > > +        disk /= 26;
> > > +    } while (disk != 0);
> > > +    assert(len == 0);
> > > +
> > > +    return name;
> > > +}
> > 
> > That function doesn't work.
> > 
> > For a simple xvdp, (so disk==15), it return "", I mean "\0p".
> > 
> > For a more complicated 'xvdbhwza', we have len == 22901. And the assert
> > failed.
> > 
> > Maybe the recursing algo in libxl would be fine, with a buffer that is
> > big enough, and could probably be on the stack (in _get_vdev).
> 
> I used libxl__device_disk_dev_number() as my model (as well as cross-checking with the spec), but I guess a recursing algorithm would be neater.

There is libxl__devid_to_vdev() actually just after ;-) which calls
encode_disk_name which is recursing.

> > > diff --git a/include/hw/xen/xen-qdisk.h b/include/hw/xen/xen-qdisk.h
> > > new file mode 100644
> > > index 0000000000..ade0866037
> > > --- /dev/null
> > > +++ b/include/hw/xen/xen-qdisk.h
> > > @@ -0,0 +1,38 @@
> > > +/*
> > > + * Copyright (c) Citrix Systems Inc.
> > > + * All rights reserved.
> > > + */
> > > +
> > > +#ifndef HW_XEN_QDISK_H
> > > +#define HW_XEN_QDISK_H
> > > +
> > > +#include "hw/xen/xen-bus.h"
> > > +
> > > +typedef enum XenQdiskVdevType {
> > > +    XEN_QDISK_VDEV_TYPE_DP,
> > 
> > Maybe we could set type_dp value to 1, so that, when vdev->type isn't
> > set, we can detect it later.
> 
> Rather than having the 'valid' bool? Yes, that would work.

Well, the 'valid' bool doesn't seems to always be check so it would be
better. e.g. xen_qdisk_get_vdev() doesn't check `valid` before
genereting a string. Then xen_qdisk_set_vdev could set `type` to invalid
when it is invalid.

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 03/18] xen: introduce 'xen-qdisk'
  2018-12-04 15:20     ` Paul Durrant
  2018-12-04 15:49       ` Anthony PERARD
@ 2018-12-04 15:49       ` Anthony PERARD
  2018-12-04 17:14       ` [Qemu-devel] " Paul Durrant
  2018-12-04 17:14       ` Paul Durrant
  3 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-04 15:49 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, xen-devel

On Tue, Dec 04, 2018 at 03:20:04PM +0000, Paul Durrant wrote:
> > > +static char *disk_to_vbd_name(unsigned int disk)
> > > +{
> > > +    unsigned int len = DIV_ROUND_UP(disk, 26);
> > > +    char *name = g_malloc0(len + 1);
> > > +
> > > +    do {
> > > +        name[len--] = 'a' + (disk % 26);
> > > +        disk /= 26;
> > > +    } while (disk != 0);
> > > +    assert(len == 0);
> > > +
> > > +    return name;
> > > +}
> > 
> > That function doesn't work.
> > 
> > For a simple xvdp, (so disk==15), it return "", I mean "\0p".
> > 
> > For a more complicated 'xvdbhwza', we have len == 22901. And the assert
> > failed.
> > 
> > Maybe the recursing algo in libxl would be fine, with a buffer that is
> > big enough, and could probably be on the stack (in _get_vdev).
> 
> I used libxl__device_disk_dev_number() as my model (as well as cross-checking with the spec), but I guess a recursing algorithm would be neater.

There is libxl__devid_to_vdev() actually just after ;-) which calls
encode_disk_name which is recursing.

> > > diff --git a/include/hw/xen/xen-qdisk.h b/include/hw/xen/xen-qdisk.h
> > > new file mode 100644
> > > index 0000000000..ade0866037
> > > --- /dev/null
> > > +++ b/include/hw/xen/xen-qdisk.h
> > > @@ -0,0 +1,38 @@
> > > +/*
> > > + * Copyright (c) Citrix Systems Inc.
> > > + * All rights reserved.
> > > + */
> > > +
> > > +#ifndef HW_XEN_QDISK_H
> > > +#define HW_XEN_QDISK_H
> > > +
> > > +#include "hw/xen/xen-bus.h"
> > > +
> > > +typedef enum XenQdiskVdevType {
> > > +    XEN_QDISK_VDEV_TYPE_DP,
> > 
> > Maybe we could set type_dp value to 1, so that, when vdev->type isn't
> > set, we can detect it later.
> 
> Rather than having the 'valid' bool? Yes, that would work.

Well, the 'valid' bool doesn't seems to always be check so it would be
better. e.g. xen_qdisk_get_vdev() doesn't check `valid` before
genereting a string. Then xen_qdisk_set_vdev could set `type` to invalid
when it is invalid.

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 03/18] xen: introduce 'xen-qdisk'
  2018-12-04 15:49       ` Anthony PERARD
@ 2018-12-04 15:50         ` Paul Durrant
  2018-12-04 15:50         ` Paul Durrant
  1 sibling, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-04 15:50 UTC (permalink / raw)
  To: Anthony Perard
  Cc: qemu-block, qemu-devel, xen-devel, Kevin Wolf, Max Reitz,
	Stefano Stabellini



> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 04 December 2018 15:49
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Kevin Wolf <kwolf@redhat.com>; Max Reitz
> <mreitz@redhat.com>; Stefano Stabellini <sstabellini@kernel.org>
> Subject: Re: [PATCH 03/18] xen: introduce 'xen-qdisk'
> 
> On Tue, Dec 04, 2018 at 03:20:04PM +0000, Paul Durrant wrote:
> > > > +static char *disk_to_vbd_name(unsigned int disk)
> > > > +{
> > > > +    unsigned int len = DIV_ROUND_UP(disk, 26);
> > > > +    char *name = g_malloc0(len + 1);
> > > > +
> > > > +    do {
> > > > +        name[len--] = 'a' + (disk % 26);
> > > > +        disk /= 26;
> > > > +    } while (disk != 0);
> > > > +    assert(len == 0);
> > > > +
> > > > +    return name;
> > > > +}
> > >
> > > That function doesn't work.
> > >
> > > For a simple xvdp, (so disk==15), it return "", I mean "\0p".
> > >
> > > For a more complicated 'xvdbhwza', we have len == 22901. And the
> assert
> > > failed.
> > >
> > > Maybe the recursing algo in libxl would be fine, with a buffer that is
> > > big enough, and could probably be on the stack (in _get_vdev).
> >
> > I used libxl__device_disk_dev_number() as my model (as well as cross-
> checking with the spec), but I guess a recursing algorithm would be
> neater.
> 
> There is libxl__devid_to_vdev() actually just after ;-) which calls
> encode_disk_name which is recursing.

Ah, I'll look for that. Currently having trouble reconciling the 'tq' -> 536 mapping in the doc.

  Paul

> 
> > > > diff --git a/include/hw/xen/xen-qdisk.h b/include/hw/xen/xen-qdisk.h
> > > > new file mode 100644
> > > > index 0000000000..ade0866037
> > > > --- /dev/null
> > > > +++ b/include/hw/xen/xen-qdisk.h
> > > > @@ -0,0 +1,38 @@
> > > > +/*
> > > > + * Copyright (c) Citrix Systems Inc.
> > > > + * All rights reserved.
> > > > + */
> > > > +
> > > > +#ifndef HW_XEN_QDISK_H
> > > > +#define HW_XEN_QDISK_H
> > > > +
> > > > +#include "hw/xen/xen-bus.h"
> > > > +
> > > > +typedef enum XenQdiskVdevType {
> > > > +    XEN_QDISK_VDEV_TYPE_DP,
> > >
> > > Maybe we could set type_dp value to 1, so that, when vdev->type isn't
> > > set, we can detect it later.
> >
> > Rather than having the 'valid' bool? Yes, that would work.
> 
> Well, the 'valid' bool doesn't seems to always be check so it would be
> better. e.g. xen_qdisk_get_vdev() doesn't check `valid` before
> genereting a string. Then xen_qdisk_set_vdev could set `type` to invalid
> when it is invalid.
> 
> --
> Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 03/18] xen: introduce 'xen-qdisk'
  2018-12-04 15:49       ` Anthony PERARD
  2018-12-04 15:50         ` Paul Durrant
@ 2018-12-04 15:50         ` Paul Durrant
  1 sibling, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-04 15:50 UTC (permalink / raw)
  To: Anthony Perard
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, xen-devel



> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 04 December 2018 15:49
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Kevin Wolf <kwolf@redhat.com>; Max Reitz
> <mreitz@redhat.com>; Stefano Stabellini <sstabellini@kernel.org>
> Subject: Re: [PATCH 03/18] xen: introduce 'xen-qdisk'
> 
> On Tue, Dec 04, 2018 at 03:20:04PM +0000, Paul Durrant wrote:
> > > > +static char *disk_to_vbd_name(unsigned int disk)
> > > > +{
> > > > +    unsigned int len = DIV_ROUND_UP(disk, 26);
> > > > +    char *name = g_malloc0(len + 1);
> > > > +
> > > > +    do {
> > > > +        name[len--] = 'a' + (disk % 26);
> > > > +        disk /= 26;
> > > > +    } while (disk != 0);
> > > > +    assert(len == 0);
> > > > +
> > > > +    return name;
> > > > +}
> > >
> > > That function doesn't work.
> > >
> > > For a simple xvdp, (so disk==15), it return "", I mean "\0p".
> > >
> > > For a more complicated 'xvdbhwza', we have len == 22901. And the
> assert
> > > failed.
> > >
> > > Maybe the recursing algo in libxl would be fine, with a buffer that is
> > > big enough, and could probably be on the stack (in _get_vdev).
> >
> > I used libxl__device_disk_dev_number() as my model (as well as cross-
> checking with the spec), but I guess a recursing algorithm would be
> neater.
> 
> There is libxl__devid_to_vdev() actually just after ;-) which calls
> encode_disk_name which is recursing.

Ah, I'll look for that. Currently having trouble reconciling the 'tq' -> 536 mapping in the doc.

  Paul

> 
> > > > diff --git a/include/hw/xen/xen-qdisk.h b/include/hw/xen/xen-qdisk.h
> > > > new file mode 100644
> > > > index 0000000000..ade0866037
> > > > --- /dev/null
> > > > +++ b/include/hw/xen/xen-qdisk.h
> > > > @@ -0,0 +1,38 @@
> > > > +/*
> > > > + * Copyright (c) Citrix Systems Inc.
> > > > + * All rights reserved.
> > > > + */
> > > > +
> > > > +#ifndef HW_XEN_QDISK_H
> > > > +#define HW_XEN_QDISK_H
> > > > +
> > > > +#include "hw/xen/xen-bus.h"
> > > > +
> > > > +typedef enum XenQdiskVdevType {
> > > > +    XEN_QDISK_VDEV_TYPE_DP,
> > >
> > > Maybe we could set type_dp value to 1, so that, when vdev->type isn't
> > > set, we can detect it later.
> >
> > Rather than having the 'valid' bool? Yes, that would work.
> 
> Well, the 'valid' bool doesn't seems to always be check so it would be
> better. e.g. xen_qdisk_get_vdev() doesn't check `valid` before
> genereting a string. Then xen_qdisk_set_vdev could set `type` to invalid
> when it is invalid.
> 
> --
> Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 16/18] xen: automatically create XenQdiskDevice-s
  2018-11-21 15:12 ` [Qemu-devel] [PATCH 16/18] xen: automatically create XenQdiskDevice-s Paul Durrant
@ 2018-12-04 16:40     ` Anthony PERARD
  0 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-04 16:40 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Kevin Wolf, Max Reitz,
	Stefano Stabellini

On Wed, Nov 21, 2018 at 03:12:09PM +0000, Paul Durrant wrote:
> This patch adds a creator function for XenQdiskDevice-s so that they can
> be created automatically when the Xen toolstack instantiates a new
> PV backend. When the XenQdiskDevice is created this way it is also
> necessary to create a drive which matches the configuration that the Xen
> toolstack has written into xenstore. This drive is marked 'auto_del' so
> that it will be removed when the XenQdiskDevice is destroyed. Also, for
> compatibilitye with the legacy 'xen_disk' implementation, an iothread
> is automatically created for the new XenQdiskDevice. This will also be
> removed when he XenQdiskDevice is destroyed.

"the XenQdiskDevice"

[...]
> +    qemu_opt_set(drive_opts, "file.locking", "off", &local_err);

That looks new, compared to the xen_disk.c implementation. Maybe that
should be mention in the commit message.


[..]

> +static void xen_qdisk_device_create(BusState *bus, const char *name,
> +                                    QDict *opts, Error **errp)
> +{
[...]
> +    iothread = iothread_create(vdev, &error_abort);

I would just propagate the error, since iothread could fail for external
reason. No need to crash qemu while a VM is running.

> +
> +    dev = qdev_create(bus, TYPE_XEN_QDISK_DEVICE);
> +
> +    qdev_prop_set_string(dev, "vdev", vdev);
> +
> +    if (XEN_QDISK_DEVICE(dev)->vdev.number != number) {
> +        error_setg(errp, "invalid dev parameter '%s'", vdev);
> +        goto unref;
> +    }
> +
> +    qdev_prop_set_drive(dev, "drive", blk, &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        error_prepend(errp, "failed to set 'drive': ");
> +        goto unref;
> +    }
> +
> +    XEN_QDISK_DEVICE(dev)->auto_iothread = iothread;
> +
> +    qdev_init_nofail(dev);

That function shouldn't be use during hotplug. But I'm not sure what
should be done instead, probably object_property_set_bool(..., true
"realized") and check for error.


Thanks,

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 16/18] xen: automatically create XenQdiskDevice-s
@ 2018-12-04 16:40     ` Anthony PERARD
  0 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-04 16:40 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, xen-devel

On Wed, Nov 21, 2018 at 03:12:09PM +0000, Paul Durrant wrote:
> This patch adds a creator function for XenQdiskDevice-s so that they can
> be created automatically when the Xen toolstack instantiates a new
> PV backend. When the XenQdiskDevice is created this way it is also
> necessary to create a drive which matches the configuration that the Xen
> toolstack has written into xenstore. This drive is marked 'auto_del' so
> that it will be removed when the XenQdiskDevice is destroyed. Also, for
> compatibilitye with the legacy 'xen_disk' implementation, an iothread
> is automatically created for the new XenQdiskDevice. This will also be
> removed when he XenQdiskDevice is destroyed.

"the XenQdiskDevice"

[...]
> +    qemu_opt_set(drive_opts, "file.locking", "off", &local_err);

That looks new, compared to the xen_disk.c implementation. Maybe that
should be mention in the commit message.


[..]

> +static void xen_qdisk_device_create(BusState *bus, const char *name,
> +                                    QDict *opts, Error **errp)
> +{
[...]
> +    iothread = iothread_create(vdev, &error_abort);

I would just propagate the error, since iothread could fail for external
reason. No need to crash qemu while a VM is running.

> +
> +    dev = qdev_create(bus, TYPE_XEN_QDISK_DEVICE);
> +
> +    qdev_prop_set_string(dev, "vdev", vdev);
> +
> +    if (XEN_QDISK_DEVICE(dev)->vdev.number != number) {
> +        error_setg(errp, "invalid dev parameter '%s'", vdev);
> +        goto unref;
> +    }
> +
> +    qdev_prop_set_drive(dev, "drive", blk, &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        error_prepend(errp, "failed to set 'drive': ");
> +        goto unref;
> +    }
> +
> +    XEN_QDISK_DEVICE(dev)->auto_iothread = iothread;
> +
> +    qdev_init_nofail(dev);

That function shouldn't be use during hotplug. But I'm not sure what
should be done instead, probably object_property_set_bool(..., true
"realized") and check for error.


Thanks,

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 17/18] MAINTAINERS: add myself as a Xen maintainer
  2018-11-21 15:12   ` Paul Durrant
@ 2018-12-04 16:42     ` Anthony PERARD
  -1 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-04 16:42 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini, Paolo Bonzini

On Wed, Nov 21, 2018 at 03:12:10PM +0000, Paul Durrant wrote:
> I have made many significant contributions to the Xen code in QEMU,
> particularly the recent patches introducing a new PV device framework.
> I intend to make further significant contributions, porting other PV back-
> ends to the new framework with the intent of eventually removing the
> legacy code. It therefore seems reasonable that I become a maintiner of
> the Xen code.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

With the typo fixed:
Acked-by: Anthony PERARD <anthony.perard@citrix.com>

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 17/18] MAINTAINERS: add myself as a Xen maintainer
@ 2018-12-04 16:42     ` Anthony PERARD
  0 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-04 16:42 UTC (permalink / raw)
  To: Paul Durrant
  Cc: xen-devel, Stefano Stabellini, qemu-devel, qemu-block, Paolo Bonzini

On Wed, Nov 21, 2018 at 03:12:10PM +0000, Paul Durrant wrote:
> I have made many significant contributions to the Xen code in QEMU,
> particularly the recent patches introducing a new PV device framework.
> I intend to make further significant contributions, porting other PV back-
> ends to the new framework with the intent of eventually removing the
> legacy code. It therefore seems reasonable that I become a maintiner of
> the Xen code.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

With the typo fixed:
Acked-by: Anthony PERARD <anthony.perard@citrix.com>

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 03/18] xen: introduce 'xen-qdisk'
  2018-12-04 15:20     ` Paul Durrant
  2018-12-04 15:49       ` Anthony PERARD
  2018-12-04 15:49       ` Anthony PERARD
@ 2018-12-04 17:14       ` Paul Durrant
  2018-12-04 17:14       ` Paul Durrant
  3 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-04 17:14 UTC (permalink / raw)
  To: Paul Durrant, Anthony Perard
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, xen-devel

> -----Original Message-----
> From: Qemu-devel [mailto:qemu-devel-
> bounces+paul.durrant=citrix.com@nongnu.org] On Behalf Of Paul Durrant
> Sent: 04 December 2018 15:20
> To: Anthony Perard <anthony.perard@citrix.com>
> Cc: Kevin Wolf <kwolf@redhat.com>; Stefano Stabellini
> <sstabellini@kernel.org>; qemu-block@nongnu.org; qemu-devel@nongnu.org;
> Max Reitz <mreitz@redhat.com>; xen-devel@lists.xenproject.org
> Subject: Re: [Qemu-devel] [PATCH 03/18] xen: introduce 'xen-qdisk'
> 
> > -----Original Message-----
> > From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> > Sent: 29 November 2018 16:06
> > To: Paul Durrant <Paul.Durrant@citrix.com>
> > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > devel@lists.xenproject.org; Kevin Wolf <kwolf@redhat.com>; Max Reitz
> > <mreitz@redhat.com>; Stefano Stabellini <sstabellini@kernel.org>
> > Subject: Re: [PATCH 03/18] xen: introduce 'xen-qdisk'
> >
> > On Wed, Nov 21, 2018 at 03:11:56PM +0000, Paul Durrant wrote:
> > > This patch adds a new XenDevice: 'xen-qdisk' [1]. This will eventually
> > > replace the 'xen_disk' legacy PV backend but it is illustrative to
> build
> > > up the implementation incrementally, along with the XenBus/XenDevice
> > > framework. Subsequent patches will therefore add to this device's
> > > implementation as new features are added to the framework.
> > >
> > > After this patch has been applied it is possible to instantiate a new
> > > 'xen-qdisk' device with a single 'vdev' parameter, which accepts
> values
> > > adhering to the Xen VBD naming scheme [2]. For example, a command-line
> > > instantiation of a xen-qdisk can be done with an argument similar to
> the
> > > following:
> > >
> > > -device xen-qdisk,vdev=hda
> >
> > That works when QEMU boot, but doing the same thing once the guest have
> > booted, via QMP, doesn't. Here is the result (tested in qmp-shell):
> >
> > (QEMU) device_add driver=xen-qdisk vdev=hda
> > {
> >     "error": {
> >         "class": "GenericError",
> >         "desc": "Bus 'xen-bus.0' does not support hotplugging"
> >     }
> > }
> >
> > That's probably why I've asked about the hotplug capability on the
> > previous patch.
> >
> 
> Ok. I've added the hotplug now so I'll make sure QMP DTRT.
> 
> > > The implementation of the vdev parameter formulates the appropriate
> VBD
> > > number for use in the PV protocol.
> > >
> > > [1] The name 'qdisk' as always been the name given to the QEMU
> > >     implementation of the Xen PV block protocol backend implementation
> > > [2] http://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=docs/man/xen-
> vbd-
> > interface.markdown.7
> >
> > Maybe a link to the generated docs would be better:
> > https://xenbits.xen.org/docs/unstable/man/xen-vbd-interface.7.html
> >
> 
> Ok.
> 
> > Also, it would be useful to have the same link in the source code.
> >
> 
> Yes, I'll add a comment.
> 
> > > diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> > > new file mode 100644
> > > index 0000000000..72122073f7
> > > --- /dev/null
> > > +++ b/hw/block/xen-qdisk.c
> > [...]
> > > +static char *disk_to_vbd_name(unsigned int disk)
> > > +{
> > > +    unsigned int len = DIV_ROUND_UP(disk, 26);
> > > +    char *name = g_malloc0(len + 1);
> > > +
> > > +    do {
> > > +        name[len--] = 'a' + (disk % 26);
> > > +        disk /= 26;
> > > +    } while (disk != 0);
> > > +    assert(len == 0);
> > > +
> > > +    return name;
> > > +}
> >
> > That function doesn't work.
> >
> > For a simple xvdp, (so disk==15), it return "", I mean "\0p".
> >
> > For a more complicated 'xvdbhwza', we have len == 22901. And the assert
> > failed.
> >
> > Maybe the recursing algo in libxl would be fine, with a buffer that is
> > big enough, and could probably be on the stack (in _get_vdev).
> 
> I used libxl__device_disk_dev_number() as my model (as well as cross-
> checking with the spec), but I guess a recursing algorithm would be
> neater.
> 
> >
> > > +
> > > +    switch (vdev->type) {
> > > +    case XEN_QDISK_VDEV_TYPE_DP:
> > > +    case XEN_QDISK_VDEV_TYPE_XVD:
> > > +        if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) {
> > > +            vdev->number = (202 << 8) | (vdev->disk << 4) |
> > > +                vdev->partition;
> > > +        } else if (vdev->disk < (1 << 20) && vdev->partition < (1 <<
> > 8)) {
> > > +            vdev->number = (1 << 28) | (vdev->disk << 8) |
> > > +                vdev->partition;
> > > +        } else {
> > > +            goto invalid;
> > > +        }
> > > +        break;
> > > +
> > > +    case XEN_QDISK_VDEV_TYPE_HD:
> > > +        if ((vdev->disk == 0 || vdev->disk == 1) &&
> > > +            vdev->partition < (1 << 4)) {
> >
> > I think that should be:
> >
> >     vdev->partition < (1 << 6)
> >
> > Because hd disk have 0..63 partitions.
> 
> Yes, I must have typo-ed it...
> 
> >
> > > +            vdev->number = (3 << 8) | (vdev->disk << 6) | vdev-
> > >partition;
> > > +        } else if ((vdev->disk == 2 || vdev->disk == 3) &&
> > > +                   vdev->partition < (1 << 4)) {
> >
> > same here.
> 
> ...and then cut'n'pasted.
> 
> >
> > > +            vdev->number = (22 << 8) | ((vdev->disk - 2) << 6) |
> > > +                vdev->partition;
> > > +        } else {
> > > +            goto invalid;
> > > +        }
> > > +        break;
> > > +
> > > +    case XEN_QDISK_VDEV_TYPE_SD:
> > > +        if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) {
> > > +            vdev->number = (8 << 8) | (vdev->disk << 4) | vdev-
> > >partition;
> > > +        } else {
> > > +            goto invalid;
> > > +        }
> > > +        break;
> > > +
> > > +    default:
> > > +        goto invalid;
> > > +    }
> > > +
> > > +    g_free(str);
> > > +    vdev->valid = true;
> > > +    return;
> > > +
> > > +invalid:
> > > +    error_setg(errp, "invalid virtual disk specifier");
> > > +    g_free(str);
> >
> > :(, g_free is called twice.
> 
> Oops. Good catch.

Oh, I thought you'd found a double free...

> 
> >
> > maybe we could have:
> >     vdev->valid=true;
> >     out:
> >       if (!vdev->valid)
> >         error_setg(...);
> >       g_free;

No, that's quite convoluted. I prefer separate 'fail' and 'success' paths, even if they both need to call g_free().

  Paul

> >
> > > diff --git a/include/hw/xen/xen-qdisk.h b/include/hw/xen/xen-qdisk.h
> > > new file mode 100644
> > > index 0000000000..ade0866037
> > > --- /dev/null
> > > +++ b/include/hw/xen/xen-qdisk.h
> > > @@ -0,0 +1,38 @@
> > > +/*
> > > + * Copyright (c) Citrix Systems Inc.
> > > + * All rights reserved.
> > > + */
> > > +
> > > +#ifndef HW_XEN_QDISK_H
> > > +#define HW_XEN_QDISK_H
> > > +
> > > +#include "hw/xen/xen-bus.h"
> > > +
> > > +typedef enum XenQdiskVdevType {
> > > +    XEN_QDISK_VDEV_TYPE_DP,
> >
> > Maybe we could set type_dp value to 1, so that, when vdev->type isn't
> > set, we can detect it later.
> 
> Rather than having the 'valid' bool? Yes, that would work.
> 
>   Paul
> 
> >
> >
> > > +    XEN_QDISK_VDEV_TYPE_XVD,
> > > +    XEN_QDISK_VDEV_TYPE_HD,
> > > +    XEN_QDISK_VDEV_TYPE_SD,
> > > +    XEN_QDISK_VDEV_TYPE__MAX
> > > +} XenQdiskVdevType;
> >
> > Thanks,
> >
> > --
> > Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 03/18] xen: introduce 'xen-qdisk'
  2018-12-04 15:20     ` Paul Durrant
                         ` (2 preceding siblings ...)
  2018-12-04 17:14       ` [Qemu-devel] " Paul Durrant
@ 2018-12-04 17:14       ` Paul Durrant
  3 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-04 17:14 UTC (permalink / raw)
  To: Paul Durrant, Anthony Perard
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, xen-devel

> -----Original Message-----
> From: Qemu-devel [mailto:qemu-devel-
> bounces+paul.durrant=citrix.com@nongnu.org] On Behalf Of Paul Durrant
> Sent: 04 December 2018 15:20
> To: Anthony Perard <anthony.perard@citrix.com>
> Cc: Kevin Wolf <kwolf@redhat.com>; Stefano Stabellini
> <sstabellini@kernel.org>; qemu-block@nongnu.org; qemu-devel@nongnu.org;
> Max Reitz <mreitz@redhat.com>; xen-devel@lists.xenproject.org
> Subject: Re: [Qemu-devel] [PATCH 03/18] xen: introduce 'xen-qdisk'
> 
> > -----Original Message-----
> > From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> > Sent: 29 November 2018 16:06
> > To: Paul Durrant <Paul.Durrant@citrix.com>
> > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > devel@lists.xenproject.org; Kevin Wolf <kwolf@redhat.com>; Max Reitz
> > <mreitz@redhat.com>; Stefano Stabellini <sstabellini@kernel.org>
> > Subject: Re: [PATCH 03/18] xen: introduce 'xen-qdisk'
> >
> > On Wed, Nov 21, 2018 at 03:11:56PM +0000, Paul Durrant wrote:
> > > This patch adds a new XenDevice: 'xen-qdisk' [1]. This will eventually
> > > replace the 'xen_disk' legacy PV backend but it is illustrative to
> build
> > > up the implementation incrementally, along with the XenBus/XenDevice
> > > framework. Subsequent patches will therefore add to this device's
> > > implementation as new features are added to the framework.
> > >
> > > After this patch has been applied it is possible to instantiate a new
> > > 'xen-qdisk' device with a single 'vdev' parameter, which accepts
> values
> > > adhering to the Xen VBD naming scheme [2]. For example, a command-line
> > > instantiation of a xen-qdisk can be done with an argument similar to
> the
> > > following:
> > >
> > > -device xen-qdisk,vdev=hda
> >
> > That works when QEMU boot, but doing the same thing once the guest have
> > booted, via QMP, doesn't. Here is the result (tested in qmp-shell):
> >
> > (QEMU) device_add driver=xen-qdisk vdev=hda
> > {
> >     "error": {
> >         "class": "GenericError",
> >         "desc": "Bus 'xen-bus.0' does not support hotplugging"
> >     }
> > }
> >
> > That's probably why I've asked about the hotplug capability on the
> > previous patch.
> >
> 
> Ok. I've added the hotplug now so I'll make sure QMP DTRT.
> 
> > > The implementation of the vdev parameter formulates the appropriate
> VBD
> > > number for use in the PV protocol.
> > >
> > > [1] The name 'qdisk' as always been the name given to the QEMU
> > >     implementation of the Xen PV block protocol backend implementation
> > > [2] http://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=docs/man/xen-
> vbd-
> > interface.markdown.7
> >
> > Maybe a link to the generated docs would be better:
> > https://xenbits.xen.org/docs/unstable/man/xen-vbd-interface.7.html
> >
> 
> Ok.
> 
> > Also, it would be useful to have the same link in the source code.
> >
> 
> Yes, I'll add a comment.
> 
> > > diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> > > new file mode 100644
> > > index 0000000000..72122073f7
> > > --- /dev/null
> > > +++ b/hw/block/xen-qdisk.c
> > [...]
> > > +static char *disk_to_vbd_name(unsigned int disk)
> > > +{
> > > +    unsigned int len = DIV_ROUND_UP(disk, 26);
> > > +    char *name = g_malloc0(len + 1);
> > > +
> > > +    do {
> > > +        name[len--] = 'a' + (disk % 26);
> > > +        disk /= 26;
> > > +    } while (disk != 0);
> > > +    assert(len == 0);
> > > +
> > > +    return name;
> > > +}
> >
> > That function doesn't work.
> >
> > For a simple xvdp, (so disk==15), it return "", I mean "\0p".
> >
> > For a more complicated 'xvdbhwza', we have len == 22901. And the assert
> > failed.
> >
> > Maybe the recursing algo in libxl would be fine, with a buffer that is
> > big enough, and could probably be on the stack (in _get_vdev).
> 
> I used libxl__device_disk_dev_number() as my model (as well as cross-
> checking with the spec), but I guess a recursing algorithm would be
> neater.
> 
> >
> > > +
> > > +    switch (vdev->type) {
> > > +    case XEN_QDISK_VDEV_TYPE_DP:
> > > +    case XEN_QDISK_VDEV_TYPE_XVD:
> > > +        if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) {
> > > +            vdev->number = (202 << 8) | (vdev->disk << 4) |
> > > +                vdev->partition;
> > > +        } else if (vdev->disk < (1 << 20) && vdev->partition < (1 <<
> > 8)) {
> > > +            vdev->number = (1 << 28) | (vdev->disk << 8) |
> > > +                vdev->partition;
> > > +        } else {
> > > +            goto invalid;
> > > +        }
> > > +        break;
> > > +
> > > +    case XEN_QDISK_VDEV_TYPE_HD:
> > > +        if ((vdev->disk == 0 || vdev->disk == 1) &&
> > > +            vdev->partition < (1 << 4)) {
> >
> > I think that should be:
> >
> >     vdev->partition < (1 << 6)
> >
> > Because hd disk have 0..63 partitions.
> 
> Yes, I must have typo-ed it...
> 
> >
> > > +            vdev->number = (3 << 8) | (vdev->disk << 6) | vdev-
> > >partition;
> > > +        } else if ((vdev->disk == 2 || vdev->disk == 3) &&
> > > +                   vdev->partition < (1 << 4)) {
> >
> > same here.
> 
> ...and then cut'n'pasted.
> 
> >
> > > +            vdev->number = (22 << 8) | ((vdev->disk - 2) << 6) |
> > > +                vdev->partition;
> > > +        } else {
> > > +            goto invalid;
> > > +        }
> > > +        break;
> > > +
> > > +    case XEN_QDISK_VDEV_TYPE_SD:
> > > +        if (vdev->disk < (1 << 4) && vdev->partition < (1 << 4)) {
> > > +            vdev->number = (8 << 8) | (vdev->disk << 4) | vdev-
> > >partition;
> > > +        } else {
> > > +            goto invalid;
> > > +        }
> > > +        break;
> > > +
> > > +    default:
> > > +        goto invalid;
> > > +    }
> > > +
> > > +    g_free(str);
> > > +    vdev->valid = true;
> > > +    return;
> > > +
> > > +invalid:
> > > +    error_setg(errp, "invalid virtual disk specifier");
> > > +    g_free(str);
> >
> > :(, g_free is called twice.
> 
> Oops. Good catch.

Oh, I thought you'd found a double free...

> 
> >
> > maybe we could have:
> >     vdev->valid=true;
> >     out:
> >       if (!vdev->valid)
> >         error_setg(...);
> >       g_free;

No, that's quite convoluted. I prefer separate 'fail' and 'success' paths, even if they both need to call g_free().

  Paul

> >
> > > diff --git a/include/hw/xen/xen-qdisk.h b/include/hw/xen/xen-qdisk.h
> > > new file mode 100644
> > > index 0000000000..ade0866037
> > > --- /dev/null
> > > +++ b/include/hw/xen/xen-qdisk.h
> > > @@ -0,0 +1,38 @@
> > > +/*
> > > + * Copyright (c) Citrix Systems Inc.
> > > + * All rights reserved.
> > > + */
> > > +
> > > +#ifndef HW_XEN_QDISK_H
> > > +#define HW_XEN_QDISK_H
> > > +
> > > +#include "hw/xen/xen-bus.h"
> > > +
> > > +typedef enum XenQdiskVdevType {
> > > +    XEN_QDISK_VDEV_TYPE_DP,
> >
> > Maybe we could set type_dp value to 1, so that, when vdev->type isn't
> > set, we can detect it later.
> 
> Rather than having the 'valid' bool? Yes, that would work.
> 
>   Paul
> 
> >
> >
> > > +    XEN_QDISK_VDEV_TYPE_XVD,
> > > +    XEN_QDISK_VDEV_TYPE_HD,
> > > +    XEN_QDISK_VDEV_TYPE_SD,
> > > +    XEN_QDISK_VDEV_TYPE__MAX
> > > +} XenQdiskVdevType;
> >
> > Thanks,
> >
> > --
> > Anthony PERARD


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 04/18] xen: create xenstore areas for XenDevice-s
  2018-11-29 18:48   ` [Qemu-devel] " Anthony PERARD
@ 2018-12-05 12:05     ` Paul Durrant
  2018-12-05 12:43       ` Paul Durrant
                         ` (3 more replies)
  2018-12-05 12:05     ` Paul Durrant
  1 sibling, 4 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-05 12:05 UTC (permalink / raw)
  To: Anthony Perard
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Kevin Wolf, Max Reitz

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 29 November 2018 18:49
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> Kevin Wolf <kwolf@redhat.com>; Max Reitz <mreitz@redhat.com>
> Subject: Re: [PATCH 04/18] xen: create xenstore areas for XenDevice-s
> 
> On Wed, Nov 21, 2018 at 03:11:57PM +0000, Paul Durrant wrote:
> > This patch adds a new source module, xen-bus-helper.c, which builds on
> > basic libxenstore primitives to provide functions to create (setting
> > permissions appropriately) and destroy xenstore areas, and functions to
> > 'printf' and 'scanf' nodes therein. The main xen-bus code then uses
> > these primitives [1] to initialize and destroy the frontend and backend
> > areas for a XenDevice during realize and unrealize respectively.
> >
> > The 'xen-qdisk' implementation is extended with a 'get_name' method that
> > returns the VBD number. This number is reqired to 'name' the xenstore
> 
>                                          ^ required
> 

Ok.

> > diff --git a/hw/xen/xen-bus-helper.c b/hw/xen/xen-bus-helper.c
> > new file mode 100644
> > index 0000000000..d9ee2ed6a0
> > --- /dev/null
> > +++ b/hw/xen/xen-bus-helper.c
> [...]
> > +void xs_node_destroy(struct xs_handle *xsh, const char *node)
> > +{
> > +    xs_rm(xsh, XBT_NULL, node);
> 
> We should check for error, and grab errno.
> 

I'll make all of them fill in an Error *

> > +}
> > +
> > +void xs_node_vprintf(struct xs_handle *xsh, const char *node,
> > +                     const char *key, const char *fmt, va_list ap)
> > +{
> > +    char *path, *value;
> > +
> > +    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
> > +        g_strdup(key);
> 
> A comment would be helpful to findout how to use that function,
> especialy the fact that with node="", we write to $key instead of
> $node/$key.

Ok, I'll add comments into the header.

> 
> > +    value = g_strdup_vprintf(fmt, ap);
> 
> Looks like g_vasprintf() would be better, since it returns the lenght as
> well.
> 

Yes.

> > +
> > +    xs_write(xsh, XBT_NULL, path, value, strlen(value));
> 
> You should check for failures, and grab errno.
> 
> > +    g_free(value);
> > +    g_free(path);
> > +}
> > +
> > +int xs_node_vscanf(struct xs_handle *xsh, const char *node, const char
> *key,
> > +                   const char *fmt, va_list ap)
> > +{
> > +    char *path, *value;
> > +    int rc;
> > +
> > +    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
> > +        g_strdup(key);
> > +
> > +    value = xs_read(xsh, XBT_NULL, path, NULL);
> 
> The xenstore.h isn't clear about failure of this function, it is
> supposed to return a malloced value. Do we actually need to check if value
> is NULL?

The comment above xs_read() in xs.c is:

/* Get the value of a single file, nul terminated.                          
 * Returns a malloced value: call free() on it after use.                   
 * len indicates length in bytes, not including the nul.                    
 */

and I think we should check it for NULL before passing it to vsscanf().

> 
> > +
> > +    rc = value ? vsscanf(value, fmt, ap) : EOF;
> > +
> > +    free(value);
> > +    g_free(path);
> > +
> > +    return rc;
> > +}
> > +
> > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > index dede2d914a..663aa8e117 100644
> > --- a/hw/xen/xen-bus.c
> > +++ b/hw/xen/xen-bus.c
> [...]
> 
> > +static void xen_device_backend_destroy(XenDevice *xendev)
> > +{
> > +    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
> > +
> > +    if (!xendev->backend_path) {
> > +        return;
> > +    }
> > +
> > +    g_assert(xenbus->xsh);
> > +
> > +    xs_node_destroy(xenbus->xsh, xendev->backend_path);
> > +    g_free(xendev->backend_path);
> 
> It would be nice to also set backend_path to NULL.
> 

Yes, it should be for idempotency.

> > diff --git a/include/hw/xen/xen-bus-helper.h b/include/hw/xen/xen-bus-
> helper.h
> > new file mode 100644
> > index 0000000000..53570650db
> > --- /dev/null
> > +++ b/include/hw/xen/xen-bus-helper.h
> > @@ -0,0 +1,26 @@
> > +/*
> > + * Copyright (c) Citrix Systems Inc.
> > + * All rights reserved.
> > + */
> > +
> > +#ifndef HW_XEN_BUS_HELPER_H
> > +#define HW_XEN_BUS_HELPER_H
> 
> That should probably include xen_common.h, to have `enum xenbus_state`,
> `struct xs_handle`, ..

Ok.

> 
> > +const char *xs_strstate(enum xenbus_state state);
> > +
> > +void xs_node_create(struct xs_handle *xsh, const char *node,
> > +                    struct xs_permissions perms[],
> > +                    unsigned int nr_perms, Error **errp);
> > +void xs_node_destroy(struct xs_handle *xsh, const char *node);
> > +
> > +void xs_node_vprintf(struct xs_handle *xsh, const char *node,
> > +                     const char *key, const char *fmt, va_list ap);
> > +void xs_node_printf(struct xs_handle *xsh, const char *node, const char
> *key,
> > +                    const char *fmt, ...);
> 
> This prototype needs GCC_FMT_ATTR(), that's the printf format
> __attribute__.
> 
> > +
> > +int xs_node_vscanf(struct xs_handle *xsh, const char *node, const char
> *key,
> > +                   const char *fmt, va_list ap);
> > +int xs_node_scanf(struct xs_handle *xsh, const char *node, const char
> *key,
> > +                  const char *fmt, ...);
> 
> Maybe here as well.

Will do.

 Paul

> 
> 
> --
> Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 04/18] xen: create xenstore areas for XenDevice-s
  2018-11-29 18:48   ` [Qemu-devel] " Anthony PERARD
  2018-12-05 12:05     ` Paul Durrant
@ 2018-12-05 12:05     ` Paul Durrant
  1 sibling, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-05 12:05 UTC (permalink / raw)
  To: Anthony Perard
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, xen-devel

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 29 November 2018 18:49
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> Kevin Wolf <kwolf@redhat.com>; Max Reitz <mreitz@redhat.com>
> Subject: Re: [PATCH 04/18] xen: create xenstore areas for XenDevice-s
> 
> On Wed, Nov 21, 2018 at 03:11:57PM +0000, Paul Durrant wrote:
> > This patch adds a new source module, xen-bus-helper.c, which builds on
> > basic libxenstore primitives to provide functions to create (setting
> > permissions appropriately) and destroy xenstore areas, and functions to
> > 'printf' and 'scanf' nodes therein. The main xen-bus code then uses
> > these primitives [1] to initialize and destroy the frontend and backend
> > areas for a XenDevice during realize and unrealize respectively.
> >
> > The 'xen-qdisk' implementation is extended with a 'get_name' method that
> > returns the VBD number. This number is reqired to 'name' the xenstore
> 
>                                          ^ required
> 

Ok.

> > diff --git a/hw/xen/xen-bus-helper.c b/hw/xen/xen-bus-helper.c
> > new file mode 100644
> > index 0000000000..d9ee2ed6a0
> > --- /dev/null
> > +++ b/hw/xen/xen-bus-helper.c
> [...]
> > +void xs_node_destroy(struct xs_handle *xsh, const char *node)
> > +{
> > +    xs_rm(xsh, XBT_NULL, node);
> 
> We should check for error, and grab errno.
> 

I'll make all of them fill in an Error *

> > +}
> > +
> > +void xs_node_vprintf(struct xs_handle *xsh, const char *node,
> > +                     const char *key, const char *fmt, va_list ap)
> > +{
> > +    char *path, *value;
> > +
> > +    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
> > +        g_strdup(key);
> 
> A comment would be helpful to findout how to use that function,
> especialy the fact that with node="", we write to $key instead of
> $node/$key.

Ok, I'll add comments into the header.

> 
> > +    value = g_strdup_vprintf(fmt, ap);
> 
> Looks like g_vasprintf() would be better, since it returns the lenght as
> well.
> 

Yes.

> > +
> > +    xs_write(xsh, XBT_NULL, path, value, strlen(value));
> 
> You should check for failures, and grab errno.
> 
> > +    g_free(value);
> > +    g_free(path);
> > +}
> > +
> > +int xs_node_vscanf(struct xs_handle *xsh, const char *node, const char
> *key,
> > +                   const char *fmt, va_list ap)
> > +{
> > +    char *path, *value;
> > +    int rc;
> > +
> > +    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
> > +        g_strdup(key);
> > +
> > +    value = xs_read(xsh, XBT_NULL, path, NULL);
> 
> The xenstore.h isn't clear about failure of this function, it is
> supposed to return a malloced value. Do we actually need to check if value
> is NULL?

The comment above xs_read() in xs.c is:

/* Get the value of a single file, nul terminated.                          
 * Returns a malloced value: call free() on it after use.                   
 * len indicates length in bytes, not including the nul.                    
 */

and I think we should check it for NULL before passing it to vsscanf().

> 
> > +
> > +    rc = value ? vsscanf(value, fmt, ap) : EOF;
> > +
> > +    free(value);
> > +    g_free(path);
> > +
> > +    return rc;
> > +}
> > +
> > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > index dede2d914a..663aa8e117 100644
> > --- a/hw/xen/xen-bus.c
> > +++ b/hw/xen/xen-bus.c
> [...]
> 
> > +static void xen_device_backend_destroy(XenDevice *xendev)
> > +{
> > +    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
> > +
> > +    if (!xendev->backend_path) {
> > +        return;
> > +    }
> > +
> > +    g_assert(xenbus->xsh);
> > +
> > +    xs_node_destroy(xenbus->xsh, xendev->backend_path);
> > +    g_free(xendev->backend_path);
> 
> It would be nice to also set backend_path to NULL.
> 

Yes, it should be for idempotency.

> > diff --git a/include/hw/xen/xen-bus-helper.h b/include/hw/xen/xen-bus-
> helper.h
> > new file mode 100644
> > index 0000000000..53570650db
> > --- /dev/null
> > +++ b/include/hw/xen/xen-bus-helper.h
> > @@ -0,0 +1,26 @@
> > +/*
> > + * Copyright (c) Citrix Systems Inc.
> > + * All rights reserved.
> > + */
> > +
> > +#ifndef HW_XEN_BUS_HELPER_H
> > +#define HW_XEN_BUS_HELPER_H
> 
> That should probably include xen_common.h, to have `enum xenbus_state`,
> `struct xs_handle`, ..

Ok.

> 
> > +const char *xs_strstate(enum xenbus_state state);
> > +
> > +void xs_node_create(struct xs_handle *xsh, const char *node,
> > +                    struct xs_permissions perms[],
> > +                    unsigned int nr_perms, Error **errp);
> > +void xs_node_destroy(struct xs_handle *xsh, const char *node);
> > +
> > +void xs_node_vprintf(struct xs_handle *xsh, const char *node,
> > +                     const char *key, const char *fmt, va_list ap);
> > +void xs_node_printf(struct xs_handle *xsh, const char *node, const char
> *key,
> > +                    const char *fmt, ...);
> 
> This prototype needs GCC_FMT_ATTR(), that's the printf format
> __attribute__.
> 
> > +
> > +int xs_node_vscanf(struct xs_handle *xsh, const char *node, const char
> *key,
> > +                   const char *fmt, va_list ap);
> > +int xs_node_scanf(struct xs_handle *xsh, const char *node, const char
> *key,
> > +                  const char *fmt, ...);
> 
> Maybe here as well.

Will do.

 Paul

> 
> 
> --
> Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 04/18] xen: create xenstore areas for XenDevice-s
  2018-12-05 12:05     ` Paul Durrant
  2018-12-05 12:43       ` Paul Durrant
@ 2018-12-05 12:43       ` Paul Durrant
  2018-12-05 13:58         ` Anthony PERARD
  2018-12-05 13:58         ` Anthony PERARD
  2018-12-05 16:28       ` Anthony PERARD
  2018-12-05 16:28       ` [Qemu-devel] " Anthony PERARD
  3 siblings, 2 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-05 12:43 UTC (permalink / raw)
  To: Paul Durrant, Anthony Perard
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, xen-devel

> -----Original Message-----
> From: Qemu-devel [mailto:qemu-devel-
> bounces+paul.durrant=citrix.com@nongnu.org] On Behalf Of Paul Durrant
> Sent: 05 December 2018 12:05
> To: Anthony Perard <anthony.perard@citrix.com>
> Cc: Kevin Wolf <kwolf@redhat.com>; Stefano Stabellini
> <sstabellini@kernel.org>; qemu-block@nongnu.org; qemu-devel@nongnu.org;
> Max Reitz <mreitz@redhat.com>; xen-devel@lists.xenproject.org
> Subject: Re: [Qemu-devel] [PATCH 04/18] xen: create xenstore areas for
> XenDevice-s
> 
> > -----Original Message-----
> > From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> > Sent: 29 November 2018 18:49
> > To: Paul Durrant <Paul.Durrant@citrix.com>
> > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> > Kevin Wolf <kwolf@redhat.com>; Max Reitz <mreitz@redhat.com>
> > Subject: Re: [PATCH 04/18] xen: create xenstore areas for XenDevice-s
> >
> > On Wed, Nov 21, 2018 at 03:11:57PM +0000, Paul Durrant wrote:
> > > This patch adds a new source module, xen-bus-helper.c, which builds on
> > > basic libxenstore primitives to provide functions to create (setting
> > > permissions appropriately) and destroy xenstore areas, and functions
> to
> > > 'printf' and 'scanf' nodes therein. The main xen-bus code then uses
> > > these primitives [1] to initialize and destroy the frontend and
> backend
> > > areas for a XenDevice during realize and unrealize respectively.
> > >
> > > The 'xen-qdisk' implementation is extended with a 'get_name' method
> that
> > > returns the VBD number. This number is reqired to 'name' the xenstore
> >
> >                                          ^ required
> >
> 
> Ok.
> 
> > > diff --git a/hw/xen/xen-bus-helper.c b/hw/xen/xen-bus-helper.c
> > > new file mode 100644
> > > index 0000000000..d9ee2ed6a0
> > > --- /dev/null
> > > +++ b/hw/xen/xen-bus-helper.c
> > [...]
> > > +void xs_node_destroy(struct xs_handle *xsh, const char *node)
> > > +{
> > > +    xs_rm(xsh, XBT_NULL, node);
> >
> > We should check for error, and grab errno.
> >
> 
> I'll make all of them fill in an Error *
> 
> > > +}
> > > +
> > > +void xs_node_vprintf(struct xs_handle *xsh, const char *node,
> > > +                     const char *key, const char *fmt, va_list ap)
> > > +{
> > > +    char *path, *value;
> > > +
> > > +    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key)
> :
> > > +        g_strdup(key);
> >
> > A comment would be helpful to findout how to use that function,
> > especialy the fact that with node="", we write to $key instead of
> > $node/$key.
> 
> Ok, I'll add comments into the header.
> 
> >
> > > +    value = g_strdup_vprintf(fmt, ap);
> >
> > Looks like g_vasprintf() would be better, since it returns the lenght as
> > well.
> >
> 
> Yes.

I tried this and it appears not to exist in the version of glib in my environment so I guess I'll stick with g_strdup_printf().

  Paul

> 
> > > +
> > > +    xs_write(xsh, XBT_NULL, path, value, strlen(value));
> >
> > You should check for failures, and grab errno.
> >
> > > +    g_free(value);
> > > +    g_free(path);
> > > +}
> > > +
> > > +int xs_node_vscanf(struct xs_handle *xsh, const char *node, const
> char
> > *key,
> > > +                   const char *fmt, va_list ap)
> > > +{
> > > +    char *path, *value;
> > > +    int rc;
> > > +
> > > +    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key)
> :
> > > +        g_strdup(key);
> > > +
> > > +    value = xs_read(xsh, XBT_NULL, path, NULL);
> >
> > The xenstore.h isn't clear about failure of this function, it is
> > supposed to return a malloced value. Do we actually need to check if
> value
> > is NULL?
> 
> The comment above xs_read() in xs.c is:
> 
> /* Get the value of a single file, nul terminated.
>  * Returns a malloced value: call free() on it after use.
>  * len indicates length in bytes, not including the nul.
>  */
> 
> and I think we should check it for NULL before passing it to vsscanf().
> 
> >
> > > +
> > > +    rc = value ? vsscanf(value, fmt, ap) : EOF;
> > > +
> > > +    free(value);
> > > +    g_free(path);
> > > +
> > > +    return rc;
> > > +}
> > > +
> > > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > > index dede2d914a..663aa8e117 100644
> > > --- a/hw/xen/xen-bus.c
> > > +++ b/hw/xen/xen-bus.c
> > [...]
> >
> > > +static void xen_device_backend_destroy(XenDevice *xendev)
> > > +{
> > > +    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
> > > +
> > > +    if (!xendev->backend_path) {
> > > +        return;
> > > +    }
> > > +
> > > +    g_assert(xenbus->xsh);
> > > +
> > > +    xs_node_destroy(xenbus->xsh, xendev->backend_path);
> > > +    g_free(xendev->backend_path);
> >
> > It would be nice to also set backend_path to NULL.
> >
> 
> Yes, it should be for idempotency.
> 
> > > diff --git a/include/hw/xen/xen-bus-helper.h b/include/hw/xen/xen-bus-
> > helper.h
> > > new file mode 100644
> > > index 0000000000..53570650db
> > > --- /dev/null
> > > +++ b/include/hw/xen/xen-bus-helper.h
> > > @@ -0,0 +1,26 @@
> > > +/*
> > > + * Copyright (c) Citrix Systems Inc.
> > > + * All rights reserved.
> > > + */
> > > +
> > > +#ifndef HW_XEN_BUS_HELPER_H
> > > +#define HW_XEN_BUS_HELPER_H
> >
> > That should probably include xen_common.h, to have `enum xenbus_state`,
> > `struct xs_handle`, ..
> 
> Ok.
> 
> >
> > > +const char *xs_strstate(enum xenbus_state state);
> > > +
> > > +void xs_node_create(struct xs_handle *xsh, const char *node,
> > > +                    struct xs_permissions perms[],
> > > +                    unsigned int nr_perms, Error **errp);
> > > +void xs_node_destroy(struct xs_handle *xsh, const char *node);
> > > +
> > > +void xs_node_vprintf(struct xs_handle *xsh, const char *node,
> > > +                     const char *key, const char *fmt, va_list ap);
> > > +void xs_node_printf(struct xs_handle *xsh, const char *node, const
> char
> > *key,
> > > +                    const char *fmt, ...);
> >
> > This prototype needs GCC_FMT_ATTR(), that's the printf format
> > __attribute__.
> >
> > > +
> > > +int xs_node_vscanf(struct xs_handle *xsh, const char *node, const
> char
> > *key,
> > > +                   const char *fmt, va_list ap);
> > > +int xs_node_scanf(struct xs_handle *xsh, const char *node, const char
> > *key,
> > > +                  const char *fmt, ...);
> >
> > Maybe here as well.
> 
> Will do.
> 
>  Paul
> 
> >
> >
> > --
> > Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 04/18] xen: create xenstore areas for XenDevice-s
  2018-12-05 12:05     ` Paul Durrant
@ 2018-12-05 12:43       ` Paul Durrant
  2018-12-05 12:43       ` [Qemu-devel] " Paul Durrant
                         ` (2 subsequent siblings)
  3 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-05 12:43 UTC (permalink / raw)
  To: Paul Durrant, Anthony Perard
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, xen-devel

> -----Original Message-----
> From: Qemu-devel [mailto:qemu-devel-
> bounces+paul.durrant=citrix.com@nongnu.org] On Behalf Of Paul Durrant
> Sent: 05 December 2018 12:05
> To: Anthony Perard <anthony.perard@citrix.com>
> Cc: Kevin Wolf <kwolf@redhat.com>; Stefano Stabellini
> <sstabellini@kernel.org>; qemu-block@nongnu.org; qemu-devel@nongnu.org;
> Max Reitz <mreitz@redhat.com>; xen-devel@lists.xenproject.org
> Subject: Re: [Qemu-devel] [PATCH 04/18] xen: create xenstore areas for
> XenDevice-s
> 
> > -----Original Message-----
> > From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> > Sent: 29 November 2018 18:49
> > To: Paul Durrant <Paul.Durrant@citrix.com>
> > Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> > devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> > Kevin Wolf <kwolf@redhat.com>; Max Reitz <mreitz@redhat.com>
> > Subject: Re: [PATCH 04/18] xen: create xenstore areas for XenDevice-s
> >
> > On Wed, Nov 21, 2018 at 03:11:57PM +0000, Paul Durrant wrote:
> > > This patch adds a new source module, xen-bus-helper.c, which builds on
> > > basic libxenstore primitives to provide functions to create (setting
> > > permissions appropriately) and destroy xenstore areas, and functions
> to
> > > 'printf' and 'scanf' nodes therein. The main xen-bus code then uses
> > > these primitives [1] to initialize and destroy the frontend and
> backend
> > > areas for a XenDevice during realize and unrealize respectively.
> > >
> > > The 'xen-qdisk' implementation is extended with a 'get_name' method
> that
> > > returns the VBD number. This number is reqired to 'name' the xenstore
> >
> >                                          ^ required
> >
> 
> Ok.
> 
> > > diff --git a/hw/xen/xen-bus-helper.c b/hw/xen/xen-bus-helper.c
> > > new file mode 100644
> > > index 0000000000..d9ee2ed6a0
> > > --- /dev/null
> > > +++ b/hw/xen/xen-bus-helper.c
> > [...]
> > > +void xs_node_destroy(struct xs_handle *xsh, const char *node)
> > > +{
> > > +    xs_rm(xsh, XBT_NULL, node);
> >
> > We should check for error, and grab errno.
> >
> 
> I'll make all of them fill in an Error *
> 
> > > +}
> > > +
> > > +void xs_node_vprintf(struct xs_handle *xsh, const char *node,
> > > +                     const char *key, const char *fmt, va_list ap)
> > > +{
> > > +    char *path, *value;
> > > +
> > > +    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key)
> :
> > > +        g_strdup(key);
> >
> > A comment would be helpful to findout how to use that function,
> > especialy the fact that with node="", we write to $key instead of
> > $node/$key.
> 
> Ok, I'll add comments into the header.
> 
> >
> > > +    value = g_strdup_vprintf(fmt, ap);
> >
> > Looks like g_vasprintf() would be better, since it returns the lenght as
> > well.
> >
> 
> Yes.

I tried this and it appears not to exist in the version of glib in my environment so I guess I'll stick with g_strdup_printf().

  Paul

> 
> > > +
> > > +    xs_write(xsh, XBT_NULL, path, value, strlen(value));
> >
> > You should check for failures, and grab errno.
> >
> > > +    g_free(value);
> > > +    g_free(path);
> > > +}
> > > +
> > > +int xs_node_vscanf(struct xs_handle *xsh, const char *node, const
> char
> > *key,
> > > +                   const char *fmt, va_list ap)
> > > +{
> > > +    char *path, *value;
> > > +    int rc;
> > > +
> > > +    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key)
> :
> > > +        g_strdup(key);
> > > +
> > > +    value = xs_read(xsh, XBT_NULL, path, NULL);
> >
> > The xenstore.h isn't clear about failure of this function, it is
> > supposed to return a malloced value. Do we actually need to check if
> value
> > is NULL?
> 
> The comment above xs_read() in xs.c is:
> 
> /* Get the value of a single file, nul terminated.
>  * Returns a malloced value: call free() on it after use.
>  * len indicates length in bytes, not including the nul.
>  */
> 
> and I think we should check it for NULL before passing it to vsscanf().
> 
> >
> > > +
> > > +    rc = value ? vsscanf(value, fmt, ap) : EOF;
> > > +
> > > +    free(value);
> > > +    g_free(path);
> > > +
> > > +    return rc;
> > > +}
> > > +
> > > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > > index dede2d914a..663aa8e117 100644
> > > --- a/hw/xen/xen-bus.c
> > > +++ b/hw/xen/xen-bus.c
> > [...]
> >
> > > +static void xen_device_backend_destroy(XenDevice *xendev)
> > > +{
> > > +    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
> > > +
> > > +    if (!xendev->backend_path) {
> > > +        return;
> > > +    }
> > > +
> > > +    g_assert(xenbus->xsh);
> > > +
> > > +    xs_node_destroy(xenbus->xsh, xendev->backend_path);
> > > +    g_free(xendev->backend_path);
> >
> > It would be nice to also set backend_path to NULL.
> >
> 
> Yes, it should be for idempotency.
> 
> > > diff --git a/include/hw/xen/xen-bus-helper.h b/include/hw/xen/xen-bus-
> > helper.h
> > > new file mode 100644
> > > index 0000000000..53570650db
> > > --- /dev/null
> > > +++ b/include/hw/xen/xen-bus-helper.h
> > > @@ -0,0 +1,26 @@
> > > +/*
> > > + * Copyright (c) Citrix Systems Inc.
> > > + * All rights reserved.
> > > + */
> > > +
> > > +#ifndef HW_XEN_BUS_HELPER_H
> > > +#define HW_XEN_BUS_HELPER_H
> >
> > That should probably include xen_common.h, to have `enum xenbus_state`,
> > `struct xs_handle`, ..
> 
> Ok.
> 
> >
> > > +const char *xs_strstate(enum xenbus_state state);
> > > +
> > > +void xs_node_create(struct xs_handle *xsh, const char *node,
> > > +                    struct xs_permissions perms[],
> > > +                    unsigned int nr_perms, Error **errp);
> > > +void xs_node_destroy(struct xs_handle *xsh, const char *node);
> > > +
> > > +void xs_node_vprintf(struct xs_handle *xsh, const char *node,
> > > +                     const char *key, const char *fmt, va_list ap);
> > > +void xs_node_printf(struct xs_handle *xsh, const char *node, const
> char
> > *key,
> > > +                    const char *fmt, ...);
> >
> > This prototype needs GCC_FMT_ATTR(), that's the printf format
> > __attribute__.
> >
> > > +
> > > +int xs_node_vscanf(struct xs_handle *xsh, const char *node, const
> char
> > *key,
> > > +                   const char *fmt, va_list ap);
> > > +int xs_node_scanf(struct xs_handle *xsh, const char *node, const char
> > *key,
> > > +                  const char *fmt, ...);
> >
> > Maybe here as well.
> 
> Will do.
> 
>  Paul
> 
> >
> >
> > --
> > Anthony PERARD


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 04/18] xen: create xenstore areas for XenDevice-s
  2018-12-05 12:43       ` [Qemu-devel] " Paul Durrant
@ 2018-12-05 13:58         ` Anthony PERARD
  2018-12-05 14:24           ` Paul Durrant
  2018-12-05 14:24           ` Paul Durrant
  2018-12-05 13:58         ` Anthony PERARD
  1 sibling, 2 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-05 13:58 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, xen-devel

On Wed, Dec 05, 2018 at 12:43:57PM +0000, Paul Durrant wrote:
> > > > +    value = g_strdup_vprintf(fmt, ap);
> > >
> > > Looks like g_vasprintf() would be better, since it returns the lenght as
> > > well.
> > >
> > 
> > Yes.
> 
> I tried this and it appears not to exist in the version of glib in my environment so I guess I'll stick with g_strdup_printf().

It's probably because you need to include "glib/gprintf.h", I've
suggested it because I've seen the function use elsewhere in QEMU. But
g_strdup_printf is fine too.

https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html#g-vasprintf

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 04/18] xen: create xenstore areas for XenDevice-s
  2018-12-05 12:43       ` [Qemu-devel] " Paul Durrant
  2018-12-05 13:58         ` Anthony PERARD
@ 2018-12-05 13:58         ` Anthony PERARD
  1 sibling, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-05 13:58 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, xen-devel

On Wed, Dec 05, 2018 at 12:43:57PM +0000, Paul Durrant wrote:
> > > > +    value = g_strdup_vprintf(fmt, ap);
> > >
> > > Looks like g_vasprintf() would be better, since it returns the lenght as
> > > well.
> > >
> > 
> > Yes.
> 
> I tried this and it appears not to exist in the version of glib in my environment so I guess I'll stick with g_strdup_printf().

It's probably because you need to include "glib/gprintf.h", I've
suggested it because I've seen the function use elsewhere in QEMU. But
g_strdup_printf is fine too.

https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html#g-vasprintf

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 04/18] xen: create xenstore areas for XenDevice-s
  2018-12-05 13:58         ` Anthony PERARD
@ 2018-12-05 14:24           ` Paul Durrant
  2018-12-05 14:24           ` Paul Durrant
  1 sibling, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-05 14:24 UTC (permalink / raw)
  To: Anthony Perard
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, xen-devel

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 05 December 2018 13:59
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: Kevin Wolf <kwolf@redhat.com>; Stefano Stabellini
> <sstabellini@kernel.org>; qemu-block@nongnu.org; qemu-devel@nongnu.org;
> Max Reitz <mreitz@redhat.com>; xen-devel@lists.xenproject.org
> Subject: Re: [PATCH 04/18] xen: create xenstore areas for XenDevice-s
> 
> On Wed, Dec 05, 2018 at 12:43:57PM +0000, Paul Durrant wrote:
> > > > > +    value = g_strdup_vprintf(fmt, ap);
> > > >
> > > > Looks like g_vasprintf() would be better, since it returns the
> lenght as
> > > > well.
> > > >
> > >
> > > Yes.
> >
> > I tried this and it appears not to exist in the version of glib in my
> environment so I guess I'll stick with g_strdup_printf().
> 
> It's probably because you need to include "glib/gprintf.h", I've
> suggested it because I've seen the function use elsewhere in QEMU. But
> g_strdup_printf is fine too.
> 
> https://developer.gnome.org/glib/stable/glib-String-Utility-
> Functions.html#g-vasprintf

Ah, that's what I needed. Thanks,

  Paul

> 
> --
> Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 04/18] xen: create xenstore areas for XenDevice-s
  2018-12-05 13:58         ` Anthony PERARD
  2018-12-05 14:24           ` Paul Durrant
@ 2018-12-05 14:24           ` Paul Durrant
  1 sibling, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-05 14:24 UTC (permalink / raw)
  To: Anthony Perard
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, xen-devel

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 05 December 2018 13:59
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: Kevin Wolf <kwolf@redhat.com>; Stefano Stabellini
> <sstabellini@kernel.org>; qemu-block@nongnu.org; qemu-devel@nongnu.org;
> Max Reitz <mreitz@redhat.com>; xen-devel@lists.xenproject.org
> Subject: Re: [PATCH 04/18] xen: create xenstore areas for XenDevice-s
> 
> On Wed, Dec 05, 2018 at 12:43:57PM +0000, Paul Durrant wrote:
> > > > > +    value = g_strdup_vprintf(fmt, ap);
> > > >
> > > > Looks like g_vasprintf() would be better, since it returns the
> lenght as
> > > > well.
> > > >
> > >
> > > Yes.
> >
> > I tried this and it appears not to exist in the version of glib in my
> environment so I guess I'll stick with g_strdup_printf().
> 
> It's probably because you need to include "glib/gprintf.h", I've
> suggested it because I've seen the function use elsewhere in QEMU. But
> g_strdup_printf is fine too.
> 
> https://developer.gnome.org/glib/stable/glib-String-Utility-
> Functions.html#g-vasprintf

Ah, that's what I needed. Thanks,

  Paul

> 
> --
> Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 05/18] xen: add xenstore watcher infratructure
  2018-12-03 14:42   ` Anthony PERARD
@ 2018-12-05 15:24     ` Paul Durrant
  2018-12-05 15:24     ` Paul Durrant
  1 sibling, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-05 15:24 UTC (permalink / raw)
  To: Anthony Perard
  Cc: qemu-block, qemu-devel, xen-devel, Kevin Wolf, Max Reitz,
	Stefano Stabellini

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 03 December 2018 14:43
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Kevin Wolf <kwolf@redhat.com>; Max Reitz
> <mreitz@redhat.com>; Stefano Stabellini <sstabellini@kernel.org>
> Subject: Re: [PATCH 05/18] xen: add xenstore watcher infratructure
> 
> On Wed, Nov 21, 2018 at 03:11:58PM +0000, Paul Durrant wrote:
> > A Xen PV frontend communicates its state to the PV backend by writing to
> > the 'state' key in the frontend area in xenstore. It is therefore
> > necessary for a XenDevice implementation to be notified whenever the
> > value of this key changes.
> >
> > This patch adds code to do this as follows:
> >
> > - an 'fd handler' is registered on the libxenstore handle which will be
> >   triggered whenever a 'watch' event occurs
> > - primitives are added to xen-bus-helper to add or remove watch events
> > - a list of Notifier objects is added to XenBus to provide a mechanism
> >   to call the appropriate 'watch handler' when its associated event
> >   occurs
> >
> > The xen-qisk implementation is extended with a 'frontend_changed'
> method,
> 
> "The xen-qdisk"

It's xen-block now :-)

> 
> > which calls as-yet stub 'connect' and 'disconnect' functions when the
> > relevant frontend state transitions occur. A subsequent patch will
> supply
> > a full implementation for these functions.
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > ---
> > diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> > index 0859643f7d..35f7b70480 100644
> > --- a/hw/block/xen-qdisk.c
> > +++ b/hw/block/xen-qdisk.c
> > +static void xen_qdisk_frontend_changed(XenDevice *xendev,
> > +                                       enum xenbus_state
> frontend_state,
> > +                                       Error **errp)
> > +{
> > +    XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
> > +    enum xenbus_state backend_state =
> xen_device_backend_get_state(xendev);
> > +    Error *local_err = NULL;
> > +
> > +    switch (frontend_state) {
> > +    case XenbusStateInitialised:
> > +    case XenbusStateConnected:
> > +        if (backend_state == XenbusStateConnected) {
> > +            break;
> > +        }
> > +
> > +        xen_qdisk_disconnect(qdiskdev, &error_fatal);
> 
> Do we want to crash (actually exit) QEMU when disconnect failed?
> 

Ok, I'll propagate.

> > +        xen_qdisk_connect(qdiskdev, &local_err);
> > +        if (local_err) {
> > +            error_propagate(errp, local_err);
> > +            break;
> > +        }
> > +
> > +        xen_device_backend_set_state(xendev, XenbusStateConnected);
> > +        break;
> > +
> > +    case XenbusStateClosing:
> > +        xen_device_backend_set_state(xendev, XenbusStateClosing);
> > +        break;
> > +
> > +    case XenbusStateClosed:
> > +        xen_qdisk_disconnect(qdiskdev, &error_fatal);
> > +        xen_device_backend_set_state(xendev, XenbusStateClosed);
> > +        break;
> > +
> > +    default:
> > +        break;
> > +    }
> > +}
> > +
> > diff --git a/hw/xen/xen-bus-helper.c b/hw/xen/xen-bus-helper.c
> > index d9ee2ed6a0..b44acc8047 100644
> > --- a/hw/xen/xen-bus-helper.c
> > +++ b/hw/xen/xen-bus-helper.c
> > @@ -122,3 +122,31 @@ int xs_node_scanf(struct xs_handle *xsh, const char
> *node, const char *key,
> >
> >      return rc;
> >  }
> > +
> > +void xs_node_watch(struct xs_handle *xsh, const char *node, const char
> *key,
> > +                   char *token, Error **errp)
> > +{
> > +    char *path;
> > +
> > +    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
> > +        g_strdup(key);
> > +
> > +    if (!xs_watch(xsh, path, token)) {
> > +        error_setg_errno(errp, errno, "failed to watch path '%s'",
> path);
> > +    }
> > +
> > +    g_free(path);
> > +}
> > +
> > +void xs_node_unwatch(struct xs_handle *xsh, const char *node,
> > +                     const char *key, const char *token)
> > +{
> > +    char *path;
> > +
> > +    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
> > +        g_strdup(key);
> > +
> > +    xs_unwatch(xsh, path, token);
> 
> I think we should check for error from xs_unwatch as well.

Yes.

> 
> > +
> > +    g_free(path);
> > +}
> > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > index 663aa8e117..99988f8568 100644
> > --- a/hw/xen/xen-bus.c
> > +++ b/hw/xen/xen-bus.c
> > +static XenWatch *xen_bus_add_watch(XenBus *xenbus, const char *node,
> > +                                   const char *key, XenWatchHandler
> handler,
> > +                                   void *opaque, Error **errp)
> > +{
> > +    XenWatch *watch = g_new0(XenWatch, 1);
> > +    QemuUUID uuid;
> > +    Error *local_err = NULL;
> > +
> > +    qemu_uuid_generate(&uuid);
> > +    watch->token = qemu_uuid_unparse_strdup(&uuid);
> > +
> > +    trace_xen_bus_add_watch(node, key, watch->token);
> > +
> > +    watch->node = g_strdup(node);
> > +    watch->key = g_strdup(key);
> > +    watch->handler = handler;
> > +    watch->opaque = opaque;
> > +    watch->notifier.notify = watch_notify;
> > +
> > +    notifier_list_add(&xenbus->watch_notifiers, &watch->notifier);
> > +
> > +    xs_node_watch(xenbus->xsh, node, key, watch->token, &local_err);
> > +
> > +    if (local_err) {
> > +        error_propagate(errp, local_err);
> > +
> > +        notifier_remove(&watch->notifier);
> > +
> > +        g_free(watch->token);
> > +        g_free(watch->key);
> > +        g_free(watch->node);
> > +
> > +        g_free(watch);
> 
> It would be better to have a function that will free/dispose of a
> XenWatch, or maybe simply calling xen_bus_remove_watch here might be
> enough.

True. Too much cut'n'paste.

> 
> > +        watch = NULL;
> 
> You could return NULL instead.
> 
> > +    }
> > +
> > +    return watch;
> > +}
> > +
> > +static void xen_bus_remove_watch(XenBus *xenbus, XenWatch *watch)
> > +{
> > +    trace_xen_bus_remove_watch(watch->node, watch->key, watch->token);
> > +
> > +    xs_node_unwatch(xenbus->xsh, watch->node, watch->key, watch-
> >token);
> > +
> > +    notifier_remove(&watch->notifier);
> > +
> > +    g_free(watch->token);
> > +    g_free(watch->key);
> > +    g_free(watch->node);
> > +
> > +    g_free(watch);
> > +}
> 
> > +static void xen_bus_watch(void *opaque)
> > +{
> > +    XenBus *xenbus = opaque;
> > +    char **v;
> > +    const char *token;
> > +    unsigned int n;
> > +
> > +    g_assert(xenbus->xsh);
> > +
> > +    v = xs_read_watch(xenbus->xsh, &n);
> 
> What is the n for?
> Also, maybe you wanted to call xs_check_watch instead? (In a loop, until
> EGAIN)

I don't need the loop. The 'n' is the length of the vector but xs_check_watch() does what I need.

> 
> > +    if (!v) {
> > +        return;
> > +    }
> > +
> > +    token = v[XS_WATCH_TOKEN];
> > +
> > +    trace_xen_bus_watch(token);
> > +
> > +    notifier_list_notify(&xenbus->watch_notifiers, (void *)token);
> > +
> > +    free(v);
> > +}
> > +
> >  static void xen_bus_realize(BusState *bus, Error **errp)
> >  {
> >      XenBus *xenbus = XEN_BUS(bus);
> > @@ -230,12 +419,24 @@ static void xen_device_frontend_create(XenDevice
> *xendev, Error **errp)
> >          error_propagate(errp, local_err);
> >          error_prepend(errp, "failed to create frontend: ");
> >      }
> > +
> > +    xendev->frontend_state_watch =
> > +        xen_bus_add_watch(xenbus, xendev->frontend_path, "state",
> > +                          xen_device_frontend_changed, xendev,
> &local_err);
> 
> You can't reuse local_err here, *local_err must be null (It isn't
> exactly written like this, but that what I understand from reading
> qapi/error.h).

Oh, the code should have bailed on the first error.

  Paul

> 
> Maybe you meant to return when the previous function failed (call of
> xs_node_create)?
> 
> > +    if (local_err) {
> > +        error_propagate(errp, local_err);
> > +        error_prepend(errp, "failed to watch frontend state: ");
> > +    }
> >  }
> 
> Thanks,
> 
> --
> Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 05/18] xen: add xenstore watcher infratructure
  2018-12-03 14:42   ` Anthony PERARD
  2018-12-05 15:24     ` Paul Durrant
@ 2018-12-05 15:24     ` Paul Durrant
  1 sibling, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-05 15:24 UTC (permalink / raw)
  To: Anthony Perard
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, xen-devel

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 03 December 2018 14:43
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Kevin Wolf <kwolf@redhat.com>; Max Reitz
> <mreitz@redhat.com>; Stefano Stabellini <sstabellini@kernel.org>
> Subject: Re: [PATCH 05/18] xen: add xenstore watcher infratructure
> 
> On Wed, Nov 21, 2018 at 03:11:58PM +0000, Paul Durrant wrote:
> > A Xen PV frontend communicates its state to the PV backend by writing to
> > the 'state' key in the frontend area in xenstore. It is therefore
> > necessary for a XenDevice implementation to be notified whenever the
> > value of this key changes.
> >
> > This patch adds code to do this as follows:
> >
> > - an 'fd handler' is registered on the libxenstore handle which will be
> >   triggered whenever a 'watch' event occurs
> > - primitives are added to xen-bus-helper to add or remove watch events
> > - a list of Notifier objects is added to XenBus to provide a mechanism
> >   to call the appropriate 'watch handler' when its associated event
> >   occurs
> >
> > The xen-qisk implementation is extended with a 'frontend_changed'
> method,
> 
> "The xen-qdisk"

It's xen-block now :-)

> 
> > which calls as-yet stub 'connect' and 'disconnect' functions when the
> > relevant frontend state transitions occur. A subsequent patch will
> supply
> > a full implementation for these functions.
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > ---
> > diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> > index 0859643f7d..35f7b70480 100644
> > --- a/hw/block/xen-qdisk.c
> > +++ b/hw/block/xen-qdisk.c
> > +static void xen_qdisk_frontend_changed(XenDevice *xendev,
> > +                                       enum xenbus_state
> frontend_state,
> > +                                       Error **errp)
> > +{
> > +    XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
> > +    enum xenbus_state backend_state =
> xen_device_backend_get_state(xendev);
> > +    Error *local_err = NULL;
> > +
> > +    switch (frontend_state) {
> > +    case XenbusStateInitialised:
> > +    case XenbusStateConnected:
> > +        if (backend_state == XenbusStateConnected) {
> > +            break;
> > +        }
> > +
> > +        xen_qdisk_disconnect(qdiskdev, &error_fatal);
> 
> Do we want to crash (actually exit) QEMU when disconnect failed?
> 

Ok, I'll propagate.

> > +        xen_qdisk_connect(qdiskdev, &local_err);
> > +        if (local_err) {
> > +            error_propagate(errp, local_err);
> > +            break;
> > +        }
> > +
> > +        xen_device_backend_set_state(xendev, XenbusStateConnected);
> > +        break;
> > +
> > +    case XenbusStateClosing:
> > +        xen_device_backend_set_state(xendev, XenbusStateClosing);
> > +        break;
> > +
> > +    case XenbusStateClosed:
> > +        xen_qdisk_disconnect(qdiskdev, &error_fatal);
> > +        xen_device_backend_set_state(xendev, XenbusStateClosed);
> > +        break;
> > +
> > +    default:
> > +        break;
> > +    }
> > +}
> > +
> > diff --git a/hw/xen/xen-bus-helper.c b/hw/xen/xen-bus-helper.c
> > index d9ee2ed6a0..b44acc8047 100644
> > --- a/hw/xen/xen-bus-helper.c
> > +++ b/hw/xen/xen-bus-helper.c
> > @@ -122,3 +122,31 @@ int xs_node_scanf(struct xs_handle *xsh, const char
> *node, const char *key,
> >
> >      return rc;
> >  }
> > +
> > +void xs_node_watch(struct xs_handle *xsh, const char *node, const char
> *key,
> > +                   char *token, Error **errp)
> > +{
> > +    char *path;
> > +
> > +    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
> > +        g_strdup(key);
> > +
> > +    if (!xs_watch(xsh, path, token)) {
> > +        error_setg_errno(errp, errno, "failed to watch path '%s'",
> path);
> > +    }
> > +
> > +    g_free(path);
> > +}
> > +
> > +void xs_node_unwatch(struct xs_handle *xsh, const char *node,
> > +                     const char *key, const char *token)
> > +{
> > +    char *path;
> > +
> > +    path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
> > +        g_strdup(key);
> > +
> > +    xs_unwatch(xsh, path, token);
> 
> I think we should check for error from xs_unwatch as well.

Yes.

> 
> > +
> > +    g_free(path);
> > +}
> > diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> > index 663aa8e117..99988f8568 100644
> > --- a/hw/xen/xen-bus.c
> > +++ b/hw/xen/xen-bus.c
> > +static XenWatch *xen_bus_add_watch(XenBus *xenbus, const char *node,
> > +                                   const char *key, XenWatchHandler
> handler,
> > +                                   void *opaque, Error **errp)
> > +{
> > +    XenWatch *watch = g_new0(XenWatch, 1);
> > +    QemuUUID uuid;
> > +    Error *local_err = NULL;
> > +
> > +    qemu_uuid_generate(&uuid);
> > +    watch->token = qemu_uuid_unparse_strdup(&uuid);
> > +
> > +    trace_xen_bus_add_watch(node, key, watch->token);
> > +
> > +    watch->node = g_strdup(node);
> > +    watch->key = g_strdup(key);
> > +    watch->handler = handler;
> > +    watch->opaque = opaque;
> > +    watch->notifier.notify = watch_notify;
> > +
> > +    notifier_list_add(&xenbus->watch_notifiers, &watch->notifier);
> > +
> > +    xs_node_watch(xenbus->xsh, node, key, watch->token, &local_err);
> > +
> > +    if (local_err) {
> > +        error_propagate(errp, local_err);
> > +
> > +        notifier_remove(&watch->notifier);
> > +
> > +        g_free(watch->token);
> > +        g_free(watch->key);
> > +        g_free(watch->node);
> > +
> > +        g_free(watch);
> 
> It would be better to have a function that will free/dispose of a
> XenWatch, or maybe simply calling xen_bus_remove_watch here might be
> enough.

True. Too much cut'n'paste.

> 
> > +        watch = NULL;
> 
> You could return NULL instead.
> 
> > +    }
> > +
> > +    return watch;
> > +}
> > +
> > +static void xen_bus_remove_watch(XenBus *xenbus, XenWatch *watch)
> > +{
> > +    trace_xen_bus_remove_watch(watch->node, watch->key, watch->token);
> > +
> > +    xs_node_unwatch(xenbus->xsh, watch->node, watch->key, watch-
> >token);
> > +
> > +    notifier_remove(&watch->notifier);
> > +
> > +    g_free(watch->token);
> > +    g_free(watch->key);
> > +    g_free(watch->node);
> > +
> > +    g_free(watch);
> > +}
> 
> > +static void xen_bus_watch(void *opaque)
> > +{
> > +    XenBus *xenbus = opaque;
> > +    char **v;
> > +    const char *token;
> > +    unsigned int n;
> > +
> > +    g_assert(xenbus->xsh);
> > +
> > +    v = xs_read_watch(xenbus->xsh, &n);
> 
> What is the n for?
> Also, maybe you wanted to call xs_check_watch instead? (In a loop, until
> EGAIN)

I don't need the loop. The 'n' is the length of the vector but xs_check_watch() does what I need.

> 
> > +    if (!v) {
> > +        return;
> > +    }
> > +
> > +    token = v[XS_WATCH_TOKEN];
> > +
> > +    trace_xen_bus_watch(token);
> > +
> > +    notifier_list_notify(&xenbus->watch_notifiers, (void *)token);
> > +
> > +    free(v);
> > +}
> > +
> >  static void xen_bus_realize(BusState *bus, Error **errp)
> >  {
> >      XenBus *xenbus = XEN_BUS(bus);
> > @@ -230,12 +419,24 @@ static void xen_device_frontend_create(XenDevice
> *xendev, Error **errp)
> >          error_propagate(errp, local_err);
> >          error_prepend(errp, "failed to create frontend: ");
> >      }
> > +
> > +    xendev->frontend_state_watch =
> > +        xen_bus_add_watch(xenbus, xendev->frontend_path, "state",
> > +                          xen_device_frontend_changed, xendev,
> &local_err);
> 
> You can't reuse local_err here, *local_err must be null (It isn't
> exactly written like this, but that what I understand from reading
> qapi/error.h).

Oh, the code should have bailed on the first error.

  Paul

> 
> Maybe you meant to return when the previous function failed (call of
> xs_node_create)?
> 
> > +    if (local_err) {
> > +        error_propagate(errp, local_err);
> > +        error_prepend(errp, "failed to watch frontend state: ");
> > +    }
> >  }
> 
> Thanks,
> 
> --
> Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 06/18] xen: add grant table interface for XenDevice-s
  2018-12-03 15:45     ` Anthony PERARD
  (?)
  (?)
@ 2018-12-05 16:12     ` Paul Durrant
  -1 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-05 16:12 UTC (permalink / raw)
  To: Anthony Perard; +Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 03 December 2018 15:46
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>
> Subject: Re: [PATCH 06/18] xen: add grant table interface for XenDevice-s
> 
> On Wed, Nov 21, 2018 at 03:11:59PM +0000, Paul Durrant wrote:
> > The legacy PV backend infrastructure provides functions to map, unmap
> and
> > copy pages granted by frontends. Similar functionality will be required
> > by XenDevice implementations so this patch adds the necessary support.
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > ---
> > +typedef struct XenDeviceGrantCopySegment {
> > +    union {
> > +        void *virt;
> > +        struct {
> > +            uint32_t ref;
> > +            off_t offset;
> > +        } foreign;
> > +    } source, dest;
> 
> Why is there a union between `source` and `dest`, I don't see any way
> (another field) to distinguish which is which. Can't we have a
> segment without `source`/`dest`?

How? I think introducing two separate segment definitions depending on whether it is a copy-to-guest or copy-from-guest is a little ugly.

> It mimic the
> xengnttab_grant_copy_segment_t but that doesn't seems very useful as it
> doesn't really prevent mistake.

It mimics that struct apart from the field static which direction the transfer is because, to maintain compatibility, the entire copy goes only one way or the other.

> 
> > +    size_t len;
> > +} XenDeviceGrantCopySegment;
> 
> Anyway, it's not very important:
> 
> Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>

Thanks.

  Paul

> 
> Thanks,
> 
> --
> Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 06/18] xen: add grant table interface for XenDevice-s
  2018-12-03 15:45     ` Anthony PERARD
  (?)
@ 2018-12-05 16:12     ` Paul Durrant
  -1 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-05 16:12 UTC (permalink / raw)
  To: Anthony Perard; +Cc: xen-devel, Stefano Stabellini, qemu-devel, qemu-block

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 03 December 2018 15:46
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>
> Subject: Re: [PATCH 06/18] xen: add grant table interface for XenDevice-s
> 
> On Wed, Nov 21, 2018 at 03:11:59PM +0000, Paul Durrant wrote:
> > The legacy PV backend infrastructure provides functions to map, unmap
> and
> > copy pages granted by frontends. Similar functionality will be required
> > by XenDevice implementations so this patch adds the necessary support.
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > ---
> > +typedef struct XenDeviceGrantCopySegment {
> > +    union {
> > +        void *virt;
> > +        struct {
> > +            uint32_t ref;
> > +            off_t offset;
> > +        } foreign;
> > +    } source, dest;
> 
> Why is there a union between `source` and `dest`, I don't see any way
> (another field) to distinguish which is which. Can't we have a
> segment without `source`/`dest`?

How? I think introducing two separate segment definitions depending on whether it is a copy-to-guest or copy-from-guest is a little ugly.

> It mimic the
> xengnttab_grant_copy_segment_t but that doesn't seems very useful as it
> doesn't really prevent mistake.

It mimics that struct apart from the field static which direction the transfer is because, to maintain compatibility, the entire copy goes only one way or the other.

> 
> > +    size_t len;
> > +} XenDeviceGrantCopySegment;
> 
> Anyway, it's not very important:
> 
> Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>

Thanks.

  Paul

> 
> Thanks,
> 
> --
> Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 07/18] xen: add event channel interface for XenDevice-s
  2018-12-04 14:24       ` Anthony PERARD
  (?)
  (?)
@ 2018-12-05 16:16       ` Paul Durrant
  -1 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-05 16:16 UTC (permalink / raw)
  To: Anthony Perard; +Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 04 December 2018 14:25
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>
> Subject: Re: [PATCH 07/18] xen: add event channel interface for XenDevice-
> s
> 
> On Mon, Dec 03, 2018 at 04:24:24PM +0000, Anthony PERARD wrote:
> > On Wed, Nov 21, 2018 at 03:12:00PM +0000, Paul Durrant wrote:
> > > +static void xen_device_event(void *opaque)
> > > +{
> > > +    XenDevice *xendev = opaque;
> > > +    unsigned long port = xenevtchn_pending(xendev->xeh);
> > > +
> > > +    notifier_list_notify(&xendev->event_notifiers, (void *)port);
> >
> > I wonder if a Notifier is a good fit for XenDevice, like here for the
> > events or the xenstore watches in previous patches, as NotifierLists are
> > normaly used when every Notifiers want to do something, but here there
> > is only one that is going to do something. But I guess it might not be
> > much better to write a loop in here rather than use the one in
> > notifier_list_notify.
> 
> I've seen that you use GHashTable in a following patch, wouldn't that be
> useful to use for xenstore watches and evtchn events as well?
> 

There's precedent for using Notifier lists for this kind of thing. A hash table may be an optimization but I'd rather stick with the lists for now... I know they work :-)

  Paul

> 
> --
> Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 07/18] xen: add event channel interface for XenDevice-s
  2018-12-04 14:24       ` Anthony PERARD
  (?)
@ 2018-12-05 16:16       ` Paul Durrant
  -1 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-05 16:16 UTC (permalink / raw)
  To: Anthony Perard; +Cc: xen-devel, Stefano Stabellini, qemu-devel, qemu-block

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 04 December 2018 14:25
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>
> Subject: Re: [PATCH 07/18] xen: add event channel interface for XenDevice-
> s
> 
> On Mon, Dec 03, 2018 at 04:24:24PM +0000, Anthony PERARD wrote:
> > On Wed, Nov 21, 2018 at 03:12:00PM +0000, Paul Durrant wrote:
> > > +static void xen_device_event(void *opaque)
> > > +{
> > > +    XenDevice *xendev = opaque;
> > > +    unsigned long port = xenevtchn_pending(xendev->xeh);
> > > +
> > > +    notifier_list_notify(&xendev->event_notifiers, (void *)port);
> >
> > I wonder if a Notifier is a good fit for XenDevice, like here for the
> > events or the xenstore watches in previous patches, as NotifierLists are
> > normaly used when every Notifiers want to do something, but here there
> > is only one that is going to do something. But I guess it might not be
> > much better to write a loop in here rather than use the one in
> > notifier_list_notify.
> 
> I've seen that you use GHashTable in a following patch, wouldn't that be
> useful to use for xenstore watches and evtchn events as well?
> 

There's precedent for using Notifier lists for this kind of thing. A hash table may be an optimization but I'd rather stick with the lists for now... I know they work :-)

  Paul

> 
> --
> Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 04/18] xen: create xenstore areas for XenDevice-s
  2018-12-05 12:05     ` Paul Durrant
                         ` (2 preceding siblings ...)
  2018-12-05 16:28       ` Anthony PERARD
@ 2018-12-05 16:28       ` Anthony PERARD
  3 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-05 16:28 UTC (permalink / raw)
  To: Paul Durrant
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Kevin Wolf, Max Reitz

On Wed, Dec 05, 2018 at 12:05:23PM +0000, Paul Durrant wrote:
> > > +    value = xs_read(xsh, XBT_NULL, path, NULL);
> > 
> > The xenstore.h isn't clear about failure of this function, it is
> > supposed to return a malloced value. Do we actually need to check if value
> > is NULL?
> 
> The comment above xs_read() in xs.c is:
> 
> /* Get the value of a single file, nul terminated.                          
>  * Returns a malloced value: call free() on it after use.                   
>  * len indicates length in bytes, not including the nul.                    
>  */
> 
> and I think we should check it for NULL before passing it to vsscanf().

I've sent a patch against xenstore.h to document that xs_read, and some
other functions, can return NULL.
<20181205162603.25788-1-anthony.perard@citrix.com>

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 04/18] xen: create xenstore areas for XenDevice-s
  2018-12-05 12:05     ` Paul Durrant
  2018-12-05 12:43       ` Paul Durrant
  2018-12-05 12:43       ` [Qemu-devel] " Paul Durrant
@ 2018-12-05 16:28       ` Anthony PERARD
  2018-12-05 16:28       ` [Qemu-devel] " Anthony PERARD
  3 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-05 16:28 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, xen-devel

On Wed, Dec 05, 2018 at 12:05:23PM +0000, Paul Durrant wrote:
> > > +    value = xs_read(xsh, XBT_NULL, path, NULL);
> > 
> > The xenstore.h isn't clear about failure of this function, it is
> > supposed to return a malloced value. Do we actually need to check if value
> > is NULL?
> 
> The comment above xs_read() in xs.c is:
> 
> /* Get the value of a single file, nul terminated.                          
>  * Returns a malloced value: call free() on it after use.                   
>  * len indicates length in bytes, not including the nul.                    
>  */
> 
> and I think we should check it for NULL before passing it to vsscanf().

I've sent a patch against xenstore.h to document that xs_read, and some
other functions, can return NULL.
<20181205162603.25788-1-anthony.perard@citrix.com>

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 13/18] xen: purge 'blk' and 'ioreq' from function names in dataplane/xen-qdisk.c
  2018-12-04 12:10     ` Anthony PERARD
  (?)
@ 2018-12-05 17:28     ` Paul Durrant
  -1 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-05 17:28 UTC (permalink / raw)
  To: Anthony Perard
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Stefan Hajnoczi, Kevin Wolf, Max Reitz

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 04 December 2018 12:11
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> Stefan Hajnoczi <stefanha@redhat.com>; Kevin Wolf <kwolf@redhat.com>; Max
> Reitz <mreitz@redhat.com>
> Subject: Re: [PATCH 13/18] xen: purge 'blk' and 'ioreq' from function
> names in dataplane/xen-qdisk.c
> 
> On Wed, Nov 21, 2018 at 03:12:06PM +0000, Paul Durrant wrote:
> > This is a purely cosmetic patch that purges remaining use of 'blk' and
> > 'ioreq' in local function names.
> >
> > No functional change.
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> 
> I don't think it's a good idee to use function names that could be use
> elsewhere, don't have a namespace. It makes it more difficult to figure
> out which function is called by just searching for the function name.
> 
> Could you had a prefix?
> Maybe xendisk_ or xen_disk or xen_qdisk or xen_block or ..., so we can
> have xendisk_start_request, or xendisk_request_start. I don't have a
> preference beside staying away from generic names.
> 

I'll add a xen_block_ prefix.

  Paul

> Thanks,
> 
> --
> Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 13/18] xen: purge 'blk' and 'ioreq' from function names in dataplane/xen-qdisk.c
  2018-12-04 12:10     ` Anthony PERARD
  (?)
  (?)
@ 2018-12-05 17:28     ` Paul Durrant
  -1 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-05 17:28 UTC (permalink / raw)
  To: Anthony Perard
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, Stefan Hajnoczi, xen-devel

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 04 December 2018 12:11
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> Stefan Hajnoczi <stefanha@redhat.com>; Kevin Wolf <kwolf@redhat.com>; Max
> Reitz <mreitz@redhat.com>
> Subject: Re: [PATCH 13/18] xen: purge 'blk' and 'ioreq' from function
> names in dataplane/xen-qdisk.c
> 
> On Wed, Nov 21, 2018 at 03:12:06PM +0000, Paul Durrant wrote:
> > This is a purely cosmetic patch that purges remaining use of 'blk' and
> > 'ioreq' in local function names.
> >
> > No functional change.
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> 
> I don't think it's a good idee to use function names that could be use
> elsewhere, don't have a namespace. It makes it more difficult to figure
> out which function is called by just searching for the function name.
> 
> Could you had a prefix?
> Maybe xendisk_ or xen_disk or xen_qdisk or xen_block or ..., so we can
> have xendisk_start_request, or xendisk_request_start. I don't have a
> preference beside staying away from generic names.
> 

I'll add a xen_block_ prefix.

  Paul

> Thanks,
> 
> --
> Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 10/18] xen: add header and build dataplane/xen-qdisk.c
  2018-12-03 18:09   ` [Qemu-devel] " Anthony PERARD
  2018-12-05 17:31     ` Paul Durrant
@ 2018-12-05 17:31     ` Paul Durrant
  1 sibling, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-05 17:31 UTC (permalink / raw)
  To: Anthony Perard
  Cc: qemu-block, qemu-devel, xen-devel, Stefan Hajnoczi, Kevin Wolf,
	Max Reitz, Stefano Stabellini

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 03 December 2018 18:09
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefan Hajnoczi <stefanha@redhat.com>; Kevin
> Wolf <kwolf@redhat.com>; Max Reitz <mreitz@redhat.com>; Stefano Stabellini
> <sstabellini@kernel.org>
> Subject: Re: [PATCH 10/18] xen: add header and build dataplane/xen-qdisk.c
> 
> On Wed, Nov 21, 2018 at 03:12:03PM +0000, Paul Durrant wrote:
> > This patch adds the transformations necessary to get dataplane/xen-
> qdisk.c
> > to build against the new XenBus/XenDevice framework. MAINTAINERS is also
> > updated due to the introduction of dataplane/xen-qdisk.h.
> >
> > NOTE: Existing data structure names are retained for the moment. These
> will
> >       be modified by subsequent patches. A typedef for XenQdiskDataPlane
> >       has been added to the header (based on the old struct XenBlkDev
> name
> >       for the moment) so that the old names don't need to leak out of
> the
> >       dataplane code.
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > ---
> > diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-
> qdisk.c
> > index 8e4368e7af..b075aa975d 100644
> > --- a/hw/block/dataplane/xen-qdisk.c
> > +++ b/hw/block/dataplane/xen-qdisk.c
> > @@ -5,65 +5,56 @@
> >   * Based on original code (c) Gerd Hoffmann <kraxel@redhat.com>
> >   */
> >
> > +#include "qemu/osdep.h"
> > +#include "qemu/error-report.h"
> > +#include "qapi/error.h"
> > +#include "hw/hw.h"
> > +#include "hw/xen/xen.h"
> 
> xen.h isn't needed, xen_common.h should be enough.
> 
> > +#include "hw/xen/xen_common.h"
> > +#include "hw/block/block.h"
> 
> block.h isn't needed, block-backend.h should be enough.
> 
> > +#include "hw/block/xen_blkif.h"
> > +#include "sysemu/blockdev.h"
> 
> blockdev.h doesn't seems to be used.
> 

Ok. I'll clean these up.

> > +#include "sysemu/block-backend.h"
> > +#include "sysemu/iothread.h"
> > +#include "xen-qdisk.h"
> > +
> > @@ -227,20 +219,24 @@ static int ioreq_grant_copy(struct ioreq *ioreq)
> >                  file_blk;
> >              segs[i].dest.virt = virt;
> >          }
> > -        segs[i].len = (ioreq->req.seg[i].last_sect
> > -                       - ioreq->req.seg[i].first_sect + 1) * file_blk;
> > +        segs[i].len = (ioreq->req.seg[i].last_sect -
> > +                       ioreq->req.seg[i].first_sect + 1) * file_blk;
> >          virt += segs[i].len;
> >      }
> >
> > -    rc = xen_be_copy_grant_refs(xendev, to_domain, segs, count);
> > +    xen_device_copy_grant_refs(xendev, to_domain, segs, count,
> &local_err);
> > +
> > +    if (local_err) {
> > +        const char *msg = error_get_pretty(local_err);
> > +
> > +        error_report("failed to copy data: %s", msg);
> > +        error_free(local_err);
> 
> You can do the  following instead:
>     error_prepend(local_err, "failed to copy data: ")
>     error_report_err(local_err);
> 

Done.

> > +void xen_qdisk_dataplane_start(struct XenBlkDev *blkdev,
> > +                               const unsigned int ring_ref[],
> > +                               unsigned int nr_ring_ref,
> > +                               unsigned int event_channel,
> > +                               unsigned int protocol)
> >  {
> > -    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev,
> xendev);
> > +    XenDevice *xendev = blkdev->xendev;
> > +    unsigned int ring_size;
> > +    unsigned int i;
> >
> > -    qemu_bh_schedule(blkdev->bh);
> > +    blkdev->nr_ring_ref = nr_ring_ref;
> > +    blkdev->ring_ref = g_new(unsigned int, nr_ring_ref);
> > +
> > +    for (i = 0; i < nr_ring_ref; i++) {
> > +        blkdev->ring_ref[i] = ring_ref[i];
> > +    }
> > +
> > +    blkdev->protocol = protocol;
> > +
> > +    ring_size = XC_PAGE_SIZE * blkdev->nr_ring_ref;
> > +    switch (blkdev->protocol) {
> > +    case BLKIF_PROTOCOL_NATIVE:
> > +    {
> > +        blkdev->max_requests = __CONST_RING_SIZE(blkif, ring_size);
> > +        break;
> > +    }
> > +    case BLKIF_PROTOCOL_X86_32:
> > +    {
> > +        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_32,
> ring_size);
> > +        break;
> > +    }
> > +    case BLKIF_PROTOCOL_X86_64:
> > +    {
> > +        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_64,
> ring_size);
> > +        break;
> > +    }
> > +    default:
> > +        assert(false);
> > +        break;
> 
> This should return rather than keep going.
> And maybe set an Error that could be added to the parameter of the
> function.
> 
> > +    }
> > +
> > +    xen_device_set_max_grant_refs(xendev, blkdev->nr_ring_ref,
> > +                                  &error_fatal);
> 
> Do we really want to exit() here if an error happen, rather than let the
> caller know? (Same question for other uses of error_fatal.)
> 

Indeed. I added an error pointer to the function so it can bail cleanly.

> > diff --git a/hw/block/dataplane/xen-qdisk.h b/hw/block/dataplane/xen-
> qdisk.h
> > new file mode 100644
> > index 0000000000..16bcd500bf
> > --- /dev/null
> > +++ b/hw/block/dataplane/xen-qdisk.h
> > @@ -0,0 +1,25 @@
> > +/*
> > + * Copyright (c) Citrix Systems Inc.
> > + * All rights reserved.
> > + */
> > +
> > +#ifndef HW_BLOCK_DATAPLANE_QDISK_H
> > +#define HW_BLOCK_DATAPLANE_QDISK_H
> > +
> > +#include "hw/xen/xen-bus.h"
> > +#include "sysemu/iothread.h"
> 
> I would add #include "hw/block/block.h" since it includes the definition
> of BlockConf.
> 

Sure.

  Paul

> > +
> > +typedef struct XenBlkDev XenQdiskDataPlane;
> > +
> > +XenQdiskDataPlane *xen_qdisk_dataplane_create(XenDevice *xendev,
> > +                                              BlockConf *conf,
> > +                                              IOThread *iothread);
> 
> Thanks,
> 
> --
> Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 10/18] xen: add header and build dataplane/xen-qdisk.c
  2018-12-03 18:09   ` [Qemu-devel] " Anthony PERARD
@ 2018-12-05 17:31     ` Paul Durrant
  2018-12-05 17:31     ` [Qemu-devel] " Paul Durrant
  1 sibling, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-05 17:31 UTC (permalink / raw)
  To: Anthony Perard
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, Stefan Hajnoczi, xen-devel

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 03 December 2018 18:09
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefan Hajnoczi <stefanha@redhat.com>; Kevin
> Wolf <kwolf@redhat.com>; Max Reitz <mreitz@redhat.com>; Stefano Stabellini
> <sstabellini@kernel.org>
> Subject: Re: [PATCH 10/18] xen: add header and build dataplane/xen-qdisk.c
> 
> On Wed, Nov 21, 2018 at 03:12:03PM +0000, Paul Durrant wrote:
> > This patch adds the transformations necessary to get dataplane/xen-
> qdisk.c
> > to build against the new XenBus/XenDevice framework. MAINTAINERS is also
> > updated due to the introduction of dataplane/xen-qdisk.h.
> >
> > NOTE: Existing data structure names are retained for the moment. These
> will
> >       be modified by subsequent patches. A typedef for XenQdiskDataPlane
> >       has been added to the header (based on the old struct XenBlkDev
> name
> >       for the moment) so that the old names don't need to leak out of
> the
> >       dataplane code.
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > ---
> > diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-
> qdisk.c
> > index 8e4368e7af..b075aa975d 100644
> > --- a/hw/block/dataplane/xen-qdisk.c
> > +++ b/hw/block/dataplane/xen-qdisk.c
> > @@ -5,65 +5,56 @@
> >   * Based on original code (c) Gerd Hoffmann <kraxel@redhat.com>
> >   */
> >
> > +#include "qemu/osdep.h"
> > +#include "qemu/error-report.h"
> > +#include "qapi/error.h"
> > +#include "hw/hw.h"
> > +#include "hw/xen/xen.h"
> 
> xen.h isn't needed, xen_common.h should be enough.
> 
> > +#include "hw/xen/xen_common.h"
> > +#include "hw/block/block.h"
> 
> block.h isn't needed, block-backend.h should be enough.
> 
> > +#include "hw/block/xen_blkif.h"
> > +#include "sysemu/blockdev.h"
> 
> blockdev.h doesn't seems to be used.
> 

Ok. I'll clean these up.

> > +#include "sysemu/block-backend.h"
> > +#include "sysemu/iothread.h"
> > +#include "xen-qdisk.h"
> > +
> > @@ -227,20 +219,24 @@ static int ioreq_grant_copy(struct ioreq *ioreq)
> >                  file_blk;
> >              segs[i].dest.virt = virt;
> >          }
> > -        segs[i].len = (ioreq->req.seg[i].last_sect
> > -                       - ioreq->req.seg[i].first_sect + 1) * file_blk;
> > +        segs[i].len = (ioreq->req.seg[i].last_sect -
> > +                       ioreq->req.seg[i].first_sect + 1) * file_blk;
> >          virt += segs[i].len;
> >      }
> >
> > -    rc = xen_be_copy_grant_refs(xendev, to_domain, segs, count);
> > +    xen_device_copy_grant_refs(xendev, to_domain, segs, count,
> &local_err);
> > +
> > +    if (local_err) {
> > +        const char *msg = error_get_pretty(local_err);
> > +
> > +        error_report("failed to copy data: %s", msg);
> > +        error_free(local_err);
> 
> You can do the  following instead:
>     error_prepend(local_err, "failed to copy data: ")
>     error_report_err(local_err);
> 

Done.

> > +void xen_qdisk_dataplane_start(struct XenBlkDev *blkdev,
> > +                               const unsigned int ring_ref[],
> > +                               unsigned int nr_ring_ref,
> > +                               unsigned int event_channel,
> > +                               unsigned int protocol)
> >  {
> > -    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev,
> xendev);
> > +    XenDevice *xendev = blkdev->xendev;
> > +    unsigned int ring_size;
> > +    unsigned int i;
> >
> > -    qemu_bh_schedule(blkdev->bh);
> > +    blkdev->nr_ring_ref = nr_ring_ref;
> > +    blkdev->ring_ref = g_new(unsigned int, nr_ring_ref);
> > +
> > +    for (i = 0; i < nr_ring_ref; i++) {
> > +        blkdev->ring_ref[i] = ring_ref[i];
> > +    }
> > +
> > +    blkdev->protocol = protocol;
> > +
> > +    ring_size = XC_PAGE_SIZE * blkdev->nr_ring_ref;
> > +    switch (blkdev->protocol) {
> > +    case BLKIF_PROTOCOL_NATIVE:
> > +    {
> > +        blkdev->max_requests = __CONST_RING_SIZE(blkif, ring_size);
> > +        break;
> > +    }
> > +    case BLKIF_PROTOCOL_X86_32:
> > +    {
> > +        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_32,
> ring_size);
> > +        break;
> > +    }
> > +    case BLKIF_PROTOCOL_X86_64:
> > +    {
> > +        blkdev->max_requests = __CONST_RING_SIZE(blkif_x86_64,
> ring_size);
> > +        break;
> > +    }
> > +    default:
> > +        assert(false);
> > +        break;
> 
> This should return rather than keep going.
> And maybe set an Error that could be added to the parameter of the
> function.
> 
> > +    }
> > +
> > +    xen_device_set_max_grant_refs(xendev, blkdev->nr_ring_ref,
> > +                                  &error_fatal);
> 
> Do we really want to exit() here if an error happen, rather than let the
> caller know? (Same question for other uses of error_fatal.)
> 

Indeed. I added an error pointer to the function so it can bail cleanly.

> > diff --git a/hw/block/dataplane/xen-qdisk.h b/hw/block/dataplane/xen-
> qdisk.h
> > new file mode 100644
> > index 0000000000..16bcd500bf
> > --- /dev/null
> > +++ b/hw/block/dataplane/xen-qdisk.h
> > @@ -0,0 +1,25 @@
> > +/*
> > + * Copyright (c) Citrix Systems Inc.
> > + * All rights reserved.
> > + */
> > +
> > +#ifndef HW_BLOCK_DATAPLANE_QDISK_H
> > +#define HW_BLOCK_DATAPLANE_QDISK_H
> > +
> > +#include "hw/xen/xen-bus.h"
> > +#include "sysemu/iothread.h"
> 
> I would add #include "hw/block/block.h" since it includes the definition
> of BlockConf.
> 

Sure.

  Paul

> > +
> > +typedef struct XenBlkDev XenQdiskDataPlane;
> > +
> > +XenQdiskDataPlane *xen_qdisk_dataplane_create(XenDevice *xendev,
> > +                                              BlockConf *conf,
> > +                                              IOThread *iothread);
> 
> Thanks,
> 
> --
> Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 14/18] xen: add implementations of xen-qdisk connect and disconnect functions...
  2018-12-04 12:33   ` [Qemu-devel] " Anthony PERARD
@ 2018-12-06 12:27       ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-06 12:27 UTC (permalink / raw)
  To: Anthony Perard
  Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini,
	Kevin Wolf, Max Reitz

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 04 December 2018 12:34
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> Kevin Wolf <kwolf@redhat.com>; Max Reitz <mreitz@redhat.com>
> Subject: Re: [PATCH 14/18] xen: add implementations of xen-qdisk connect
> and disconnect functions...
> 
> On Wed, Nov 21, 2018 at 03:12:07PM +0000, Paul Durrant wrote:
> > diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> > index 35f7b70480..8c88393832 100644
> > --- a/hw/block/xen-qdisk.c
> > +++ b/hw/block/xen-qdisk.c
> >  static void xen_qdisk_connect(XenQdiskDevice *qdiskdev, Error **errp)
> >  {
> >      XenQdiskVdev *vdev = &qdiskdev->vdev;
> > +    XenDevice *xendev = XEN_DEVICE(qdiskdev);
> > +    unsigned int order, nr_ring_ref, *ring_ref, event_channel,
> protocol;
> > +    char *str;
> >
> >      trace_xen_qdisk_connect(vdev->disk, vdev->partition);
> > +
> > +    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");
> 
> Don't you need to free `ring_ref`?

Yes.

> 
> > +            return;
> > +        }
> [...]
> 
> > diff --git a/include/hw/xen/xen-qdisk.h b/include/hw/xen/xen-qdisk.h
> > index ade0866037..d7dd2bf0ee 100644
> > --- a/include/hw/xen/xen-qdisk.h
> > +++ b/include/hw/xen/xen-qdisk.h
> > @@ -6,7 +6,15 @@
> >  #ifndef HW_XEN_QDISK_H
> >  #define HW_XEN_QDISK_H
> >
> > +#include "hw/xen/xen.h"
> >  #include "hw/xen/xen-bus.h"
> > +#include "hw/block/block.h"
> > +#include "hw/block/xen_blkif.h"
> > +#include "hw/block/dataplane/xen-qdisk.h"
> > +#include "sysemu/blockdev.h"
> > +#include "sysemu/iothread.h"
> > +#include "sysemu/block-backend.h"
> > +#include "sysemu/iothread.h"
> 
> You don't need that many includes, especially not iothread.h twice ;-).
> 

Oops.

> I think those new includes would be enough:
> #include "hw/block/block.h"; for BlockConf
> #include "sysemu/iothread.h"
> #include "hw/block/dataplane/xen-qdisk.h"
> 

Yes, those seem to be enough.

  Paul

> >
> >  typedef enum XenQdiskVdevType {
> >      XEN_QDISK_VDEV_TYPE_DP,
> > @@ -33,6 +41,10 @@ typedef struct XenQdiskDevice XenQdiskDevice;
> >  struct XenQdiskDevice {
> >      XenDevice xendev;
> >      XenQdiskVdev vdev;
> > +    BlockConf conf;
> > +    unsigned int max_ring_page_order;
> > +    IOThread *iothread;
> > +    XenQdiskDataPlane *dataplane;
> >  };
> >
> >  #endif /* HW_XEN_QDISK_H */
> 
> --
> Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 14/18] xen: add implementations of xen-qdisk connect and disconnect functions...
@ 2018-12-06 12:27       ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-06 12:27 UTC (permalink / raw)
  To: Anthony Perard
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, xen-devel

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 04 December 2018 12:34
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>;
> Kevin Wolf <kwolf@redhat.com>; Max Reitz <mreitz@redhat.com>
> Subject: Re: [PATCH 14/18] xen: add implementations of xen-qdisk connect
> and disconnect functions...
> 
> On Wed, Nov 21, 2018 at 03:12:07PM +0000, Paul Durrant wrote:
> > diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
> > index 35f7b70480..8c88393832 100644
> > --- a/hw/block/xen-qdisk.c
> > +++ b/hw/block/xen-qdisk.c
> >  static void xen_qdisk_connect(XenQdiskDevice *qdiskdev, Error **errp)
> >  {
> >      XenQdiskVdev *vdev = &qdiskdev->vdev;
> > +    XenDevice *xendev = XEN_DEVICE(qdiskdev);
> > +    unsigned int order, nr_ring_ref, *ring_ref, event_channel,
> protocol;
> > +    char *str;
> >
> >      trace_xen_qdisk_connect(vdev->disk, vdev->partition);
> > +
> > +    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");
> 
> Don't you need to free `ring_ref`?

Yes.

> 
> > +            return;
> > +        }
> [...]
> 
> > diff --git a/include/hw/xen/xen-qdisk.h b/include/hw/xen/xen-qdisk.h
> > index ade0866037..d7dd2bf0ee 100644
> > --- a/include/hw/xen/xen-qdisk.h
> > +++ b/include/hw/xen/xen-qdisk.h
> > @@ -6,7 +6,15 @@
> >  #ifndef HW_XEN_QDISK_H
> >  #define HW_XEN_QDISK_H
> >
> > +#include "hw/xen/xen.h"
> >  #include "hw/xen/xen-bus.h"
> > +#include "hw/block/block.h"
> > +#include "hw/block/xen_blkif.h"
> > +#include "hw/block/dataplane/xen-qdisk.h"
> > +#include "sysemu/blockdev.h"
> > +#include "sysemu/iothread.h"
> > +#include "sysemu/block-backend.h"
> > +#include "sysemu/iothread.h"
> 
> You don't need that many includes, especially not iothread.h twice ;-).
> 

Oops.

> I think those new includes would be enough:
> #include "hw/block/block.h"; for BlockConf
> #include "sysemu/iothread.h"
> #include "hw/block/dataplane/xen-qdisk.h"
> 

Yes, those seem to be enough.

  Paul

> >
> >  typedef enum XenQdiskVdevType {
> >      XEN_QDISK_VDEV_TYPE_DP,
> > @@ -33,6 +41,10 @@ typedef struct XenQdiskDevice XenQdiskDevice;
> >  struct XenQdiskDevice {
> >      XenDevice xendev;
> >      XenQdiskVdev vdev;
> > +    BlockConf conf;
> > +    unsigned int max_ring_page_order;
> > +    IOThread *iothread;
> > +    XenQdiskDataPlane *dataplane;
> >  };
> >
> >  #endif /* HW_XEN_QDISK_H */
> 
> --
> Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 15/18] xen: add a mechanism to automatically create XenDevice-s...
  2018-12-04 15:35     ` Anthony PERARD
@ 2018-12-06 12:36       ` Paul Durrant
  -1 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-06 12:36 UTC (permalink / raw)
  To: Anthony Perard; +Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 04 December 2018 15:35
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>
> Subject: Re: [PATCH 15/18] xen: add a mechanism to automatically create
> XenDevice-s...
> 
> On Wed, Nov 21, 2018 at 03:12:08PM +0000, Paul Durrant wrote:
> > +    xen_backend_device_create(BUS(xenbus), type, name, opts,
> &local_err);
> > +    qobject_unref(opts);
> > +
> > +    if (local_err) {
> > +        const char *msg = error_get_pretty(local_err);
> > +
> > +        error_report("failed to create '%s' device '%s': %s", type,
> name,
> > +                     msg);
> > +        error_free(local_err);
> 
> You can use error_reportf_err() instead of those three calls. I may have
> only suggest error_report_err in a previous patch, but error_reportf_err
> does the error_prepend as well.
> 

Ah. I'll go back over the patches and use that where necessary.

> > +    }
> > +}
> > +
> > +static void xen_bus_type_enumerate(XenBus *xenbus, const char *type)
> > +{
> > +    char *domain_path = g_strdup_printf("backend/%s/%u", type,
> xen_domid);
> > +    char **backend;
> > +    unsigned int i, n;
> > +
> > +    trace_xen_bus_type_enumerate(type);
> > +
> > +    backend = xs_directory(xenbus->xsh, XBT_NULL, domain_path, &n);
> > +    if (!backend) {
> 
> domain_path isn't free here, you probably want a `goto out` which would
> free everything.

Ok.

> 
> > +        return;
> > +    }
> > +
> > @@ -193,6 +302,17 @@ static void xen_bus_realize(BusState *bus, Error
> **errp)
> >      notifier_list_init(&xenbus->watch_notifiers);
> >      qemu_set_fd_handler(xs_fileno(xenbus->xsh), xen_bus_watch, NULL,
> >                          xenbus);
> > +
> > +    module_call_init(MODULE_INIT_XEN_BACKEND);
> > +
> > +    xenbus->backend_watch =
> > +        xen_bus_add_watch(xenbus, "", /* domain root node */
> > +                          "backend", xen_bus_enumerate, xenbus,
> &local_err);
> > +    if (local_err) {
> > +        error_propagate(errp, local_err);
> > +        error_prepend(errp, "failed to set up enumeration watch: ");
> 
> You should use error_propagate_prepend instead
> error_propagate;error_prepend. And it looks like there is the same
> mistake in other patches that I haven't notice.
> 

Oh, I didn't know about that one either... I've only seen the separate calls used elsewhere.

> Also you probably want goto fail here.
> 

Not sure about that. Whilst the bus scan won't happen, it doesn't mean devices can't be added via QMP.

> 
> > +static void xen_device_backend_changed(void *opaque)
> > +{
> > +    XenDevice *xendev = opaque;
> > +    const char *type = object_get_typename(OBJECT(xendev));
> > +    enum xenbus_state state;
> > +    unsigned int online;
> > +
> > +    trace_xen_device_backend_changed(type, xendev->name);
> > +
> > +    if (xen_device_backend_scanf(xendev, "state", "%u", &state) != 1) {
> > +        state = XenbusStateUnknown;
> > +    }
> > +
> > +    xen_device_backend_set_state(xendev, state);
> 
> It's kind of weird to set the internal state base on the external one
> that something else may have modified. Shouldn't we check that it is
> fine for something else to modify the state and that it is a correct
> transition?

The only thing (apart from this code) that's going to have perms to write the backend state is the toolstack... which is, of course, be definition trusted.

> 
> Also aren't we going in a loop by having QEMU set the state, then the
> watch fires again? (Not really a loop since the function _set_state
> check for changes.

No. It's de-bounced inside the set_state function.

> 
> Also maybe we should watch for the state changes only when something
> else like libxl creates (ask for) the backend, and ignore changes when
> QEMU did it itself.

I don't think it's necessary to add that complexity.

> 
> > +
> > +    if (xen_device_backend_scanf(xendev, "online", "%u", &online) != 1)
> {
> > +        online = 0;
> > +    }
> > +
> > +    xen_device_backend_set_online(xendev, !!online);
> > +
> > +    /*
> > +     * If a backend is still 'online' then its state should be cycled
> > +     * back round to InitWait in order for a new frontend instance to
> > +     * connect. This may happen when, for example, a frontend driver is
> > +     * re-installed or updated.
> > +     * If a backend id not 'online' then the device should be
> destroyed.
> 
> s/id/is/

Ok.

> 
> > +     */
> > +    if (xendev->backend_online &&
> > +        xendev->backend_state == XenbusStateClosed) {
> > +        xen_device_backend_set_state(xendev, XenbusStateInitWait);
> > +    } else if (!xendev->backend_online &&
> > +               (xendev->backend_state == XenbusStateClosed ||
> > +                xendev->backend_state == XenbusStateInitialising ||
> > +                xendev->backend_state == XenbusStateInitWait ||
> > +                xendev->backend_state == XenbusStateUnknown)) {
> > +        object_unparent(OBJECT(xendev));
> > +    }
> > +}
> > +
> >  static void xen_device_backend_create(XenDevice *xendev, Error **errp)
> >  {
> >      XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
> > @@ -289,12 +463,38 @@ static void xen_device_backend_create(XenDevice
> *xendev, Error **errp)
> >          error_propagate(errp, local_err);
> >          error_prepend(errp, "failed to create backend: ");
> 
> It looks like there is a missing return here.
> 
> >      }
> > +
> > +    xendev->backend_state_watch =
> > +        xen_bus_add_watch(xenbus, xendev->backend_path,
> > +                          "state", xen_device_backend_changed,
> > +                          xendev, &local_err);
> > +    if (local_err) {
> > +        error_propagate(errp, local_err);
> > +        error_prepend(errp, "failed to watch backend state: ");
> 
> You should return here, as local_err mustn't be reused.
> 
> > +    }
> > +
> > +    xendev->backend_online_watch =
> > +        xen_bus_add_watch(xenbus, xendev->backend_path,
> > +                          "online", xen_device_backend_changed,
> > +                          xendev, &local_err);
> > +    if (local_err) {
> > +        error_propagate(errp, local_err);
> > +        error_prepend(errp, "failed to watch backend online: ");
> 
> You probably want a return here, in case there is more code added after.

Yes, there should be returns in all three cases above.

> 
> > +    }
> 
> Other instances of error_propagate;error_prepend to be replaced by
> error_propagate_prepend.

Yes, will do.

  Paul

> 
> >  }
> >
> 
> Thanks,
> 
> --
> Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 15/18] xen: add a mechanism to automatically create XenDevice-s...
@ 2018-12-06 12:36       ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-06 12:36 UTC (permalink / raw)
  To: Anthony Perard; +Cc: xen-devel, Stefano Stabellini, qemu-devel, qemu-block

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 04 December 2018 15:35
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>
> Subject: Re: [PATCH 15/18] xen: add a mechanism to automatically create
> XenDevice-s...
> 
> On Wed, Nov 21, 2018 at 03:12:08PM +0000, Paul Durrant wrote:
> > +    xen_backend_device_create(BUS(xenbus), type, name, opts,
> &local_err);
> > +    qobject_unref(opts);
> > +
> > +    if (local_err) {
> > +        const char *msg = error_get_pretty(local_err);
> > +
> > +        error_report("failed to create '%s' device '%s': %s", type,
> name,
> > +                     msg);
> > +        error_free(local_err);
> 
> You can use error_reportf_err() instead of those three calls. I may have
> only suggest error_report_err in a previous patch, but error_reportf_err
> does the error_prepend as well.
> 

Ah. I'll go back over the patches and use that where necessary.

> > +    }
> > +}
> > +
> > +static void xen_bus_type_enumerate(XenBus *xenbus, const char *type)
> > +{
> > +    char *domain_path = g_strdup_printf("backend/%s/%u", type,
> xen_domid);
> > +    char **backend;
> > +    unsigned int i, n;
> > +
> > +    trace_xen_bus_type_enumerate(type);
> > +
> > +    backend = xs_directory(xenbus->xsh, XBT_NULL, domain_path, &n);
> > +    if (!backend) {
> 
> domain_path isn't free here, you probably want a `goto out` which would
> free everything.

Ok.

> 
> > +        return;
> > +    }
> > +
> > @@ -193,6 +302,17 @@ static void xen_bus_realize(BusState *bus, Error
> **errp)
> >      notifier_list_init(&xenbus->watch_notifiers);
> >      qemu_set_fd_handler(xs_fileno(xenbus->xsh), xen_bus_watch, NULL,
> >                          xenbus);
> > +
> > +    module_call_init(MODULE_INIT_XEN_BACKEND);
> > +
> > +    xenbus->backend_watch =
> > +        xen_bus_add_watch(xenbus, "", /* domain root node */
> > +                          "backend", xen_bus_enumerate, xenbus,
> &local_err);
> > +    if (local_err) {
> > +        error_propagate(errp, local_err);
> > +        error_prepend(errp, "failed to set up enumeration watch: ");
> 
> You should use error_propagate_prepend instead
> error_propagate;error_prepend. And it looks like there is the same
> mistake in other patches that I haven't notice.
> 

Oh, I didn't know about that one either... I've only seen the separate calls used elsewhere.

> Also you probably want goto fail here.
> 

Not sure about that. Whilst the bus scan won't happen, it doesn't mean devices can't be added via QMP.

> 
> > +static void xen_device_backend_changed(void *opaque)
> > +{
> > +    XenDevice *xendev = opaque;
> > +    const char *type = object_get_typename(OBJECT(xendev));
> > +    enum xenbus_state state;
> > +    unsigned int online;
> > +
> > +    trace_xen_device_backend_changed(type, xendev->name);
> > +
> > +    if (xen_device_backend_scanf(xendev, "state", "%u", &state) != 1) {
> > +        state = XenbusStateUnknown;
> > +    }
> > +
> > +    xen_device_backend_set_state(xendev, state);
> 
> It's kind of weird to set the internal state base on the external one
> that something else may have modified. Shouldn't we check that it is
> fine for something else to modify the state and that it is a correct
> transition?

The only thing (apart from this code) that's going to have perms to write the backend state is the toolstack... which is, of course, be definition trusted.

> 
> Also aren't we going in a loop by having QEMU set the state, then the
> watch fires again? (Not really a loop since the function _set_state
> check for changes.

No. It's de-bounced inside the set_state function.

> 
> Also maybe we should watch for the state changes only when something
> else like libxl creates (ask for) the backend, and ignore changes when
> QEMU did it itself.

I don't think it's necessary to add that complexity.

> 
> > +
> > +    if (xen_device_backend_scanf(xendev, "online", "%u", &online) != 1)
> {
> > +        online = 0;
> > +    }
> > +
> > +    xen_device_backend_set_online(xendev, !!online);
> > +
> > +    /*
> > +     * If a backend is still 'online' then its state should be cycled
> > +     * back round to InitWait in order for a new frontend instance to
> > +     * connect. This may happen when, for example, a frontend driver is
> > +     * re-installed or updated.
> > +     * If a backend id not 'online' then the device should be
> destroyed.
> 
> s/id/is/

Ok.

> 
> > +     */
> > +    if (xendev->backend_online &&
> > +        xendev->backend_state == XenbusStateClosed) {
> > +        xen_device_backend_set_state(xendev, XenbusStateInitWait);
> > +    } else if (!xendev->backend_online &&
> > +               (xendev->backend_state == XenbusStateClosed ||
> > +                xendev->backend_state == XenbusStateInitialising ||
> > +                xendev->backend_state == XenbusStateInitWait ||
> > +                xendev->backend_state == XenbusStateUnknown)) {
> > +        object_unparent(OBJECT(xendev));
> > +    }
> > +}
> > +
> >  static void xen_device_backend_create(XenDevice *xendev, Error **errp)
> >  {
> >      XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
> > @@ -289,12 +463,38 @@ static void xen_device_backend_create(XenDevice
> *xendev, Error **errp)
> >          error_propagate(errp, local_err);
> >          error_prepend(errp, "failed to create backend: ");
> 
> It looks like there is a missing return here.
> 
> >      }
> > +
> > +    xendev->backend_state_watch =
> > +        xen_bus_add_watch(xenbus, xendev->backend_path,
> > +                          "state", xen_device_backend_changed,
> > +                          xendev, &local_err);
> > +    if (local_err) {
> > +        error_propagate(errp, local_err);
> > +        error_prepend(errp, "failed to watch backend state: ");
> 
> You should return here, as local_err mustn't be reused.
> 
> > +    }
> > +
> > +    xendev->backend_online_watch =
> > +        xen_bus_add_watch(xenbus, xendev->backend_path,
> > +                          "online", xen_device_backend_changed,
> > +                          xendev, &local_err);
> > +    if (local_err) {
> > +        error_propagate(errp, local_err);
> > +        error_prepend(errp, "failed to watch backend online: ");
> 
> You probably want a return here, in case there is more code added after.

Yes, there should be returns in all three cases above.

> 
> > +    }
> 
> Other instances of error_propagate;error_prepend to be replaced by
> error_propagate_prepend.

Yes, will do.

  Paul

> 
> >  }
> >
> 
> Thanks,
> 
> --
> Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 16/18] xen: automatically create XenQdiskDevice-s
  2018-12-04 16:40     ` Anthony PERARD
  (?)
  (?)
@ 2018-12-06 13:06     ` Paul Durrant
  -1 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-06 13:06 UTC (permalink / raw)
  To: Anthony Perard
  Cc: qemu-block, qemu-devel, xen-devel, Kevin Wolf, Max Reitz,
	Stefano Stabellini

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 04 December 2018 16:41
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Kevin Wolf <kwolf@redhat.com>; Max Reitz
> <mreitz@redhat.com>; Stefano Stabellini <sstabellini@kernel.org>
> Subject: Re: [PATCH 16/18] xen: automatically create XenQdiskDevice-s
> 
> On Wed, Nov 21, 2018 at 03:12:09PM +0000, Paul Durrant wrote:
> > This patch adds a creator function for XenQdiskDevice-s so that they can
> > be created automatically when the Xen toolstack instantiates a new
> > PV backend. When the XenQdiskDevice is created this way it is also
> > necessary to create a drive which matches the configuration that the Xen
> > toolstack has written into xenstore. This drive is marked 'auto_del' so
> > that it will be removed when the XenQdiskDevice is destroyed. Also, for
> > compatibilitye with the legacy 'xen_disk' implementation, an iothread
> > is automatically created for the new XenQdiskDevice. This will also be
> > removed when he XenQdiskDevice is destroyed.
> 
> "the XenQdiskDevice"
> 
> [...]
> > +    qemu_opt_set(drive_opts, "file.locking", "off", &local_err);
> 
> That looks new, compared to the xen_disk.c implementation. Maybe that
> should be mention in the commit message.
> 

It's necessary to avoid problems when an emulated device is also present. The xen_disk code avoided the issue by basically bypassing the checks and stooging into the middle of the block code. I'll add a comment to the code saying why locking needs to be off.

> 
> [..]
> 
> > +static void xen_qdisk_device_create(BusState *bus, const char *name,
> > +                                    QDict *opts, Error **errp)
> > +{
> [...]
> > +    iothread = iothread_create(vdev, &error_abort);
> 
> I would just propagate the error, since iothread could fail for external
> reason. No need to crash qemu while a VM is running.

True.

> 
> > +
> > +    dev = qdev_create(bus, TYPE_XEN_QDISK_DEVICE);
> > +
> > +    qdev_prop_set_string(dev, "vdev", vdev);
> > +
> > +    if (XEN_QDISK_DEVICE(dev)->vdev.number != number) {
> > +        error_setg(errp, "invalid dev parameter '%s'", vdev);
> > +        goto unref;
> > +    }
> > +
> > +    qdev_prop_set_drive(dev, "drive", blk, &local_err);
> > +    if (local_err) {
> > +        error_propagate(errp, local_err);
> > +        error_prepend(errp, "failed to set 'drive': ");
> > +        goto unref;
> > +    }
> > +
> > +    XEN_QDISK_DEVICE(dev)->auto_iothread = iothread;
> > +
> > +    qdev_init_nofail(dev);
> 
> That function shouldn't be use during hotplug. But I'm not sure what
> should be done instead, probably object_property_set_bool(..., true
> "realized") and check for error.

Ok, I'll do that.

  Paul

> 
> 
> Thanks,
> 
> --
> Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 16/18] xen: automatically create XenQdiskDevice-s
  2018-12-04 16:40     ` Anthony PERARD
  (?)
@ 2018-12-06 13:06     ` Paul Durrant
  -1 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-06 13:06 UTC (permalink / raw)
  To: Anthony Perard
  Cc: Kevin Wolf, Stefano Stabellini, qemu-block, qemu-devel,
	Max Reitz, xen-devel

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 04 December 2018 16:41
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Kevin Wolf <kwolf@redhat.com>; Max Reitz
> <mreitz@redhat.com>; Stefano Stabellini <sstabellini@kernel.org>
> Subject: Re: [PATCH 16/18] xen: automatically create XenQdiskDevice-s
> 
> On Wed, Nov 21, 2018 at 03:12:09PM +0000, Paul Durrant wrote:
> > This patch adds a creator function for XenQdiskDevice-s so that they can
> > be created automatically when the Xen toolstack instantiates a new
> > PV backend. When the XenQdiskDevice is created this way it is also
> > necessary to create a drive which matches the configuration that the Xen
> > toolstack has written into xenstore. This drive is marked 'auto_del' so
> > that it will be removed when the XenQdiskDevice is destroyed. Also, for
> > compatibilitye with the legacy 'xen_disk' implementation, an iothread
> > is automatically created for the new XenQdiskDevice. This will also be
> > removed when he XenQdiskDevice is destroyed.
> 
> "the XenQdiskDevice"
> 
> [...]
> > +    qemu_opt_set(drive_opts, "file.locking", "off", &local_err);
> 
> That looks new, compared to the xen_disk.c implementation. Maybe that
> should be mention in the commit message.
> 

It's necessary to avoid problems when an emulated device is also present. The xen_disk code avoided the issue by basically bypassing the checks and stooging into the middle of the block code. I'll add a comment to the code saying why locking needs to be off.

> 
> [..]
> 
> > +static void xen_qdisk_device_create(BusState *bus, const char *name,
> > +                                    QDict *opts, Error **errp)
> > +{
> [...]
> > +    iothread = iothread_create(vdev, &error_abort);
> 
> I would just propagate the error, since iothread could fail for external
> reason. No need to crash qemu while a VM is running.

True.

> 
> > +
> > +    dev = qdev_create(bus, TYPE_XEN_QDISK_DEVICE);
> > +
> > +    qdev_prop_set_string(dev, "vdev", vdev);
> > +
> > +    if (XEN_QDISK_DEVICE(dev)->vdev.number != number) {
> > +        error_setg(errp, "invalid dev parameter '%s'", vdev);
> > +        goto unref;
> > +    }
> > +
> > +    qdev_prop_set_drive(dev, "drive", blk, &local_err);
> > +    if (local_err) {
> > +        error_propagate(errp, local_err);
> > +        error_prepend(errp, "failed to set 'drive': ");
> > +        goto unref;
> > +    }
> > +
> > +    XEN_QDISK_DEVICE(dev)->auto_iothread = iothread;
> > +
> > +    qdev_init_nofail(dev);
> 
> That function shouldn't be use during hotplug. But I'm not sure what
> should be done instead, probably object_property_set_bool(..., true
> "realized") and check for error.

Ok, I'll do that.

  Paul

> 
> 
> Thanks,
> 
> --
> Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 15/18] xen: add a mechanism to automatically create XenDevice-s...
  2018-12-06 12:36       ` Paul Durrant
  (?)
  (?)
@ 2018-12-06 15:24       ` Anthony PERARD
  2018-12-06 15:36           ` Paul Durrant
  -1 siblings, 1 reply; 157+ messages in thread
From: Anthony PERARD @ 2018-12-06 15:24 UTC (permalink / raw)
  To: Paul Durrant; +Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini

On Thu, Dec 06, 2018 at 12:36:52PM +0000, Paul Durrant wrote:
> > -----Original Message-----
> > From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> > Sent: 04 December 2018 15:35
> > 
> > On Wed, Nov 21, 2018 at 03:12:08PM +0000, Paul Durrant wrote:
> > > +    xenbus->backend_watch =
> > > +        xen_bus_add_watch(xenbus, "", /* domain root node */
> > > +                          "backend", xen_bus_enumerate, xenbus,
> > &local_err);
> > > +    if (local_err) {
> > > +        error_propagate(errp, local_err);
> > > +        error_prepend(errp, "failed to set up enumeration watch: ");
> > 
> > You should use error_propagate_prepend instead
> > error_propagate;error_prepend. And it looks like there is the same
> > mistake in other patches that I haven't notice.
> > 
> 
> Oh, I didn't know about that one either... I've only seen the separate calls used elsewhere.

That information is all in "include/qapi/error.h", if you which to know
more on how to use Error.

> > Also you probably want goto fail here.
> > 
> 
> Not sure about that. Whilst the bus scan won't happen, it doesn't mean devices can't be added via QMP.

In that case, don't modify errp, and use error_reportf_err instead, or
warn_reportf_err (then local_err = NULL, in case it is reused in a
future modification of the function).

Setting errp (with error_propagate) means that the function failed, and
QEMU is going to exit(1), because of qdev_init_nofail call in
xen_bus_init.

> > > +static void xen_device_backend_changed(void *opaque)
> > > +{
> > > +    XenDevice *xendev = opaque;
> > > +    const char *type = object_get_typename(OBJECT(xendev));
> > > +    enum xenbus_state state;
> > > +    unsigned int online;
> > > +
> > > +    trace_xen_device_backend_changed(type, xendev->name);
> > > +
> > > +    if (xen_device_backend_scanf(xendev, "state", "%u", &state) != 1) {
> > > +        state = XenbusStateUnknown;
> > > +    }
> > > +
> > > +    xen_device_backend_set_state(xendev, state);
> > 
> > It's kind of weird to set the internal state base on the external one
> > that something else may have modified. Shouldn't we check that it is
> > fine for something else to modify the state and that it is a correct
> > transition?
> 
> The only thing (apart from this code) that's going to have perms to write the backend state is the toolstack... which is, of course, be definition trusted.

"trusted" doesn't mean that there isn't a bug somewhere else :-). But I
guess it's good enough for now.

> > Also aren't we going in a loop by having QEMU set the state, then the
> > watch fires again? (Not really a loop since the function _set_state
> > check for changes.
> 
> No. It's de-bounced inside the set_state function.
> 
> > 
> > Also maybe we should watch for the state changes only when something
> > else like libxl creates (ask for) the backend, and ignore changes when
> > QEMU did it itself.
> 
> I don't think it's necessary to add that complexity.

Ok.

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 15/18] xen: add a mechanism to automatically create XenDevice-s...
  2018-12-06 12:36       ` Paul Durrant
  (?)
@ 2018-12-06 15:24       ` Anthony PERARD
  -1 siblings, 0 replies; 157+ messages in thread
From: Anthony PERARD @ 2018-12-06 15:24 UTC (permalink / raw)
  To: Paul Durrant; +Cc: xen-devel, Stefano Stabellini, qemu-devel, qemu-block

On Thu, Dec 06, 2018 at 12:36:52PM +0000, Paul Durrant wrote:
> > -----Original Message-----
> > From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> > Sent: 04 December 2018 15:35
> > 
> > On Wed, Nov 21, 2018 at 03:12:08PM +0000, Paul Durrant wrote:
> > > +    xenbus->backend_watch =
> > > +        xen_bus_add_watch(xenbus, "", /* domain root node */
> > > +                          "backend", xen_bus_enumerate, xenbus,
> > &local_err);
> > > +    if (local_err) {
> > > +        error_propagate(errp, local_err);
> > > +        error_prepend(errp, "failed to set up enumeration watch: ");
> > 
> > You should use error_propagate_prepend instead
> > error_propagate;error_prepend. And it looks like there is the same
> > mistake in other patches that I haven't notice.
> > 
> 
> Oh, I didn't know about that one either... I've only seen the separate calls used elsewhere.

That information is all in "include/qapi/error.h", if you which to know
more on how to use Error.

> > Also you probably want goto fail here.
> > 
> 
> Not sure about that. Whilst the bus scan won't happen, it doesn't mean devices can't be added via QMP.

In that case, don't modify errp, and use error_reportf_err instead, or
warn_reportf_err (then local_err = NULL, in case it is reused in a
future modification of the function).

Setting errp (with error_propagate) means that the function failed, and
QEMU is going to exit(1), because of qdev_init_nofail call in
xen_bus_init.

> > > +static void xen_device_backend_changed(void *opaque)
> > > +{
> > > +    XenDevice *xendev = opaque;
> > > +    const char *type = object_get_typename(OBJECT(xendev));
> > > +    enum xenbus_state state;
> > > +    unsigned int online;
> > > +
> > > +    trace_xen_device_backend_changed(type, xendev->name);
> > > +
> > > +    if (xen_device_backend_scanf(xendev, "state", "%u", &state) != 1) {
> > > +        state = XenbusStateUnknown;
> > > +    }
> > > +
> > > +    xen_device_backend_set_state(xendev, state);
> > 
> > It's kind of weird to set the internal state base on the external one
> > that something else may have modified. Shouldn't we check that it is
> > fine for something else to modify the state and that it is a correct
> > transition?
> 
> The only thing (apart from this code) that's going to have perms to write the backend state is the toolstack... which is, of course, be definition trusted.

"trusted" doesn't mean that there isn't a bug somewhere else :-). But I
guess it's good enough for now.

> > Also aren't we going in a loop by having QEMU set the state, then the
> > watch fires again? (Not really a loop since the function _set_state
> > check for changes.
> 
> No. It's de-bounced inside the set_state function.
> 
> > 
> > Also maybe we should watch for the state changes only when something
> > else like libxl creates (ask for) the backend, and ignore changes when
> > QEMU did it itself.
> 
> I don't think it's necessary to add that complexity.

Ok.

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [Qemu-devel] [PATCH 15/18] xen: add a mechanism to automatically create XenDevice-s...
  2018-12-06 15:24       ` [Qemu-devel] " Anthony PERARD
@ 2018-12-06 15:36           ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-06 15:36 UTC (permalink / raw)
  To: Anthony Perard; +Cc: qemu-block, qemu-devel, xen-devel, Stefano Stabellini

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 06 December 2018 15:24
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>
> Subject: Re: [PATCH 15/18] xen: add a mechanism to automatically create
> XenDevice-s...
> 
> On Thu, Dec 06, 2018 at 12:36:52PM +0000, Paul Durrant wrote:
> > > -----Original Message-----
> > > From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> > > Sent: 04 December 2018 15:35
> > >
> > > On Wed, Nov 21, 2018 at 03:12:08PM +0000, Paul Durrant wrote:
> > > > +    xenbus->backend_watch =
> > > > +        xen_bus_add_watch(xenbus, "", /* domain root node */
> > > > +                          "backend", xen_bus_enumerate, xenbus,
> > > &local_err);
> > > > +    if (local_err) {
> > > > +        error_propagate(errp, local_err);
> > > > +        error_prepend(errp, "failed to set up enumeration watch:
> ");
> > >
> > > You should use error_propagate_prepend instead
> > > error_propagate;error_prepend. And it looks like there is the same
> > > mistake in other patches that I haven't notice.
> > >
> >
> > Oh, I didn't know about that one either... I've only seen the separate
> calls used elsewhere.
> 
> That information is all in "include/qapi/error.h", if you which to know
> more on how to use Error.
> 

Thanks.

> > > Also you probably want goto fail here.
> > >
> >
> > Not sure about that. Whilst the bus scan won't happen, it doesn't mean
> devices can't be added via QMP.
> 
> In that case, don't modify errp, and use error_reportf_err instead, or
> warn_reportf_err (then local_err = NULL, in case it is reused in a
> future modification of the function).
> 
> Setting errp (with error_propagate) means that the function failed, and
> QEMU is going to exit(1), because of qdev_init_nofail call in
> xen_bus_init.

Ah, good point. I'll wait for more feedback on v2 and then fix in v3.

  Paul

^ permalink raw reply	[flat|nested] 157+ messages in thread

* Re: [PATCH 15/18] xen: add a mechanism to automatically create XenDevice-s...
@ 2018-12-06 15:36           ` Paul Durrant
  0 siblings, 0 replies; 157+ messages in thread
From: Paul Durrant @ 2018-12-06 15:36 UTC (permalink / raw)
  To: Anthony Perard; +Cc: xen-devel, Stefano Stabellini, qemu-devel, qemu-block

> -----Original Message-----
> From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> Sent: 06 December 2018 15:24
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: qemu-block@nongnu.org; qemu-devel@nongnu.org; xen-
> devel@lists.xenproject.org; Stefano Stabellini <sstabellini@kernel.org>
> Subject: Re: [PATCH 15/18] xen: add a mechanism to automatically create
> XenDevice-s...
> 
> On Thu, Dec 06, 2018 at 12:36:52PM +0000, Paul Durrant wrote:
> > > -----Original Message-----
> > > From: Anthony PERARD [mailto:anthony.perard@citrix.com]
> > > Sent: 04 December 2018 15:35
> > >
> > > On Wed, Nov 21, 2018 at 03:12:08PM +0000, Paul Durrant wrote:
> > > > +    xenbus->backend_watch =
> > > > +        xen_bus_add_watch(xenbus, "", /* domain root node */
> > > > +                          "backend", xen_bus_enumerate, xenbus,
> > > &local_err);
> > > > +    if (local_err) {
> > > > +        error_propagate(errp, local_err);
> > > > +        error_prepend(errp, "failed to set up enumeration watch:
> ");
> > >
> > > You should use error_propagate_prepend instead
> > > error_propagate;error_prepend. And it looks like there is the same
> > > mistake in other patches that I haven't notice.
> > >
> >
> > Oh, I didn't know about that one either... I've only seen the separate
> calls used elsewhere.
> 
> That information is all in "include/qapi/error.h", if you which to know
> more on how to use Error.
> 

Thanks.

> > > Also you probably want goto fail here.
> > >
> >
> > Not sure about that. Whilst the bus scan won't happen, it doesn't mean
> devices can't be added via QMP.
> 
> In that case, don't modify errp, and use error_reportf_err instead, or
> warn_reportf_err (then local_err = NULL, in case it is reused in a
> future modification of the function).
> 
> Setting errp (with error_propagate) means that the function failed, and
> QEMU is going to exit(1), because of qdev_init_nofail call in
> xen_bus_init.

Ah, good point. I'll wait for more feedback on v2 and then fix in v3.

  Paul


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 157+ messages in thread

end of thread, other threads:[~2018-12-06 15:49 UTC | newest]

Thread overview: 157+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-21 15:11 [Qemu-devel] [PATCH 00/18] Xen PV backend 'qdevification' Paul Durrant
2018-11-21 15:11 ` [Qemu-devel] [PATCH 01/18] xen: re-name XenDevice to XenLegacyDevice Paul Durrant
2018-11-21 15:11   ` Paul Durrant
2018-11-28 16:06   ` [Qemu-devel] " Anthony PERARD
2018-11-28 16:06   ` Anthony PERARD
2018-11-21 15:11 ` [Qemu-devel] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy Paul Durrant
2018-11-28 16:19   ` [Qemu-block] " Kevin Wolf
2018-11-28 16:19   ` [Qemu-devel] " Kevin Wolf
2018-11-28 16:26     ` Paul Durrant
2018-11-28 16:26       ` Paul Durrant
2018-11-28 16:28       ` [Qemu-devel] " Paul Durrant
2018-11-28 16:28         ` Paul Durrant
2018-11-28 16:28       ` [Qemu-devel] " Stefano Stabellini
2018-11-28 16:28         ` Stefano Stabellini
2018-11-28 16:29         ` [Qemu-devel] " Paul Durrant
2018-11-28 16:29           ` Paul Durrant
2018-11-28 16:39           ` [Qemu-devel] " Kevin Wolf
2018-11-28 16:39             ` Kevin Wolf
2018-11-28 16:45             ` [Qemu-devel] " Paul Durrant
2018-11-28 16:46               ` Paul Durrant
2018-11-28 16:46                 ` Paul Durrant
2018-11-29  9:04                 ` [Qemu-devel] " Kevin Wolf
2018-11-29  9:04                   ` Kevin Wolf
2018-11-28 16:45             ` Paul Durrant
2018-11-28 17:01       ` [Qemu-devel] " Eric Blake
2018-11-28 17:01         ` Eric Blake
2018-11-28 17:04         ` Paul Durrant
2018-11-28 17:04           ` Paul Durrant
2018-11-28 17:10   ` [Qemu-devel] " Anthony PERARD
2018-11-28 17:10     ` Anthony PERARD
2018-11-28 17:17     ` [Qemu-devel] " Paul Durrant
2018-11-28 17:17       ` Paul Durrant
2018-11-28 17:32       ` [Qemu-devel] " Anthony PERARD
2018-11-28 17:32         ` Anthony PERARD
2018-11-21 15:11 ` Paul Durrant
2018-11-21 15:11 ` [PATCH 03/18] xen: introduce 'xen-qdisk' Paul Durrant
2018-11-21 15:11 ` [Qemu-devel] " Paul Durrant
2018-11-29 16:05   ` Anthony PERARD
2018-11-29 16:05   ` [Qemu-devel] " Anthony PERARD
2018-12-04 15:20     ` Paul Durrant
2018-12-04 15:49       ` Anthony PERARD
2018-12-04 15:50         ` Paul Durrant
2018-12-04 15:50         ` Paul Durrant
2018-12-04 15:49       ` Anthony PERARD
2018-12-04 17:14       ` [Qemu-devel] " Paul Durrant
2018-12-04 17:14       ` Paul Durrant
2018-12-04 15:20     ` Paul Durrant
2018-11-21 15:11 ` [Qemu-devel] [PATCH 04/18] xen: create xenstore areas for XenDevice-s Paul Durrant
2018-11-29 18:48   ` Anthony PERARD
2018-11-29 18:48   ` [Qemu-devel] " Anthony PERARD
2018-12-05 12:05     ` Paul Durrant
2018-12-05 12:43       ` Paul Durrant
2018-12-05 12:43       ` [Qemu-devel] " Paul Durrant
2018-12-05 13:58         ` Anthony PERARD
2018-12-05 14:24           ` Paul Durrant
2018-12-05 14:24           ` Paul Durrant
2018-12-05 13:58         ` Anthony PERARD
2018-12-05 16:28       ` Anthony PERARD
2018-12-05 16:28       ` [Qemu-devel] " Anthony PERARD
2018-12-05 12:05     ` Paul Durrant
2018-11-21 15:11 ` Paul Durrant
2018-11-21 15:11 ` [Qemu-devel] [PATCH 05/18] xen: add xenstore watcher infratructure Paul Durrant
2018-12-03 14:42   ` Anthony PERARD
2018-12-05 15:24     ` Paul Durrant
2018-12-05 15:24     ` Paul Durrant
2018-12-03 14:42   ` Anthony PERARD
2018-11-21 15:11 ` Paul Durrant
2018-11-21 15:11 ` [Qemu-devel] [PATCH 06/18] xen: add grant table interface for XenDevice-s Paul Durrant
2018-11-21 15:11   ` Paul Durrant
2018-12-03 15:45   ` [Qemu-devel] " Anthony PERARD
2018-12-03 15:45     ` Anthony PERARD
2018-12-05 16:12     ` Paul Durrant
2018-12-05 16:12     ` [Qemu-devel] " Paul Durrant
2018-11-21 15:12 ` [PATCH 07/18] xen: add event channel " Paul Durrant
2018-11-21 15:12 ` [Qemu-devel] " Paul Durrant
2018-12-03 16:24   ` Anthony PERARD
2018-12-03 16:24     ` Anthony PERARD
2018-12-04 14:24     ` [Qemu-devel] " Anthony PERARD
2018-12-04 14:24       ` Anthony PERARD
2018-12-05 16:16       ` Paul Durrant
2018-12-05 16:16       ` [Qemu-devel] " Paul Durrant
2018-11-21 15:12 ` [Qemu-devel] [PATCH 08/18] xen: duplicate xen_disk.c as basis of dataplane/xen-qdisk.c Paul Durrant
2018-11-21 15:12   ` Paul Durrant
2018-12-03 16:35   ` [Qemu-devel] " Anthony PERARD
2018-12-03 16:35     ` Anthony PERARD
2018-12-03 16:42     ` [Qemu-devel] " Anthony PERARD
2018-12-03 16:42       ` Anthony PERARD
2018-11-21 15:12 ` [Qemu-devel] [PATCH 09/18] xen: remove unnecessary code from dataplane/xen-qdisk.c Paul Durrant
2018-11-21 15:12   ` Paul Durrant
2018-12-03 16:58   ` [Qemu-devel] " Anthony PERARD
2018-12-03 16:58     ` Anthony PERARD
2018-11-21 15:12 ` [Qemu-devel] [PATCH 10/18] xen: add header and build dataplane/xen-qdisk.c Paul Durrant
2018-11-21 15:12   ` Paul Durrant
2018-12-03 18:09   ` Anthony PERARD
2018-12-03 18:09   ` [Qemu-devel] " Anthony PERARD
2018-12-05 17:31     ` Paul Durrant
2018-12-05 17:31     ` [Qemu-devel] " Paul Durrant
2018-11-21 15:12 ` [PATCH 11/18] xen: remove 'XenBlkDev' and 'blkdev' names from dataplane/xen-qdisk Paul Durrant
2018-11-21 15:12 ` [Qemu-devel] " Paul Durrant
2018-12-04 11:05   ` Anthony PERARD
2018-12-04 11:05   ` [Qemu-devel] " Anthony PERARD
2018-11-21 15:12 ` [Qemu-devel] [PATCH 12/18] xen: remove 'ioreq' struct/varable/field names from dataplane/xen-qdisk.c Paul Durrant
2018-11-21 15:12   ` Paul Durrant
2018-12-04 11:34   ` Anthony PERARD
2018-12-04 11:34   ` [Qemu-devel] " Anthony PERARD
2018-11-21 15:12 ` [Qemu-devel] [PATCH 13/18] xen: purge 'blk' and 'ioreq' from function names in dataplane/xen-qdisk.c Paul Durrant
2018-11-21 15:12   ` Paul Durrant
2018-12-04 12:10   ` [Qemu-devel] " Anthony PERARD
2018-12-04 12:10     ` Anthony PERARD
2018-12-05 17:28     ` [Qemu-devel] " Paul Durrant
2018-12-05 17:28     ` Paul Durrant
2018-11-21 15:12 ` [PATCH 14/18] xen: add implementations of xen-qdisk connect and disconnect functions Paul Durrant
2018-11-21 15:12 ` [Qemu-devel] " Paul Durrant
2018-11-28 16:34   ` Kevin Wolf
2018-11-28 16:34     ` Kevin Wolf
2018-11-28 16:40     ` [Qemu-devel] " Paul Durrant
2018-11-28 16:40       ` Paul Durrant
2018-11-29  9:00       ` [Qemu-devel] " Kevin Wolf
2018-11-29  9:33         ` Paul Durrant
2018-11-29 10:46           ` Kevin Wolf
2018-11-29 10:46             ` Kevin Wolf
2018-11-29 10:47             ` Paul Durrant
2018-11-29 10:47             ` [Qemu-devel] " Paul Durrant
2018-11-29  9:33         ` Paul Durrant
2018-11-29  9:00       ` Kevin Wolf
2018-12-04 12:33   ` Anthony PERARD
2018-12-04 12:33   ` [Qemu-devel] " Anthony PERARD
2018-12-06 12:27     ` Paul Durrant
2018-12-06 12:27       ` Paul Durrant
2018-11-21 15:12 ` [Qemu-devel] [PATCH 15/18] xen: add a mechanism to automatically create XenDevice-s Paul Durrant
2018-11-21 15:12   ` Paul Durrant
2018-12-04 15:35   ` [Qemu-devel] " Anthony PERARD
2018-12-04 15:35     ` Anthony PERARD
2018-12-06 12:36     ` [Qemu-devel] " Paul Durrant
2018-12-06 12:36       ` Paul Durrant
2018-12-06 15:24       ` Anthony PERARD
2018-12-06 15:24       ` [Qemu-devel] " Anthony PERARD
2018-12-06 15:36         ` Paul Durrant
2018-12-06 15:36           ` Paul Durrant
2018-11-21 15:12 ` [Qemu-devel] [PATCH 16/18] xen: automatically create XenQdiskDevice-s Paul Durrant
2018-12-04 16:40   ` Anthony PERARD
2018-12-04 16:40     ` Anthony PERARD
2018-12-06 13:06     ` Paul Durrant
2018-12-06 13:06     ` [Qemu-devel] " Paul Durrant
2018-11-21 15:12 ` Paul Durrant
2018-11-21 15:12 ` [Qemu-devel] [PATCH 17/18] MAINTAINERS: add myself as a Xen maintainer Paul Durrant
2018-11-21 15:12   ` Paul Durrant
2018-11-27 19:05   ` Stefano Stabellini
2018-11-27 19:05   ` [Qemu-devel] " Stefano Stabellini
2018-11-29 14:00   ` Philippe Mathieu-Daudé
2018-11-29 14:01     ` Paul Durrant
2018-11-29 14:01     ` Paul Durrant
2018-11-29 14:00   ` Philippe Mathieu-Daudé
2018-12-04 16:42   ` Anthony PERARD
2018-12-04 16:42     ` Anthony PERARD
2018-11-21 15:12 ` [Qemu-devel] [PATCH 18/18] xen: remove the legacy 'xen_disk' backend Paul Durrant
2018-11-21 15:12   ` Paul Durrant

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.