All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes)
@ 2019-09-19 17:16 Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 01/35] libxl: Make libxl_domain_unpause async Anthony PERARD
                   ` (35 more replies)
  0 siblings, 36 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

Patches with missing ackes:
    libxl: Use ev_qmp for switch_qemu_xen_logdirty
    libxl: Use ev_qmp in libxl_set_vcpuonline
    libxl_pci: Extract common part of *qemu_trad_watch_state_cb

The series depends on "Some cleanup of libxl" series.
Patch series available in this git branch (which is on top of the branch
br.libxl-cleanup-v2):
https://xenbits.xen.org/git-http/people/aperard/xen-unstable.git br.libxl-ev_qmp-refactoring-v2

Hi,

On the quest to have QEMU depriviledge, we need to make quite a few changes to
libxl. This patch series rework quite a few libxl feature to use libxl__ev_qmp,
which is the new asynchronous way of communicating with QEMU in libxl.

Unfortunately, some libxl functions (in the public API) are supposed to be
synchronous but are communicating with QEMU before returning. So those functions
are made asynchronous with an additional parameter `libxl_asyncop_how'.

% libxl API changes

Functions that are changes:
    - libxl_domain_unpause
    - libxl_domain_pause
    - libxl_send_trigger
    - libxl_set_vcpuonline
    - libxl_retrieve_domain_configuration
    - libxl_qemu_monitor_command

% Patch series dependency

This series depends on:
    - [PATCH 00/15] Some cleanup of libxl
      (its v2)

Cheers,

Anthony PERARD (35):
  libxl: Make libxl_domain_unpause async
  libxl: Make libxl_send_trigger async
  libxl: Make libxl_set_vcpuonline async
  libxl: Make libxl_retrieve_domain_configuration async
  libxl: Make libxl_qemu_monitor_command async
  libxl: Use ev_qmp for switch_qemu_xen_logdirty
  libxl: Move "qmp_initializations" to libxl_dm
  libxl: Replace libxl__qmp_initializations by ev_qmp calls
  libxl: Deprecate libxl__domain_{unpause,resume}
  libxl: Re-introduce libxl__domain_resume
  libxl_domain: Convert libxl_domain_resume to use libxl__domain_resume
  libxl: Re-introduce libxl__domain_unpause
  libxl_dm: Update libxl__spawn_stub_dm to use libxl__domain_unpause
  libxl_domain: Convert libxl_domain_unpause to use
    libxl__domain_unpause
  libxl: Inline do_usbdev_add into libxl__device_usbdev_add
  libxl: Inline do_usbdev_remove into libxl__device_usbdev_remove
  libxl: Add libxl__ev_qmp to libxl__ao_device
  libxl: Add device_{config,type} to libxl__ao_device
  libxl_usb: Make libxl__device_usbctrl_add uses ev_qmp
  libxl_usb: Make libxl__initiate_device_usbctrl_remove uses ev_qmp
  libxl_usb: Make libxl__device_usbdev_add uses ev_qmp
  libxl: Use aodev for libxl__device_usbdev_remove
  libxl: libxl__initiate_device_usbdev_remove now use ev_qmp
  libxl: Remove libxl__qmp_run_command_flexarray
  libxl_pci: Coding style of do_pci_add
  libxl_pci: Only check if qemu-dm is running in qemu-trad case
  libxl_pci: Use libxl__ao_device with libxl__device_pci_add
  libxl_pci: Use ev_qmp in do_pci_add
  libxl_pci: Use libxl__ao_device with pci_remove
  libxl_pci: Use ev_qmp for pci_remove
  libxl: Use ev_qmp for libxl_send_trigger
  libxl: Use ev_qmp in libxl_set_vcpuonline
  libxl: libxl_retrieve_domain_configuration now uses ev_qmp
  libxl: libxl_qemu_monitor_command now uses ev_qmp
  libxl_pci: Extract common part of *qemu_trad_watch_state_cb

 tools/libxl/libxl.h              |  92 ++-
 tools/libxl/libxl_colo_restore.c |   4 +-
 tools/libxl/libxl_colo_save.c    |   4 +-
 tools/libxl/libxl_create.c       |  10 -
 tools/libxl/libxl_device.c       |   2 +
 tools/libxl/libxl_dm.c           | 239 +++++++-
 tools/libxl/libxl_dom_save.c     |  41 +-
 tools/libxl/libxl_dom_suspend.c  | 198 ++++++-
 tools/libxl/libxl_domain.c       | 627 ++++++++++++++++----
 tools/libxl/libxl_internal.h     |  90 ++-
 tools/libxl/libxl_pci.c          | 976 ++++++++++++++++++++++++++-----
 tools/libxl/libxl_qmp.c          | 471 ++-------------
 tools/libxl/libxl_remus.c        |   2 +-
 tools/libxl/libxl_usb.c          | 598 +++++++++++++------
 tools/xl/xl_cpupool.c            |   2 +-
 tools/xl/xl_info.c               |   3 +-
 tools/xl/xl_migrate.c            |   4 +-
 tools/xl/xl_misc.c               |   6 +-
 tools/xl/xl_saverestore.c        |   5 +-
 tools/xl/xl_vcpu.c               |   2 +-
 tools/xl/xl_vmcontrol.c          |  13 +-
 21 files changed, 2456 insertions(+), 933 deletions(-)

-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 01/35] libxl: Make libxl_domain_unpause async
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 02/35] libxl: Make libxl_send_trigger async Anthony PERARD
                   ` (34 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

libxl_domain_unpause needs to make QMP calls, which are asynchronous,
change the API to reflect that.

Do the same with libxl_domain_pause async, even if it will keep
completing synchronously.

Also fix some coding style issue in those functions.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---

Notes:
    v2:
    - Added LIBXL_HAVE_FN_USING_QMP_ASYNC

 tools/libxl/libxl.h              | 37 ++++++++++++++++++++++--
 tools/libxl/libxl_colo_restore.c |  2 +-
 tools/libxl/libxl_colo_save.c    |  2 +-
 tools/libxl/libxl_dm.c           |  2 +-
 tools/libxl/libxl_domain.c       | 48 +++++++++++++++++++++-----------
 tools/libxl/libxl_internal.h     |  1 +
 tools/xl/xl_migrate.c            |  4 +--
 tools/xl/xl_saverestore.c        |  2 +-
 tools/xl/xl_vmcontrol.c          |  6 ++--
 9 files changed, 76 insertions(+), 28 deletions(-)

diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index b165b2831176..10dfde3fd897 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -638,7 +638,8 @@ typedef struct libxl__ctx libxl_ctx;
 /* API compatibility. */
 #ifdef LIBXL_API_VERSION
 #if LIBXL_API_VERSION != 0x040200 && LIBXL_API_VERSION != 0x040300 && \
-    LIBXL_API_VERSION != 0x040400 && LIBXL_API_VERSION != 0x040500
+    LIBXL_API_VERSION != 0x040400 && LIBXL_API_VERSION != 0x040500 && \
+    LIBXL_API_VERSION != 0x041300
 #error Unknown LIBXL_API_VERSION
 #endif
 #endif
@@ -1210,6 +1211,17 @@ void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, const libxl_mac *src);
  */
 #define LIBXL_HAVE_PVCALLS 1
 
+/*
+ * LIBXL_HAVE_FN_USING_QMP_ASYNC
+ *
+ * This define indicates that some function's API has changed and have an
+ * extra parameter "ao_how" which means that the function can be executed
+ * asynchronously. Those functions are:
+ *   libxl_domain_pause()
+ *   libxl_domain_unpause()
+ */
+#define LIBXL_HAVE_FN_USING_QMP_ASYNC 1
+
 typedef char **libxl_string_list;
 void libxl_string_list_dispose(libxl_string_list *sl);
 int libxl_string_list_length(const libxl_string_list *sl);
@@ -1614,8 +1626,27 @@ int libxl_domain_rename(libxl_ctx *ctx, uint32_t domid,
    * transactionally that the domain has the old old name; if
    * trans is not 0 we use caller's transaction and caller must do retries */
 
-int libxl_domain_pause(libxl_ctx *ctx, uint32_t domid);
-int libxl_domain_unpause(libxl_ctx *ctx, uint32_t domid);
+int libxl_domain_pause(libxl_ctx *ctx, uint32_t domid,
+                       const libxl_asyncop_how *ao_how)
+                       LIBXL_EXTERNAL_CALLERS_ONLY;
+int libxl_domain_unpause(libxl_ctx *ctx, uint32_t domid,
+                         const libxl_asyncop_how *ao_how)
+                         LIBXL_EXTERNAL_CALLERS_ONLY;
+#if defined(LIBXL_API_VERSION) && LIBXL_API_VERSION < 0x041300
+static inline int libxl_domain_pause_0x041200(
+    libxl_ctx *ctx, uint32_t domid)
+{
+    return libxl_domain_pause(ctx, domid, NULL);
+}
+static inline int libxl_domain_unpause_0x041200(
+    libxl_ctx *ctx, uint32_t domid)
+{
+    return libxl_domain_unpause(ctx, domid, NULL);
+}
+#define libxl_domain_pause libxl_domain_pause_0x041200
+#define libxl_domain_unpause libxl_domain_unpause_0x041200
+#endif
+
 
 int libxl_domain_core_dump(libxl_ctx *ctx, uint32_t domid,
                            const char *filename,
diff --git a/tools/libxl/libxl_colo_restore.c b/tools/libxl/libxl_colo_restore.c
index 0c535bd95d69..aaa70552b8c4 100644
--- a/tools/libxl/libxl_colo_restore.c
+++ b/tools/libxl/libxl_colo_restore.c
@@ -853,7 +853,7 @@ static void colo_unpause_svm(libxl__egc *egc,
     EGC_GC;
 
     /* We have enabled secondary vm's logdirty, so we can unpause it now */
-    rc = libxl_domain_unpause(CTX, domid);
+    rc = libxl__domain_unpause(gc, domid);
     if (rc) {
         LOGD(ERROR, domid, "cannot unpause secondary vm");
         goto out;
diff --git a/tools/libxl/libxl_colo_save.c b/tools/libxl/libxl_colo_save.c
index 3247cce3a7e5..1d261a1639f7 100644
--- a/tools/libxl/libxl_colo_save.c
+++ b/tools/libxl/libxl_colo_save.c
@@ -480,7 +480,7 @@ static void colo_preresume_cb(libxl__egc *egc,
      * no disk migration.
      */
     if (css->paused) {
-        rc = libxl_domain_unpause(CTX, dss->domid);
+        rc = libxl__domain_unpause(gc, dss->domid);
         if (rc) {
             LOGD(ERROR, dss->domid, "cannot unpause primary vm");
             goto out;
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index 5fe25b56f596..00da59153d67 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -2402,7 +2402,7 @@ static void stubdom_pvqemu_cb(libxl__egc *egc,
         goto out;
     }
 
-    rc = libxl_domain_unpause(CTX, dm_domid);
+    rc = libxl__domain_unpause(gc, dm_domid);
     if (rc) goto out;
 
     sdss->xswait.ao = ao;
diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c
index 11a29b235b1d..1c313005db51 100644
--- a/tools/libxl/libxl_domain.c
+++ b/tools/libxl/libxl_domain.c
@@ -557,18 +557,18 @@ int libxl_domain_suspend_only(libxl_ctx *ctx, uint32_t domid,
     return AO_CREATE_FAIL(rc);
 }
 
-int libxl_domain_pause(libxl_ctx *ctx, uint32_t domid)
+int libxl_domain_pause(libxl_ctx *ctx, uint32_t domid,
+                       const libxl_asyncop_how *ao_how)
 {
-    int ret;
-    GC_INIT(ctx);
-    ret = xc_domain_pause(ctx->xch, domid);
-    if (ret<0) {
+    AO_CREATE(ctx, domid, ao_how);
+    int r;
+    r = xc_domain_pause(ctx->xch, domid);
+    if (r < 0) {
         LOGED(ERROR, domid, "Pausing domain");
-        GC_FREE;
-        return ERROR_FAIL;
+        return AO_CREATE_FAIL(ERROR_FAIL);
     }
-    GC_FREE;
-    return 0;
+    libxl__ao_complete(egc, ao, 0);
+    return AO_INPROGRESS;
 }
 
 int libxl_domain_core_dump(libxl_ctx *ctx, uint32_t domid,
@@ -593,10 +593,9 @@ int libxl_domain_core_dump(libxl_ctx *ctx, uint32_t domid,
     return AO_INPROGRESS;
 }
 
-int libxl_domain_unpause(libxl_ctx *ctx, uint32_t domid)
+int libxl__domain_unpause(libxl__gc *gc, libxl_domid domid)
 {
-    GC_INIT(ctx);
-    int ret, rc = 0;
+    int r, rc;
 
     libxl_domain_type type = libxl__domain_type(gc, domid);
     if (type == LIBXL_DOMAIN_TYPE_INVALID) {
@@ -612,16 +611,33 @@ int libxl_domain_unpause(libxl_ctx *ctx, uint32_t domid)
             goto out;
         }
     }
-    ret = xc_domain_unpause(ctx->xch, domid);
-    if (ret<0) {
+    r = xc_domain_unpause(CTX->xch, domid);
+    if (r < 0) {
         LOGED(ERROR, domid, "Unpausing domain");
         rc = ERROR_FAIL;
+        goto out;
     }
- out:
-    GC_FREE;
+    rc = 0;
+out:
     return rc;
 }
 
+int libxl_domain_unpause(libxl_ctx *ctx, uint32_t domid,
+                         const libxl_asyncop_how *ao_how)
+{
+    AO_CREATE(ctx, domid, ao_how);
+    int rc = 0;
+
+    rc = libxl__domain_unpause(gc, domid);
+    if (rc) goto out;
+
+    libxl__ao_complete(egc, ao, rc);
+    return AO_INPROGRESS;
+
+ out:
+    return AO_CREATE_FAIL(rc);
+}
+
 int libxl__domain_pvcontrol_available(libxl__gc *gc, uint32_t domid)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 1fba10e39e71..7486b512fd54 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -4109,6 +4109,7 @@ _hidden void libxl__remus_teardown(libxl__egc *egc,
                                    int rc);
 _hidden void libxl__remus_restore_setup(libxl__egc *egc,
                                         libxl__domain_create_state *dcs);
+_hidden int libxl__domain_unpause(libxl__gc *, libxl_domid domid);
 
 
 /*
diff --git a/tools/xl/xl_migrate.c b/tools/xl/xl_migrate.c
index 1f0e87df50b5..22f0429b8488 100644
--- a/tools/xl/xl_migrate.c
+++ b/tools/xl/xl_migrate.c
@@ -394,7 +394,7 @@ static void migrate_receive(int debug, int daemonize, int monitor,
             /* The guest is running after failover in COLO mode */
             exit(rc ? -ERROR_FAIL: 0);
 
-        rc = libxl_domain_unpause(ctx, domid);
+        rc = libxl_domain_unpause(ctx, domid, NULL);
         if (rc)
             fprintf(stderr, "migration target (%s): "
                     "Failed to unpause domain %s (id: %u):%d\n",
@@ -429,7 +429,7 @@ static void migrate_receive(int debug, int daemonize, int monitor,
     }
 
     if (!pause_after_migration) {
-        rc = libxl_domain_unpause(ctx, domid);
+        rc = libxl_domain_unpause(ctx, domid, NULL);
         if (rc) goto perhaps_destroy_notify_rc;
     }
 
diff --git a/tools/xl/xl_saverestore.c b/tools/xl/xl_saverestore.c
index 9afeadeeb29f..5c70e2e8747d 100644
--- a/tools/xl/xl_saverestore.c
+++ b/tools/xl/xl_saverestore.c
@@ -150,7 +150,7 @@ static int save_domain(uint32_t domid, const char *filename, int checkpoint,
     }
     else if (leavepaused || checkpoint) {
         if (leavepaused)
-            libxl_domain_pause(ctx, domid);
+            libxl_domain_pause(ctx, domid, NULL);
         libxl_domain_resume(ctx, domid, 1, 0);
     }
     else
diff --git a/tools/xl/xl_vmcontrol.c b/tools/xl/xl_vmcontrol.c
index a1d633795c9f..419bf780a4c2 100644
--- a/tools/xl/xl_vmcontrol.c
+++ b/tools/xl/xl_vmcontrol.c
@@ -34,12 +34,12 @@ static int fd_lock = -1;
 
 static void pause_domain(uint32_t domid)
 {
-    libxl_domain_pause(ctx, domid);
+    libxl_domain_pause(ctx, domid, NULL);
 }
 
 static void unpause_domain(uint32_t domid)
 {
-    libxl_domain_unpause(ctx, domid);
+    libxl_domain_unpause(ctx, domid, NULL);
 }
 
 static void destroy_domain(uint32_t domid, int force)
@@ -972,7 +972,7 @@ int create_domain(struct domain_create *dom_info)
     }
 
     if (!paused)
-        libxl_domain_unpause(ctx, domid);
+        libxl_domain_unpause(ctx, domid, NULL);
 
     ret = domid; /* caller gets success in parent */
     if (!daemonize && !monitor)
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 02/35] libxl: Make libxl_send_trigger async
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 01/35] libxl: Make libxl_domain_unpause async Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 03/35] libxl: Make libxl_set_vcpuonline async Anthony PERARD
                   ` (33 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

.. because it makes QMP calls which are going to be async.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl.h        | 13 ++++++++++++-
 tools/libxl/libxl_domain.c | 12 ++++++++----
 tools/xl/xl_misc.c         |  4 ++--
 tools/xl/xl_vmcontrol.c    |  4 ++--
 4 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 10dfde3fd897..430123274964 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1219,6 +1219,7 @@ void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, const libxl_mac *src);
  * asynchronously. Those functions are:
  *   libxl_domain_pause()
  *   libxl_domain_unpause()
+ *   libxl_send_trigger()
  */
 #define LIBXL_HAVE_FN_USING_QMP_ASYNC 1
 
@@ -2380,7 +2381,17 @@ int libxl_vcpu_sched_params_set_all(libxl_ctx *ctx, uint32_t domid,
                                     const libxl_vcpu_sched_params *params);
 
 int libxl_send_trigger(libxl_ctx *ctx, uint32_t domid,
-                       libxl_trigger trigger, uint32_t vcpuid);
+                       libxl_trigger trigger, uint32_t vcpuid,
+                       const libxl_asyncop_how *ao_how)
+                       LIBXL_EXTERNAL_CALLERS_ONLY;
+#if defined(LIBXL_API_VERSION) && LIBXL_API_VERSION < 0x041300
+static inline int libxl_send_trigger_0x041200(
+    libxl_ctx *ctx, uint32_t domid, libxl_trigger trigger, uint32_t vcpuid)
+{
+    return libxl_send_trigger_0x041200(ctx, domid, trigger, vcpuid, NULL);
+}
+#define libxl_send_trigger libxl_send_trigger_0x041200
+#endif
 int libxl_send_sysrq(libxl_ctx *ctx, uint32_t domid, char sysrq);
 int libxl_send_debug_keys(libxl_ctx *ctx, char *keys);
 int libxl_set_parameters(libxl_ctx *ctx, char *params);
diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c
index 1c313005db51..86cddc05a944 100644
--- a/tools/libxl/libxl_domain.c
+++ b/tools/libxl/libxl_domain.c
@@ -1470,10 +1470,11 @@ static int libxl__domain_s3_resume(libxl__gc *gc, int domid)
 }
 
 int libxl_send_trigger(libxl_ctx *ctx, uint32_t domid,
-                       libxl_trigger trigger, uint32_t vcpuid)
+                       libxl_trigger trigger, uint32_t vcpuid,
+                       const libxl_asyncop_how *ao_how)
 {
+    AO_CREATE(ctx, domid, ao_how);
     int rc;
-    GC_INIT(ctx);
 
     switch (trigger) {
     case LIBXL_TRIGGER_POWER:
@@ -1509,10 +1510,13 @@ int libxl_send_trigger(libxl_ctx *ctx, uint32_t domid,
         LOGED(ERROR, domid, "Send trigger '%s' failed",
               libxl_trigger_to_string(trigger));
         rc = ERROR_FAIL;
+        goto out;
     }
 
-    GC_FREE;
-    return rc;
+    libxl__ao_complete(egc, ao, rc);
+    return AO_INPROGRESS;
+out:
+    return AO_CREATE_FAIL(rc);
 }
 
 uint32_t libxl_vm_get_start_time(libxl_ctx *ctx, uint32_t domid)
diff --git a/tools/xl/xl_misc.c b/tools/xl/xl_misc.c
index dcf940a6d4a6..50c8436337c9 100644
--- a/tools/xl/xl_misc.c
+++ b/tools/xl/xl_misc.c
@@ -36,7 +36,7 @@ static void button_press(uint32_t domid, const char *b)
         exit(EXIT_FAILURE);
     }
 
-    libxl_send_trigger(ctx, domid, trigger, 0);
+    libxl_send_trigger(ctx, domid, trigger, 0, NULL);
 }
 
 int main_button_press(int argc, char **argv)
@@ -106,7 +106,7 @@ int main_trigger(int argc, char **argv)
         }
     }
 
-    libxl_send_trigger(ctx, domid, trigger, vcpuid);
+    libxl_send_trigger(ctx, domid, trigger, vcpuid, NULL);
 
     return EXIT_SUCCESS;
 }
diff --git a/tools/xl/xl_vmcontrol.c b/tools/xl/xl_vmcontrol.c
index 419bf780a4c2..3fc6f565748c 100644
--- a/tools/xl/xl_vmcontrol.c
+++ b/tools/xl/xl_vmcontrol.c
@@ -108,7 +108,7 @@ static void reboot_domain(uint32_t domid, libxl_evgen_domain_death **deathw,
         if (fallback_trigger) {
             fprintf(stderr, "PV control interface not available:"
                     " sending ACPI reset button event.\n");
-            rc = libxl_send_trigger(ctx, domid, LIBXL_TRIGGER_RESET, 0);
+            rc = libxl_send_trigger(ctx, domid, LIBXL_TRIGGER_RESET, 0, NULL);
         } else {
             fprintf(stderr, "PV control interface not available:"
                     " external graceful reboot not possible.\n");
@@ -141,7 +141,7 @@ static void shutdown_domain(uint32_t domid,
         if (fallback_trigger) {
             fprintf(stderr, "PV control interface not available:"
                     " sending ACPI power button event.\n");
-            rc = libxl_send_trigger(ctx, domid, LIBXL_TRIGGER_POWER, 0);
+            rc = libxl_send_trigger(ctx, domid, LIBXL_TRIGGER_POWER, 0, NULL);
         } else {
             fprintf(stderr, "PV control interface not available:"
                     " external graceful shutdown not possible.\n");
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 03/35] libxl: Make libxl_set_vcpuonline async
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 01/35] libxl: Make libxl_domain_unpause async Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 02/35] libxl: Make libxl_send_trigger async Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 04/35] libxl: Make libxl_retrieve_domain_configuration async Anthony PERARD
                   ` (32 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

.. because it makes QMP calls which are going to be async.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl.h        | 15 ++++++++++++++-
 tools/libxl/libxl_domain.c | 12 ++++++++----
 tools/xl/xl_cpupool.c      |  2 +-
 tools/xl/xl_vcpu.c         |  2 +-
 4 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 430123274964..fd69e92166b8 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1220,6 +1220,7 @@ void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, const libxl_mac *src);
  *   libxl_domain_pause()
  *   libxl_domain_unpause()
  *   libxl_send_trigger()
+ *   libxl_set_vcpuonline()
  */
 #define LIBXL_HAVE_FN_USING_QMP_ASYNC 1
 
@@ -2318,7 +2319,19 @@ int libxl_domain_set_nodeaffinity(libxl_ctx *ctx, uint32_t domid,
                                   libxl_bitmap *nodemap);
 int libxl_domain_get_nodeaffinity(libxl_ctx *ctx, uint32_t domid,
                                   libxl_bitmap *nodemap);
-int libxl_set_vcpuonline(libxl_ctx *ctx, uint32_t domid, libxl_bitmap *cpumap);
+int libxl_set_vcpuonline(libxl_ctx *ctx, uint32_t domid,
+                         libxl_bitmap *cpumap,
+                         const libxl_asyncop_how *ao_how)
+                         LIBXL_EXTERNAL_CALLERS_ONLY;
+#if defined(LIBXL_API_VERSION) && LIBXL_API_VERSION < 0x041300
+static inline int libxl_set_vcpuonline_0x041200(libxl_ctx *ctx,
+                                                uint32_t domid,
+                                                libxl_bitmap *cpumap)
+{
+    return libxl_set_vcpuonline(ctx, domid, cpumap, NULL);
+}
+#define libxl_set_vcpuonline libxl_set_vcpuonline_0x041200
+#endif
 
 /* A return value less than 0 should be interpreted as a libxl_error, while a
  * return value greater than or equal to 0 should be interpreted as a
diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c
index 86cddc05a944..60c3f7a34b4c 100644
--- a/tools/libxl/libxl_domain.c
+++ b/tools/libxl/libxl_domain.c
@@ -1386,9 +1386,11 @@ static int libxl__set_vcpuonline_qmp(libxl__gc *gc, uint32_t domid,
     return rc;
 }
 
-int libxl_set_vcpuonline(libxl_ctx *ctx, uint32_t domid, libxl_bitmap *cpumap)
+int libxl_set_vcpuonline(libxl_ctx *ctx, uint32_t domid,
+                         libxl_bitmap *cpumap,
+                         const libxl_asyncop_how *ao_how)
 {
-    GC_INIT(ctx);
+    AO_CREATE(ctx, domid, ao_how);
     int rc, maxcpus;
     libxl_dominfo info;
 
@@ -1439,8 +1441,10 @@ int libxl_set_vcpuonline(libxl_ctx *ctx, uint32_t domid, libxl_bitmap *cpumap)
 
 out:
     libxl_dominfo_dispose(&info);
-    GC_FREE;
-    return rc;
+    if (rc)
+        return AO_CREATE_FAIL(rc);
+    libxl__ao_complete(egc, ao, rc);
+    return AO_INPROGRESS;
 }
 
 static int libxl__domain_s3_resume(libxl__gc *gc, int domid)
diff --git a/tools/xl/xl_cpupool.c b/tools/xl/xl_cpupool.c
index 273811b66366..cffe87e0c7cc 100644
--- a/tools/xl/xl_cpupool.c
+++ b/tools/xl/xl_cpupool.c
@@ -546,7 +546,7 @@ int main_cpupoolnumasplit(int argc, char **argv)
         fprintf(stderr, "error on getting info for Domain-0\n");
         goto out;
     }
-    if (info.vcpu_online > n && libxl_set_vcpuonline(ctx, 0, &cpumap)) {
+    if (info.vcpu_online > n && libxl_set_vcpuonline(ctx, 0, &cpumap, NULL)) {
         fprintf(stderr, "error on removing vcpus for Domain-0\n");
         goto out;
     }
diff --git a/tools/xl/xl_vcpu.c b/tools/xl/xl_vcpu.c
index 329512eaaf79..9ff5354f749b 100644
--- a/tools/xl/xl_vcpu.c
+++ b/tools/xl/xl_vcpu.c
@@ -369,7 +369,7 @@ static int vcpuset(uint32_t domid, const char* nr_vcpus, int check_host)
     for (i = 0; i < max_vcpus; i++)
         libxl_bitmap_set(&cpumap, i);
 
-    rc = libxl_set_vcpuonline(ctx, domid, &cpumap);
+    rc = libxl_set_vcpuonline(ctx, domid, &cpumap, NULL);
     if (rc == ERROR_DOMAIN_NOTFOUND)
         fprintf(stderr, "Domain %u does not exist.\n", domid);
     else if (rc)
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 04/35] libxl: Make libxl_retrieve_domain_configuration async
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (2 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 03/35] libxl: Make libxl_set_vcpuonline async Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 05/35] libxl: Make libxl_qemu_monitor_command async Anthony PERARD
                   ` (31 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

.. because it makes QMP calls which are going to be async.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl.h        | 13 ++++++++++++-
 tools/libxl/libxl_domain.c | 14 +++++++-------
 tools/xl/xl_info.c         |  3 ++-
 tools/xl/xl_saverestore.c  |  3 ++-
 tools/xl/xl_vmcontrol.c    |  3 ++-
 5 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index fd69e92166b8..fd1e1349bf6a 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1221,6 +1221,7 @@ void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, const libxl_mac *src);
  *   libxl_domain_unpause()
  *   libxl_send_trigger()
  *   libxl_set_vcpuonline()
+ *   libxl_retrieve_domain_configuration()
  */
 #define LIBXL_HAVE_FN_USING_QMP_ASYNC 1
 
@@ -1564,8 +1565,18 @@ void libxl_domain_config_dispose(libxl_domain_config *d_config);
  * works with DomU.
  */
 int libxl_retrieve_domain_configuration(libxl_ctx *ctx, uint32_t domid,
-                                        libxl_domain_config *d_config)
+                                        libxl_domain_config *d_config,
+                                        const libxl_asyncop_how *ao_how)
                                         LIBXL_EXTERNAL_CALLERS_ONLY;
+#if defined(LIBXL_API_VERSION) && LIBXL_API_VERSION < 0x041300
+static inline int libxl_retrieve_domain_configuration_0x041200(
+    libxl_ctx *ctx, uint32_t domid, libxl_domain_config *d_config)
+{
+    return libxl_retrieve_domain_configuration(ctx, domid, d_config, NULL);
+}
+#define libxl_retrieve_domain_configuration \
+    libxl_retrieve_domain_configuration_0x041200
+#endif
 
 int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd,
                          int flags, /* LIBXL_SUSPEND_* */
diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c
index 60c3f7a34b4c..f2d5c86427ad 100644
--- a/tools/libxl/libxl_domain.c
+++ b/tools/libxl/libxl_domain.c
@@ -1594,14 +1594,13 @@ static int libxl__update_avail_vcpus_xenstore(libxl__gc *gc, uint32_t domid,
 }
 
 int libxl_retrieve_domain_configuration(libxl_ctx *ctx, uint32_t domid,
-                                        libxl_domain_config *d_config)
+                                        libxl_domain_config *d_config,
+                                        const libxl_asyncop_how *ao_how)
 {
-    GC_INIT(ctx);
+    AO_CREATE(ctx, domid, ao_how);
     int rc;
     libxl__domain_userdata_lock *lock = NULL;
 
-    CTX_LOCK;
-
     lock = libxl__lock_domain_userdata(gc, domid);
     if (!lock) {
         rc = ERROR_LOCK_FAIL;
@@ -1808,9 +1807,10 @@ int libxl_retrieve_domain_configuration(libxl_ctx *ctx, uint32_t domid,
 
 out:
     if (lock) libxl__unlock_domain_userdata(lock);
-    CTX_UNLOCK;
-    GC_FREE;
-    return rc;
+    if (rc)
+        return AO_CREATE_FAIL(rc);
+    libxl__ao_complete(egc, ao, rc);
+    return AO_INPROGRESS;
 }
 
 /*
diff --git a/tools/xl/xl_info.c b/tools/xl/xl_info.c
index bfbca93997dd..ca417df8e8a5 100644
--- a/tools/xl/xl_info.c
+++ b/tools/xl/xl_info.c
@@ -464,7 +464,8 @@ static void list_domains_details(const libxl_dominfo *info, int nb_domain)
 
     for (i = 0; i < nb_domain; i++) {
         libxl_domain_config_init(&d_config);
-        rc = libxl_retrieve_domain_configuration(ctx, info[i].domid, &d_config);
+        rc = libxl_retrieve_domain_configuration(ctx, info[i].domid,
+                                                 &d_config, NULL);
         if (rc)
             continue;
         if (default_output_format == OUTPUT_FORMAT_JSON)
diff --git a/tools/xl/xl_saverestore.c b/tools/xl/xl_saverestore.c
index 5c70e2e8747d..9be033fe65e4 100644
--- a/tools/xl/xl_saverestore.c
+++ b/tools/xl/xl_saverestore.c
@@ -56,7 +56,8 @@ void save_domain_core_begin(uint32_t domid,
                           &d_config);
         free(config_v);
     } else {
-        rc = libxl_retrieve_domain_configuration(ctx, domid, &d_config);
+        rc = libxl_retrieve_domain_configuration(ctx, domid, &d_config,
+                                                 NULL);
         if (rc) {
             fprintf(stderr, "unable to retrieve domain configuration\n");
             exit(EXIT_FAILURE);
diff --git a/tools/xl/xl_vmcontrol.c b/tools/xl/xl_vmcontrol.c
index 3fc6f565748c..eb6779a56197 100644
--- a/tools/xl/xl_vmcontrol.c
+++ b/tools/xl/xl_vmcontrol.c
@@ -377,7 +377,8 @@ static void reload_domain_config(uint32_t domid,
     }
 
     libxl_domain_config_init(&d_config_new);
-    rc = libxl_retrieve_domain_configuration(ctx, domid, &d_config_new);
+    rc = libxl_retrieve_domain_configuration(ctx, domid, &d_config_new,
+                                             NULL);
     if (rc) {
         LOG("failed to retrieve guest configuration (rc=%d). "
             "reusing old configuration", rc);
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 05/35] libxl: Make libxl_qemu_monitor_command async
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (3 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 04/35] libxl: Make libxl_retrieve_domain_configuration async Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 06/35] libxl: Use ev_qmp for switch_qemu_xen_logdirty Anthony PERARD
                   ` (30 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

.. because it makes QMP calls which are going to be async.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl.h     | 14 +++++++++++++-
 tools/libxl/libxl_qmp.c |  9 +++++----
 tools/xl/xl_misc.c      |  2 +-
 3 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index fd1e1349bf6a..ba48e7e900d3 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1222,6 +1222,7 @@ void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, const libxl_mac *src);
  *   libxl_send_trigger()
  *   libxl_set_vcpuonline()
  *   libxl_retrieve_domain_configuration()
+ *   libxl_qemu_monitor_command()
  */
 #define LIBXL_HAVE_FN_USING_QMP_ASYNC 1
 
@@ -2571,7 +2572,18 @@ int libxl_fd_set_nonblock(libxl_ctx *ctx, int fd, int nonblock);
  * via output.
  */
 int libxl_qemu_monitor_command(libxl_ctx *ctx, uint32_t domid,
-                               const char *command_line, char **output);
+                               const char *command_line, char **output,
+                               const libxl_asyncop_how *ao_how)
+                               LIBXL_EXTERNAL_CALLERS_ONLY;
+#if defined(LIBXL_API_VERSION) && LIBXL_API_VERSION < 0x041300
+static inline int libxl_qemu_monitor_command_0x041200(libxl_ctx *ctx,
+    uint32_t domid, const char *command_line, char **output)
+{
+    return libxl_qemu_monitor_command(ctx, domid, command_line, output,
+                                      NULL);
+}
+#define libxl_qemu_monitor_command libxl_qemu_monitor_command_0x041200
+#endif
 
 #include <libxl_event.h>
 
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index 20d9eed8ddc8..505e0e5469a9 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -1291,15 +1291,16 @@ int libxl__qmp_hmp(libxl__gc *gc, int domid, const char *command_line,
 }
 
 int libxl_qemu_monitor_command(libxl_ctx *ctx, uint32_t domid,
-                               const char *command_line, char **output)
+                               const char *command_line, char **output,
+                               const libxl_asyncop_how *ao_how)
 {
-    GC_INIT(ctx);
+    AO_CREATE(ctx, domid, ao_how);
     int rc;
 
     rc = libxl__qmp_hmp(gc, domid, command_line, output);
 
-    GC_FREE;
-    return rc;
+    libxl__ao_complete(egc, ao, rc);
+    return AO_INPROGRESS;
 }
 
 int libxl__qmp_initializations(libxl__gc *gc, uint32_t domid,
diff --git a/tools/xl/xl_misc.c b/tools/xl/xl_misc.c
index 50c8436337c9..20ed605f4f44 100644
--- a/tools/xl/xl_misc.c
+++ b/tools/xl/xl_misc.c
@@ -228,7 +228,7 @@ int main_qemu_monitor_command(int argc, char **argv)
         return EXIT_FAILURE;
     }
 
-    ret = libxl_qemu_monitor_command(ctx, domid, cmd, &output);
+    ret = libxl_qemu_monitor_command(ctx, domid, cmd, &output, NULL);
     if (!ret && output) {
         printf("%s\n", output);
         free(output);
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 06/35] libxl: Use ev_qmp for switch_qemu_xen_logdirty
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (4 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 05/35] libxl: Make libxl_qemu_monitor_command async Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 19:14   ` Ian Jackson
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 07/35] libxl: Move "qmp_initializations" to libxl_dm Anthony PERARD
                   ` (29 subsequent siblings)
  35 siblings, 1 reply; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 tools/libxl/libxl_dom_save.c | 41 ++++++++++++++++++++++++++++++++----
 tools/libxl/libxl_internal.h |  3 +--
 tools/libxl/libxl_qmp.c      | 10 ---------
 3 files changed, 38 insertions(+), 16 deletions(-)

diff --git a/tools/libxl/libxl_dom_save.c b/tools/libxl/libxl_dom_save.c
index 13d08d6dae14..e70aa1585976 100644
--- a/tools/libxl/libxl_dom_save.c
+++ b/tools/libxl/libxl_dom_save.c
@@ -44,6 +44,10 @@ static void switch_logdirty_xswatch(libxl__egc *egc, libxl__ev_xswatch*,
 static void domain_suspend_switch_qemu_xen_logdirty
                                (libxl__egc *egc, int domid, unsigned enable,
                                 libxl__logdirty_switch *lds);
+static void switch_qemu_xen_logdirty_done(libxl__egc *egc,
+                                          libxl__ev_qmp *qmp,
+                                          const libxl__json_object *,
+                                          int rc);
 static void switch_logdirty_timeout(libxl__egc *egc, libxl__ev_time *ev,
                                     const struct timeval *requested_abs,
                                     int rc);
@@ -55,6 +59,7 @@ void libxl__logdirty_init(libxl__logdirty_switch *lds)
     lds->cmd_path = 0;
     libxl__ev_xswatch_init(&lds->watch);
     libxl__ev_time_init(&lds->timeout);
+    libxl__ev_qmp_init(&lds->qmp);
 }
 
 void libxl__domain_common_switch_qemu_logdirty(libxl__egc *egc,
@@ -207,13 +212,40 @@ static void domain_suspend_switch_qemu_xen_logdirty
 {
     STATE_AO_GC(lds->ao);
     int rc;
+    libxl__json_object *args = NULL;
+
+    /* Convenience aliases. */
+    libxl__ev_qmp *const qmp = &lds->qmp;
+
+    rc = libxl__ev_time_register_rel(ao, &lds->timeout,
+                                     switch_logdirty_timeout, 10 * 1000);
+    if (rc) goto out;
+
+    qmp->ao = ao;
+    qmp->domid = domid;
+    qmp->payload_fd = -1;
+    qmp->callback = switch_qemu_xen_logdirty_done;
+    libxl__qmp_param_add_bool(gc, &args, "enable", enable);
+    rc = libxl__ev_qmp_send(gc, qmp, "xen-set-global-dirty-log", args);
+    if (rc) goto out;
+
+    return;
+out:
+    switch_qemu_xen_logdirty_done(egc, qmp, NULL, rc);
+}
+
+static void switch_qemu_xen_logdirty_done(libxl__egc *egc,
+                                          libxl__ev_qmp *qmp,
+                                          const libxl__json_object *r,
+                                          int rc)
+{
+    EGC_GC;
+    libxl__logdirty_switch *lds = CONTAINER_OF(qmp, *lds, qmp);
 
-    rc = libxl__qmp_set_global_dirty_log(gc, domid, enable);
     if (rc)
-        LOGD(ERROR, domid,
+        LOGD(ERROR, qmp->domid,
              "logdirty switch failed (rc=%d), abandoning suspend",rc);
-
-    lds->callback(egc, lds, rc);
+    switch_logdirty_done(egc, lds, rc);
 }
 
 static void switch_logdirty_timeout(libxl__egc *egc, libxl__ev_time *ev,
@@ -234,6 +266,7 @@ static void switch_logdirty_done(libxl__egc *egc,
 
     libxl__ev_xswatch_deregister(gc, &lds->watch);
     libxl__ev_time_deregister(gc, &lds->timeout);
+    libxl__ev_qmp_dispose(gc, &lds->qmp);
 
     lds->callback(egc, lds, rc);
 }
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 7486b512fd54..c4834ac9c6c5 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1958,8 +1958,6 @@ _hidden int libxl__qmp_system_wakeup(libxl__gc *gc, int domid);
 _hidden int libxl__qmp_resume(libxl__gc *gc, int domid);
 /* Load current QEMU state from file. */
 _hidden int libxl__qmp_restore(libxl__gc *gc, int domid, const char *filename);
-/* Set dirty bitmap logging status */
-_hidden int libxl__qmp_set_global_dirty_log(libxl__gc *gc, int domid, bool enable);
 /* Add a virtual CPU */
 _hidden int libxl__qmp_cpu_add(libxl__gc *gc, int domid, int index);
 /* Query the bitmap of CPUs */
@@ -3413,6 +3411,7 @@ typedef struct libxl__logdirty_switch {
     const char *ret_path;
     libxl__ev_xswatch watch;
     libxl__ev_time timeout;
+    libxl__ev_qmp qmp;
 } libxl__logdirty_switch;
 
 _hidden void libxl__logdirty_init(libxl__logdirty_switch *lds);
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index 505e0e5469a9..f1529925ee0e 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -1108,16 +1108,6 @@ int libxl__qmp_resume(libxl__gc *gc, int domid)
     return qmp_run_command(gc, domid, "cont", NULL, NULL, NULL);
 }
 
-int libxl__qmp_set_global_dirty_log(libxl__gc *gc, int domid, bool enable)
-{
-    libxl__json_object *args = NULL;
-
-    libxl__qmp_param_add_bool(gc, &args, "enable", enable);
-
-    return qmp_run_command(gc, domid, "xen-set-global-dirty-log", args,
-                           NULL, NULL);
-}
-
 int libxl__qmp_cpu_add(libxl__gc *gc, int domid, int idx)
 {
     libxl__json_object *args = NULL;
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 07/35] libxl: Move "qmp_initializations" to libxl_dm
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (5 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 06/35] libxl: Use ev_qmp for switch_qemu_xen_logdirty Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 08/35] libxl: Replace libxl__qmp_initializations by ev_qmp calls Anthony PERARD
                   ` (28 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

libxl__qmp_initializations is part of the device domain startup, it
queries information about the newly spawned QEMU and do some
post-startup configuration. So the function call doesn't belong to the
general domain creation, but only to the device model part of the
process, thus the call belong to libxl_dm and libxl__dm_spawn_state's
machinery.

We move the call ahead of a follow-up patch which going to "inline"
libxl__qmp_initializations.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_create.c | 10 ----------
 tools/libxl/libxl_dm.c     |  8 ++++++++
 2 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 3f31f2ebcd1f..93fbe1d74067 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -1557,21 +1557,11 @@ static void domcreate_devmodel_started(libxl__egc *egc,
     STATE_AO_GC(dmss->spawn.ao);
     int domid = dcs->guest_domid;
 
-    /* convenience aliases */
-    libxl_domain_config *const d_config = dcs->guest_config;
-
     if (ret) {
         LOGD(ERROR, domid, "device model did not start: %d", ret);
         goto error_out;
     }
 
-    if (dcs->sdss.dm.guest_domid) {
-        if (d_config->b_info.device_model_version
-            == LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN) {
-            libxl__qmp_initializations(gc, domid, d_config);
-        }
-    }
-
     dcs->device_type_idx = -1;
     domcreate_attach_devices(egc, &dcs->multidev, 0);
     return;
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index 00da59153d67..5a2e3497769d 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -2744,6 +2744,9 @@ static void device_model_spawn_outcome(libxl__egc *egc,
     STATE_AO_GC(dmss->spawn.ao);
     int ret2;
 
+    /* Convenience aliases */
+    libxl_domain_config *const d_config = dmss->guest_config;
+
     if (rc)
         LOGD(ERROR, dmss->guest_domid,
              "%s: spawn failed (rc=%d)", dmss->spawn.what, rc);
@@ -2760,6 +2763,11 @@ static void device_model_spawn_outcome(libxl__egc *egc,
         }
     }
 
+    if (d_config->b_info.device_model_version
+            == LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN) {
+        libxl__qmp_initializations(gc, dmss->guest_domid, d_config);
+    }
+
  out:
     dmss_dispose(gc, dmss);
     dmss->callback(egc, dmss, rc);
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 08/35] libxl: Replace libxl__qmp_initializations by ev_qmp calls
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (6 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 07/35] libxl: Move "qmp_initializations" to libxl_dm Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 09/35] libxl: Deprecate libxl__domain_{unpause, resume} Anthony PERARD
                   ` (27 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

Setup a timeout of 10s for all the commands. It used to be about 5s
per commands.

The order of command is changed, we call 'query-vnc' before
'change-vnc-password', but that should not matter. That makes it
easier to call 'change-vnc-password' conditionally.

Also 'change' command is replaced by 'change-vnc-password'
because 'change' is deprecated. The new command is available in all
QEMU versions that also have Xen support.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_dm.c       | 211 ++++++++++++++++++++++++++++++++++-
 tools/libxl/libxl_internal.h |   8 +-
 tools/libxl/libxl_qmp.c      | 169 ----------------------------
 3 files changed, 212 insertions(+), 176 deletions(-)

diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index 5a2e3497769d..bb5339784ea8 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -2063,11 +2063,13 @@ static int libxl__write_stub_dmargs(libxl__gc *gc,
 static void dmss_init(libxl__dm_spawn_state *dmss)
 {
     libxl__ev_qmp_init(&dmss->qmp);
+    libxl__ev_time_init(&dmss->timeout);
 }
 
 static void dmss_dispose(libxl__gc *gc, libxl__dm_spawn_state *dmss)
 {
     libxl__ev_qmp_dispose(gc, &dmss->qmp);
+    libxl__ev_time_deregister(gc, &dmss->timeout);
 }
 
 static void spawn_stubdom_pvqemu_cb(libxl__egc *egc,
@@ -2462,6 +2464,16 @@ static void device_model_qmp_cb(libxl__egc *egc, libxl__ev_qmp *ev,
 static void device_model_spawn_outcome(libxl__egc *egc,
                                        libxl__dm_spawn_state *dmss,
                                        int rc);
+static void device_model_postconfig_chardev(libxl__egc *egc,
+    libxl__ev_qmp *qmp, const libxl__json_object *response, int rc);
+static void device_model_postconfig_vnc(libxl__egc *egc,
+    libxl__ev_qmp *qmp, const libxl__json_object *response, int rc);
+static void device_model_postconfig_vnc_passwd(libxl__egc *egc,
+    libxl__ev_qmp *qmp, const libxl__json_object *response, int rc);
+static void devise_model_postconfig_timeout(libxl__egc *egc,
+    libxl__ev_time *ev, const struct timeval *requested_abs, int rc);
+static void device_model_postconfig_done(libxl__egc *egc,
+    libxl__dm_spawn_state *dmss, int rc);
 
 void libxl__spawn_local_dm(libxl__egc *egc, libxl__dm_spawn_state *dmss)
 {
@@ -2763,12 +2775,209 @@ static void device_model_spawn_outcome(libxl__egc *egc,
         }
     }
 
+    /* Check if spawn failed */
+    if (rc) goto out;
+
     if (d_config->b_info.device_model_version
             == LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN) {
-        libxl__qmp_initializations(gc, dmss->guest_domid, d_config);
+        rc = libxl__ev_time_register_rel(ao, &dmss->timeout,
+                                         devise_model_postconfig_timeout,
+                                         LIBXL_QMP_CMD_TIMEOUT * 1000);
+        if (rc) goto out;
+        dmss->qmp.ao = ao;
+        dmss->qmp.domid = dmss->guest_domid;
+        dmss->qmp.payload_fd = -1;
+        dmss->qmp.callback = device_model_postconfig_chardev;
+        rc = libxl__ev_qmp_send(gc, &dmss->qmp, "query-chardev", NULL);
+        if (rc) goto out;
+        return;
     }
 
  out:
+    device_model_postconfig_done(egc, dmss, rc); /* must be last */
+}
+
+static void device_model_postconfig_chardev(libxl__egc *egc,
+    libxl__ev_qmp *qmp, const libxl__json_object *response, int rc)
+{
+    EGC_GC;
+    libxl__dm_spawn_state *dmss = CONTAINER_OF(qmp, *dmss, qmp);
+    const libxl__json_object *item = NULL;
+    const libxl__json_object *o = NULL;
+    int i = 0;
+    const char *label;
+    const char *filename;
+    int port;
+    char *endptr;
+    const char *dompath;
+    const char serial[] = "serial";
+    const size_t seriall = sizeof(serial) - 1;
+    const char pty[] = "pty:";
+    const size_t ptyl = sizeof(pty) - 1;
+
+    if (rc) goto out;
+
+    /*
+     * query-chardev response:
+     * [{ 'label': 'str',
+     *    'filename': 'str',
+     *    'frontend-open': 'bool' }, ...]
+     */
+
+    for (i = 0; (item = libxl__json_array_get(response, i)); i++) {
+        o = libxl__json_map_get("label", item, JSON_STRING);
+        if (!o) goto protocol_error;
+        label = libxl__json_object_get_string(o);
+
+        /* Check if the "label" start with "serial". */
+        if (!label || strncmp(label, serial, seriall))
+            continue;
+        port = strtol(label + seriall, &endptr, 10);
+        if (*(label + seriall) == '\0' || *endptr != '\0') {
+            LOGD(ERROR, qmp->domid,
+                 "Invalid serial port number: %s", label);
+            rc = ERROR_QEMU_API;
+            goto out;
+        }
+
+        o = libxl__json_map_get("filename", item, JSON_STRING);
+        if (!o) goto protocol_error;
+        filename = libxl__json_object_get_string(o);
+
+        /* Check if filename start with "pty:" */
+        if (!filename || strncmp(filename, pty, ptyl))
+            continue;
+
+        dompath = libxl__xs_get_dompath(gc, qmp->domid);
+        if (!dompath) {
+            rc = ERROR_FAIL;
+            goto out;
+        }
+        rc = libxl__xs_printf(gc, XBT_NULL,
+                              GCSPRINTF("%s/serial/%d/tty", dompath, port),
+                              "%s", filename + ptyl);
+        if (rc) goto out;
+    }
+
+    qmp->callback = device_model_postconfig_vnc;
+    rc = libxl__ev_qmp_send(gc, qmp, "query-vnc", NULL);
+    if (rc) goto out;
+    return;
+
+protocol_error:
+    rc = ERROR_QEMU_API;
+    LOGD(ERROR, qmp->domid,
+         "unexpected response to QMP cmd 'query-chardev', received:\n%s",
+         JSON(response));
+out:
+    device_model_postconfig_done(egc, dmss, rc); /* must be last */
+}
+
+static void device_model_postconfig_vnc(libxl__egc *egc,
+    libxl__ev_qmp *qmp, const libxl__json_object *response, int rc)
+{
+    EGC_GC;
+    libxl__dm_spawn_state *dmss = CONTAINER_OF(qmp, *dmss, qmp);
+    const libxl_vnc_info *vnc = libxl__dm_vnc(dmss->guest_config);
+    const libxl__json_object *o;
+    libxl__json_object *args = NULL;
+
+    if (rc) goto out;
+
+    /*
+     * query-vnc response:
+     * { 'enabled': 'bool', '*host': 'str', '*service': 'str' }
+     */
+
+    o = libxl__json_map_get("enabled", response, JSON_BOOL);
+    if (!o) goto protocol_error;
+    if (libxl__json_object_get_bool(o)) {
+        const char *addr, *port;
+        const char *dompath;
+
+        o = libxl__json_map_get("host", response, JSON_STRING);
+        if (!o) goto protocol_error;
+        addr = libxl__json_object_get_string(o);
+        o = libxl__json_map_get("service", response, JSON_STRING);
+        if (!o) goto protocol_error;
+        port = libxl__json_object_get_string(o);
+
+        dompath = libxl__xs_get_dompath(gc, qmp->domid);
+        if (!dompath) {
+            rc = ERROR_FAIL;
+            goto out;
+        }
+        rc = libxl__xs_printf(gc, XBT_NULL,
+                              GCSPRINTF("%s/console/vnc-listen", dompath),
+                              "%s", addr);
+        if (rc) goto out;
+        rc = libxl__xs_printf(gc, XBT_NULL,
+                              GCSPRINTF("%s/console/vnc-port", dompath),
+                              "%s", port);
+        if (rc) goto out;
+    }
+
+    if (vnc && vnc->passwd) {
+        qmp->callback = device_model_postconfig_vnc_passwd;
+        libxl__qmp_param_add_string(gc, &args, "password", vnc->passwd);
+        rc = libxl__ev_qmp_send(gc, qmp, "change-vnc-password", args);
+        if (rc) goto out;
+        return;
+    }
+
+    rc = 0;
+    goto out;
+
+protocol_error:
+    rc = ERROR_QEMU_API;
+    LOGD(ERROR, qmp->domid,
+         "unexpected response to QMP cmd 'query-vnc', received:\n%s",
+         JSON(response));
+out:
+    device_model_postconfig_done(egc, dmss, rc); /* must be last */
+}
+
+static void device_model_postconfig_vnc_passwd(libxl__egc *egc,
+    libxl__ev_qmp *qmp, const libxl__json_object *response, int rc)
+{
+    EGC_GC;
+    libxl__dm_spawn_state *dmss = CONTAINER_OF(qmp, *dmss, qmp);
+    const libxl_vnc_info *vnc = libxl__dm_vnc(dmss->guest_config);
+    const char *dompath;
+
+    if (rc) goto out;
+
+    dompath = libxl__xs_get_dompath(gc, qmp->domid);
+    if (!dompath) {
+        rc = ERROR_FAIL;
+        goto out;
+    }
+    rc = libxl__xs_printf(gc, XBT_NULL,
+                          GCSPRINTF("%s/console/vnc-pass", dompath),
+                          "%s", vnc->passwd);
+
+out:
+    device_model_postconfig_done(egc, dmss, rc); /* must be last */
+}
+
+void devise_model_postconfig_timeout(libxl__egc *egc, libxl__ev_time *ev,
+                                     const struct timeval *requested_abs,
+                                     int rc)
+{
+    libxl__dm_spawn_state *dmss = CONTAINER_OF(ev, *dmss, timeout);
+    device_model_postconfig_done(egc, dmss, rc); /* must be last */
+}
+
+
+static void device_model_postconfig_done(libxl__egc *egc,
+                                         libxl__dm_spawn_state *dmss,
+                                         int rc)
+{
+    EGC_GC;
+
+    if (rc)
+        LOGD(ERROR, dmss->guest_domid,
+             "Post DM startup configs failed, rc=%d", rc);
     dmss_dispose(gc, dmss);
     dmss->callback(egc, dmss, rc);
 }
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index c4834ac9c6c5..f5f234be7e3c 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -100,6 +100,7 @@
 #define LIBXL_DEVICE_MODEL_START_TIMEOUT 60
 #define LIBXL_DEVICE_MODEL_SAVE_FILE XEN_LIB_DIR "/qemu-save" /* .$domid */
 #define LIBXL_DEVICE_MODEL_RESTORE_FILE XEN_LIB_DIR "/qemu-resume" /* .$domid */
+#define LIBXL_QMP_CMD_TIMEOUT 10
 #define LIBXL_STUBDOM_START_TIMEOUT 30
 #define LIBXL_QEMU_BODGE_TIMEOUT 2
 #define LIBXL_XENCONSOLE_LIMIT 1048576
@@ -1947,8 +1948,6 @@ _hidden libxl__qmp_handler *libxl__qmp_initialize(libxl__gc *gc,
 _hidden int libxl__qmp_run_command_flexarray(libxl__gc *gc, int domid,
                                              const char *cmd,
                                              flexarray_t *array);
-/* ask to QEMU the serial port information and store it in xenstore. */
-_hidden int libxl__qmp_query_serial(libxl__qmp_handler *qmp);
 _hidden int libxl__qmp_pci_add(libxl__gc *gc, int d, libxl_device_pci *pcidev);
 _hidden int libxl__qmp_pci_del(libxl__gc *gc, int domid,
                                libxl_device_pci *pcidev);
@@ -1994,10 +1993,6 @@ _hidden void libxl__qmp_close(libxl__qmp_handler *qmp);
  * nothing happen */
 _hidden void libxl__qmp_cleanup(libxl__gc *gc, uint32_t domid);
 
-/* this helper calls qmp_initialize, query_serial and qmp_close */
-_hidden int libxl__qmp_initializations(libxl__gc *gc, uint32_t domid,
-                                       const libxl_domain_config *guest_config);
-
 /* `data' should contain a byte to send.
  * When dealing with a non-blocking fd, it returns
  *   ERROR_NOT_READY on EWOULDBLOCK
@@ -3954,6 +3949,7 @@ struct libxl__dm_spawn_state {
     /* mixed - spawn.ao must be initialised by user; rest is private: */
     libxl__spawn_state spawn;
     libxl__ev_qmp qmp;
+    libxl__ev_time timeout;
     /* filled in by user, must remain valid: */
     uint32_t guest_domid; /* domain being served */
     libxl_domain_config *guest_config;
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index f1529925ee0e..0d6aedcc7d3c 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -143,121 +143,6 @@ static const int QMP_SOCKET_CONNECT_TIMEOUT = 5;
  * QMP callbacks functions
  */
 
-static int store_serial_port_info(libxl__qmp_handler *qmp,
-                                  const char *chardev,
-                                  int port)
-{
-    GC_INIT(qmp->ctx);
-    char *path = NULL;
-    int ret = 0;
-
-    if (!(chardev && strncmp("pty:", chardev, 4) == 0)) {
-        return 0;
-    }
-
-    path = libxl__xs_get_dompath(gc, qmp->domid);
-    path = GCSPRINTF("%s/serial/%d/tty", path, port);
-
-    ret = libxl__xs_printf(gc, XBT_NULL, path, "%s", chardev + 4);
-
-    GC_FREE;
-    return ret;
-}
-
-static int register_serials_chardev_callback(libxl__qmp_handler *qmp,
-                                             const libxl__json_object *o,
-                                             void *unused)
-{
-    const libxl__json_object *obj = NULL;
-    const libxl__json_object *label = NULL;
-    const char *s = NULL;
-    int i = 0;
-    const char *chardev = NULL;
-    int ret = 0;
-
-    for (i = 0; (obj = libxl__json_array_get(o, i)); i++) {
-        if (!libxl__json_object_is_map(obj))
-            continue;
-        label = libxl__json_map_get("label", obj, JSON_STRING);
-        s = libxl__json_object_get_string(label);
-
-        if (s && strncmp("serial", s, strlen("serial")) == 0) {
-            const libxl__json_object *filename = NULL;
-            char *endptr = NULL;
-            int port_number;
-
-            filename = libxl__json_map_get("filename", obj, JSON_STRING);
-            chardev = libxl__json_object_get_string(filename);
-
-            s += strlen("serial");
-            port_number = strtol(s, &endptr, 10);
-            if (*s == 0 || *endptr != 0) {
-                LIBXL__LOGD(qmp->ctx, LIBXL__LOG_ERROR, qmp->domid,
-                            "Invalid serial port number: %s", s);
-                return -1;
-            }
-            ret = store_serial_port_info(qmp, chardev, port_number);
-            if (ret) {
-                LIBXL__LOGD_ERRNO(qmp->ctx, LIBXL__LOG_ERROR, qmp->domid,
-                                  "Failed to store serial port information"
-                                  " in xenstore");
-                return ret;
-            }
-        }
-    };
-
-    return ret;
-}
-
-static int qmp_write_domain_console_item(libxl__gc *gc, int domid,
-                                         const char *item, const char *value)
-{
-    char *path;
-
-    path = libxl__xs_get_dompath(gc, domid);
-    path = GCSPRINTF("%s/console/%s", path, item);
-
-    return libxl__xs_printf(gc, XBT_NULL, path, "%s", value);
-}
-
-static int qmp_register_vnc_callback(libxl__qmp_handler *qmp,
-                                     const libxl__json_object *o,
-                                     void *unused)
-{
-    GC_INIT(qmp->ctx);
-    const libxl__json_object *obj;
-    const char *addr, *port;
-    int rc = -1;
-
-    if (!libxl__json_object_is_map(o)) {
-        goto out;
-    }
-
-    obj = libxl__json_map_get("enabled", o, JSON_BOOL);
-    if (!obj || !libxl__json_object_get_bool(obj)) {
-        rc = 0;
-        goto out;
-    }
-
-    obj = libxl__json_map_get("host", o, JSON_STRING);
-    addr = libxl__json_object_get_string(obj);
-    obj = libxl__json_map_get("service", o, JSON_STRING);
-    port = libxl__json_object_get_string(obj);
-
-    if (!addr || !port) {
-        LOGD(ERROR, qmp->domid, "Failed to retrieve VNC connect information.");
-        goto out;
-    }
-
-    rc = qmp_write_domain_console_item(gc, qmp->domid, "vnc-listen", addr);
-    if (!rc)
-        rc = qmp_write_domain_console_item(gc, qmp->domid, "vnc-port", port);
-
-out:
-    GC_FREE;
-    return rc;
-}
-
 static int qmp_capabilities_callback(libxl__qmp_handler *qmp,
                                      const libxl__json_object *o, void *unused)
 {
@@ -851,20 +736,6 @@ void libxl__qmp_cleanup(libxl__gc *gc, uint32_t domid)
     }
 }
 
-int libxl__qmp_query_serial(libxl__qmp_handler *qmp)
-{
-    return qmp_synchronous_send(qmp, "query-chardev", NULL,
-                                register_serials_chardev_callback,
-                                NULL, qmp->timeout);
-}
-
-static int qmp_query_vnc(libxl__qmp_handler *qmp)
-{
-    return qmp_synchronous_send(qmp, "query-vnc", NULL,
-                                qmp_register_vnc_callback,
-                                NULL, qmp->timeout);
-}
-
 static int pci_add_callback(libxl__qmp_handler *qmp,
                             const libxl__json_object *response, void *opaque)
 {
@@ -1085,24 +956,6 @@ int libxl__qmp_restore(libxl__gc *gc, int domid, const char *state_file)
                            NULL, NULL);
 }
 
-static int qmp_change(libxl__gc *gc, libxl__qmp_handler *qmp,
-                      char *device, char *target, char *arg)
-{
-    libxl__json_object *args = NULL;
-    int rc = 0;
-
-    libxl__qmp_param_add_string(gc, &args, "device", device);
-    libxl__qmp_param_add_string(gc, &args, "target", target);
-    if (arg) {
-        libxl__qmp_param_add_string(gc, &args, "arg", arg);
-    }
-
-    rc = qmp_synchronous_send(qmp, "change", args,
-                              NULL, NULL, qmp->timeout);
-
-    return rc;
-}
-
 int libxl__qmp_resume(libxl__gc *gc, int domid)
 {
     return qmp_run_command(gc, domid, "cont", NULL, NULL, NULL);
@@ -1293,28 +1146,6 @@ int libxl_qemu_monitor_command(libxl_ctx *ctx, uint32_t domid,
     return AO_INPROGRESS;
 }
 
-int libxl__qmp_initializations(libxl__gc *gc, uint32_t domid,
-                               const libxl_domain_config *guest_config)
-{
-    const libxl_vnc_info *vnc = libxl__dm_vnc(guest_config);
-    libxl__qmp_handler *qmp = NULL;
-    int ret = 0;
-
-    qmp = libxl__qmp_initialize(gc, domid);
-    if (!qmp)
-        return -1;
-    ret = libxl__qmp_query_serial(qmp);
-    if (!ret && vnc && vnc->passwd) {
-        ret = qmp_change(gc, qmp, "vnc", "password", vnc->passwd);
-        qmp_write_domain_console_item(gc, domid, "vnc-pass", vnc->passwd);
-    }
-    if (!ret) {
-        ret = qmp_query_vnc(qmp);
-    }
-    libxl__qmp_close(qmp);
-    return ret;
-}
-
 
 /*
  * Functions using libxl__ev_qmp
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 09/35] libxl: Deprecate libxl__domain_{unpause, resume}
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (7 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 08/35] libxl: Replace libxl__qmp_initializations by ev_qmp calls Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 10/35] libxl: Re-introduce libxl__domain_resume Anthony PERARD
                   ` (26 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

These two functions are used from many places in libxl and need to
change to be able to accomodate libxl__ev_qmp calls and thus needs to
be asynchronous.

(There is also libxl__domain_resume_device_model in the mix.)

A later patch will introduce a new libxl__domain_resume and
libxl__domain_unpause which will make use of libxl__ev_qmp.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_colo_restore.c |  4 ++--
 tools/libxl/libxl_colo_save.c    |  4 ++--
 tools/libxl/libxl_dm.c           |  2 +-
 tools/libxl/libxl_dom_suspend.c  |  6 +++---
 tools/libxl/libxl_domain.c       |  8 ++++----
 tools/libxl/libxl_internal.h     | 12 ++++++++----
 tools/libxl/libxl_remus.c        |  2 +-
 7 files changed, 21 insertions(+), 17 deletions(-)

diff --git a/tools/libxl/libxl_colo_restore.c b/tools/libxl/libxl_colo_restore.c
index aaa70552b8c4..aa365670fb14 100644
--- a/tools/libxl/libxl_colo_restore.c
+++ b/tools/libxl/libxl_colo_restore.c
@@ -124,7 +124,7 @@ static void colo_resume_vm(libxl__egc *egc,
                 return;
             }
         }
-        rc = libxl__domain_resume(gc, crs->domid, 0);
+        rc = libxl__domain_resume_deprecated(gc, crs->domid, 0);
         if (rc)
             LOGD(ERROR, crs->domid, "cannot resume secondary vm");
 
@@ -853,7 +853,7 @@ static void colo_unpause_svm(libxl__egc *egc,
     EGC_GC;
 
     /* We have enabled secondary vm's logdirty, so we can unpause it now */
-    rc = libxl__domain_unpause(gc, domid);
+    rc = libxl__domain_unpause_deprecated(gc, domid);
     if (rc) {
         LOGD(ERROR, domid, "cannot unpause secondary vm");
         goto out;
diff --git a/tools/libxl/libxl_colo_save.c b/tools/libxl/libxl_colo_save.c
index 1d261a1639f7..b47f038f6e6e 100644
--- a/tools/libxl/libxl_colo_save.c
+++ b/tools/libxl/libxl_colo_save.c
@@ -470,7 +470,7 @@ static void colo_preresume_cb(libxl__egc *egc,
     }
 
     /* Resumes the domain and the device model */
-    if (libxl__domain_resume(gc, dss->domid, /* Fast Suspend */1)) {
+    if (libxl__domain_resume_deprecated(gc, dss->domid, /* Fast Suspend */1)) {
         LOGD(ERROR, dss->domid, "cannot resume primary vm");
         goto out;
     }
@@ -480,7 +480,7 @@ static void colo_preresume_cb(libxl__egc *egc,
      * no disk migration.
      */
     if (css->paused) {
-        rc = libxl__domain_unpause(gc, dss->domid);
+        rc = libxl__domain_unpause_deprecated(gc, dss->domid);
         if (rc) {
             LOGD(ERROR, dss->domid, "cannot unpause primary vm");
             goto out;
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index bb5339784ea8..246c570121d3 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -2404,7 +2404,7 @@ static void stubdom_pvqemu_cb(libxl__egc *egc,
         goto out;
     }
 
-    rc = libxl__domain_unpause(gc, dm_domid);
+    rc = libxl__domain_unpause_deprecated(gc, dm_domid);
     if (rc) goto out;
 
     sdss->xswait.ao = ao;
diff --git a/tools/libxl/libxl_dom_suspend.c b/tools/libxl/libxl_dom_suspend.c
index d1af3a657303..2460021e5a59 100644
--- a/tools/libxl/libxl_dom_suspend.c
+++ b/tools/libxl/libxl_dom_suspend.c
@@ -421,7 +421,7 @@ static void domain_suspend_callback_common_done(libxl__egc *egc,
 
 /*======================= Domain resume ========================*/
 
-int libxl__domain_resume_device_model(libxl__gc *gc, uint32_t domid)
+int libxl__domain_resume_device_model_deprecated(libxl__gc *gc, uint32_t domid)
 {
     const char *path, *state;
 
@@ -449,7 +449,7 @@ int libxl__domain_resume_device_model(libxl__gc *gc, uint32_t domid)
     return 0;
 }
 
-int libxl__domain_resume(libxl__gc *gc, uint32_t domid, int suspend_cancel)
+int libxl__domain_resume_deprecated(libxl__gc *gc, uint32_t domid, int suspend_cancel)
 {
     int rc = 0;
 
@@ -460,7 +460,7 @@ int libxl__domain_resume(libxl__gc *gc, uint32_t domid, int suspend_cancel)
     }
 
     if (type == LIBXL_DOMAIN_TYPE_HVM) {
-        rc = libxl__domain_resume_device_model(gc, domid);
+        rc = libxl__domain_resume_device_model_deprecated(gc, domid);
         if (rc) {
             LOGD(ERROR, domid, "failed to resume device model:%d", rc);
             goto out;
diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c
index f2d5c86427ad..80797c5ed21c 100644
--- a/tools/libxl/libxl_domain.c
+++ b/tools/libxl/libxl_domain.c
@@ -178,7 +178,7 @@ int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid, int suspend_cancel,
                         const libxl_asyncop_how *ao_how)
 {
     AO_CREATE(ctx, domid, ao_how);
-    int rc = libxl__domain_resume(gc, domid, suspend_cancel);
+    int rc = libxl__domain_resume_deprecated(gc, domid, suspend_cancel);
     libxl__ao_complete(egc, ao, rc);
     return AO_INPROGRESS;
 }
@@ -593,7 +593,7 @@ int libxl_domain_core_dump(libxl_ctx *ctx, uint32_t domid,
     return AO_INPROGRESS;
 }
 
-int libxl__domain_unpause(libxl__gc *gc, libxl_domid domid)
+int libxl__domain_unpause_deprecated(libxl__gc *gc, libxl_domid domid)
 {
     int r, rc;
 
@@ -604,7 +604,7 @@ int libxl__domain_unpause(libxl__gc *gc, libxl_domid domid)
     }
 
     if (type == LIBXL_DOMAIN_TYPE_HVM) {
-        rc = libxl__domain_resume_device_model(gc, domid);
+        rc = libxl__domain_resume_device_model_deprecated(gc, domid);
         if (rc < 0) {
             LOGD(ERROR, domid,
                  "Failed to unpause device model for domain: %d", rc);
@@ -628,7 +628,7 @@ int libxl_domain_unpause(libxl_ctx *ctx, uint32_t domid,
     AO_CREATE(ctx, domid, ao_how);
     int rc = 0;
 
-    rc = libxl__domain_unpause(gc, domid);
+    rc = libxl__domain_unpause_deprecated(gc, domid);
     if (rc) goto out;
 
     libxl__ao_complete(egc, ao, rc);
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index f5f234be7e3c..db8860507b18 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1315,7 +1315,8 @@ _hidden int libxl__domain_rename(libxl__gc *gc, uint32_t domid,
                                  const char *old_name, const char *new_name,
                                  xs_transaction_t trans);
 
-_hidden int libxl__domain_resume_device_model(libxl__gc *gc, uint32_t domid);
+/* Deprecated, use libxl__dm_resume instead. */
+_hidden int libxl__domain_resume_device_model_deprecated(libxl__gc *gc, uint32_t domid);
 
 _hidden const char *libxl__userdata_path(libxl__gc *gc, uint32_t domid,
                                          const char *userdata_userid,
@@ -1332,8 +1333,12 @@ _hidden int libxl__userdata_store(libxl__gc *gc, uint32_t domid,
                                   const char *userdata_userid,
                                   const uint8_t *data, int datalen);
 
-_hidden int libxl__domain_resume(libxl__gc *gc, uint32_t domid,
-                                 int suspend_cancel);
+/* Deprecated, use libxl__domain_resume instead */
+_hidden int libxl__domain_resume_deprecated(libxl__gc *gc, uint32_t domid,
+                                            int suspend_cancel);
+/* Deprecated, use libxl__domain_unpause instead */
+_hidden int libxl__domain_unpause_deprecated(libxl__gc *,
+                                             libxl_domid domid);
 
 /* returns 0 or 1, or a libxl error code */
 _hidden int libxl__domain_pvcontrol_available(libxl__gc *gc, uint32_t domid);
@@ -4104,7 +4109,6 @@ _hidden void libxl__remus_teardown(libxl__egc *egc,
                                    int rc);
 _hidden void libxl__remus_restore_setup(libxl__egc *egc,
                                         libxl__domain_create_state *dcs);
-_hidden int libxl__domain_unpause(libxl__gc *, libxl_domid domid);
 
 
 /*
diff --git a/tools/libxl/libxl_remus.c b/tools/libxl/libxl_remus.c
index 29a47838c8e6..6338a1bae5a5 100644
--- a/tools/libxl/libxl_remus.c
+++ b/tools/libxl/libxl_remus.c
@@ -267,7 +267,7 @@ static void remus_devices_preresume_cb(libxl__egc *egc,
         goto out;
 
     /* Resumes the domain and the device model */
-    rc = libxl__domain_resume(gc, dss->domid, /* Fast Suspend */1);
+    rc = libxl__domain_resume_deprecated(gc, dss->domid, /* Fast Suspend */1);
     if (rc)
         goto out;
 
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 10/35] libxl: Re-introduce libxl__domain_resume
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (8 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 09/35] libxl: Deprecate libxl__domain_{unpause, resume} Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 11/35] libxl_domain: Convert libxl_domain_resume to use libxl__domain_resume Anthony PERARD
                   ` (25 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

libxl__domain_resume is a rework libxl__domain_resume_deprecated. It
makes uses of ev_xswatch and ev_qmp, to replace synchronous QMP calls
and libxl__wait_for_device_model_deprecated call.

This patch also introduce libxl__dm_resume which is a sub-operation of
both libxl__domain_resume and libxl__domain_unpause and can be used
instead of libxl__domain_resume_device_model_deprecated.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_dom_suspend.c | 192 ++++++++++++++++++++++++++++++++
 tools/libxl/libxl_internal.h    |  27 +++++
 2 files changed, 219 insertions(+)

diff --git a/tools/libxl/libxl_dom_suspend.c b/tools/libxl/libxl_dom_suspend.c
index 2460021e5a59..9bb2d00bec9a 100644
--- a/tools/libxl/libxl_dom_suspend.c
+++ b/tools/libxl/libxl_dom_suspend.c
@@ -481,6 +481,198 @@ int libxl__domain_resume_deprecated(libxl__gc *gc, uint32_t domid, int suspend_c
     return rc;
 }
 
+static void dm_resume_init(libxl__dm_resume_state *dmrs)
+{
+    libxl__ev_qmp_init(&dmrs->qmp);
+    libxl__ev_time_init(&dmrs->time);
+    libxl__ev_xswatch_init(&dmrs->watch);
+}
+
+static void dm_resume_dispose(libxl__gc *gc,
+                              libxl__dm_resume_state *dmrs)
+{
+    libxl__ev_qmp_dispose(gc, &dmrs->qmp);
+    libxl__ev_time_deregister(gc, &dmrs->time);
+    libxl__ev_xswatch_deregister(gc, &dmrs->watch);
+}
+
+static void dm_resume_xswatch_cb(libxl__egc *egc,
+    libxl__ev_xswatch *, const char *watch_path, const char *);
+static void dm_resume_qmp_done(libxl__egc *egc,
+    libxl__ev_qmp *qmp, const libxl__json_object *, int rc);
+static void dm_resume_timeout(libxl__egc *egc,
+    libxl__ev_time *, const struct timeval *, int rc);
+static void dm_resume_done(libxl__egc *egc,
+    libxl__dm_resume_state *dmrs, int rc);
+
+void libxl__dm_resume(libxl__egc *egc,
+                      libxl__dm_resume_state *dmrs)
+{
+    STATE_AO_GC(dmrs->ao);
+    int rc = 0;
+
+    /* Convenience aliases */
+    libxl_domid domid = dmrs->domid;
+    libxl__ev_qmp *qmp = &dmrs->qmp;
+
+    dm_resume_init(dmrs);
+
+    rc = libxl__ev_time_register_rel(dmrs->ao,
+                                     &dmrs->time,
+                                     dm_resume_timeout,
+                                     LIBXL_DEVICE_MODEL_START_TIMEOUT);
+    if (rc) goto out;
+
+    switch (libxl__device_model_version_running(gc, domid)) {
+    case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL: {
+        uint32_t dm_domid = libxl_get_stubdom_id(CTX, domid);
+        const char *path, *state;
+
+        path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid, "/state");
+        rc = libxl__xs_read_checked(gc, XBT_NULL, path, &state);
+        if (rc) goto out;
+        if (!state || strcmp(state, "paused")) {
+            /* already running */
+            rc = 0;
+            goto out;
+        }
+
+        rc = libxl__qemu_traditional_cmd(gc, domid, "continue");
+        if (rc) goto out;
+        rc = libxl__ev_xswatch_register(gc, &dmrs->watch,
+                                        dm_resume_xswatch_cb,
+                                        path);
+        if (rc) goto out;
+        break;
+    }
+    case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
+        qmp->ao = dmrs->ao;
+        qmp->domid = domid;
+        qmp->callback = dm_resume_qmp_done;
+        qmp->payload_fd = -1;
+        rc = libxl__ev_qmp_send(gc, qmp, "cont", NULL);
+        if (rc) goto out;
+        break;
+    default:
+        rc = ERROR_INVAL;
+        goto out;
+    }
+
+    return;
+
+out:
+    dm_resume_done(egc, dmrs, rc);
+}
+
+static void dm_resume_xswatch_cb(libxl__egc *egc,
+                                 libxl__ev_xswatch *xsw,
+                                 const char *watch_path,
+                                 const char *event_path)
+{
+    EGC_GC;
+    libxl__dm_resume_state *dmrs = CONTAINER_OF(xsw, *dmrs, watch);
+    int rc;
+    const char *value;
+
+    rc = libxl__xs_read_checked(gc, XBT_NULL, watch_path, &value);
+    if (rc) goto out;
+
+    if (!value || strcmp(value, "running"))
+        return;
+
+    rc = 0;
+out:
+    dm_resume_done(egc, dmrs, rc);
+}
+
+static void dm_resume_qmp_done(libxl__egc *egc,
+                               libxl__ev_qmp *qmp,
+                               const libxl__json_object *response,
+                               int rc)
+{
+    libxl__dm_resume_state *dmrs = CONTAINER_OF(qmp, *dmrs, qmp);
+    dm_resume_done(egc, dmrs, rc);
+}
+
+static void dm_resume_timeout(libxl__egc *egc,
+                              libxl__ev_time *ev,
+                              const struct timeval *requested_abs,
+                              int rc)
+{
+    libxl__dm_resume_state *dmrs = CONTAINER_OF(ev, *dmrs, time);
+    dm_resume_done(egc, dmrs, rc);
+}
+
+static void dm_resume_done(libxl__egc *egc,
+                           libxl__dm_resume_state *dmrs,
+                           int rc)
+{
+    EGC_GC;
+
+    if (rc) {
+        LOGD(ERROR, dmrs->domid,
+             "Failed to resume device model: rc=%d", rc);
+    }
+
+    dm_resume_dispose(gc, dmrs);
+    dmrs->dm_resumed_callback(egc, dmrs, rc);
+}
+
+
+static void domain_resume_done(libxl__egc *egc,
+                               libxl__dm_resume_state *dmrs, int rc);
+
+void libxl__domain_resume(libxl__egc *egc,
+                          libxl__dm_resume_state *dmrs,
+                          bool suspend_cancel)
+{
+    STATE_AO_GC(dmrs->ao);
+    int rc = 0;
+    libxl_domain_type type = libxl__domain_type(gc, dmrs->domid);
+
+    if (type == LIBXL_DOMAIN_TYPE_INVALID) {
+        rc = ERROR_FAIL;
+        goto out;
+    }
+
+    if (type != LIBXL_DOMAIN_TYPE_HVM) {
+        rc = 0;
+        goto out;
+    }
+
+    dmrs->suspend_cancel = suspend_cancel;
+    dmrs->dm_resumed_callback = domain_resume_done;
+    libxl__dm_resume(egc, dmrs); /* must be last */
+    return;
+
+out:
+    domain_resume_done(egc, dmrs, rc);
+}
+
+static void domain_resume_done(libxl__egc *egc,
+                               libxl__dm_resume_state *dmrs, int rc)
+{
+    EGC_GC;
+
+    /* Convenience aliases */
+    libxl_domid domid = dmrs->domid;
+
+    if (rc) goto out;
+
+    if (xc_domain_resume(CTX->xch, domid, dmrs->suspend_cancel)) {
+        LOGED(ERROR, domid, "xc_domain_resume failed");
+        rc = ERROR_FAIL;
+        goto out;
+    }
+
+    if (!xs_resume_domain(CTX->xsh, domid)) {
+        LOGED(ERROR, domid, "xs_resume_domain failed");
+        rc = ERROR_FAIL;
+    }
+out:
+    dmrs->callback(egc, dmrs, rc);
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index db8860507b18..6bb6d6d2e166 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -197,6 +197,7 @@ typedef struct libxl__device_type libxl__device_type;
 typedef struct libxl__json_object libxl__json_object;
 typedef struct libxl__carefd libxl__carefd;
 typedef struct libxl__ev_devlock libxl__ev_devlock;
+typedef struct libxl__dm_resume_state libxl__dm_resume_state;
 
 typedef struct libxl__domain_create_state libxl__domain_create_state;
 typedef void libxl__domain_create_cb(struct libxl__egc *egc,
@@ -1340,6 +1341,32 @@ _hidden int libxl__domain_resume_deprecated(libxl__gc *gc, uint32_t domid,
 _hidden int libxl__domain_unpause_deprecated(libxl__gc *,
                                              libxl_domid domid);
 
+/* Call libxl__dm_resume_init() and fill the first few fields,
+ * then call one of libxl__domain_resume / libxl__domain_unpause
+ * or directly libxl__dm_resume if only the device model needs to be
+ * "resumed". */
+struct libxl__dm_resume_state {
+    /* caller must fill these in, and they must all remain valid */
+    libxl__ao *ao;
+    libxl_domid domid;
+    void (*callback)(libxl__egc *, libxl__dm_resume_state *, int rc);
+
+    /* private to libxl__domain_resume */
+    void (*dm_resumed_callback)(libxl__egc *,
+                                libxl__dm_resume_state *, int rc);
+    bool suspend_cancel;
+
+    /* private to libxl__dm_resume */
+    libxl__ev_qmp qmp;
+    libxl__ev_time time;
+    libxl__ev_xswatch watch;
+};
+_hidden void libxl__dm_resume(libxl__egc *egc,
+                              libxl__dm_resume_state *dmrs);
+_hidden void libxl__domain_resume(libxl__egc *egc,
+                                  libxl__dm_resume_state *dmrs,
+                                  bool suspend_cancel);
+
 /* returns 0 or 1, or a libxl error code */
 _hidden int libxl__domain_pvcontrol_available(libxl__gc *gc, uint32_t domid);
 
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 11/35] libxl_domain: Convert libxl_domain_resume to use libxl__domain_resume
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (9 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 10/35] libxl: Re-introduce libxl__domain_resume Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 12/35] libxl: Re-introduce libxl__domain_unpause Anthony PERARD
                   ` (24 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_domain.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c
index 80797c5ed21c..d78ffa6b6019 100644
--- a/tools/libxl/libxl_domain.c
+++ b/tools/libxl/libxl_domain.c
@@ -174,15 +174,32 @@ int libxl_domain_rename(libxl_ctx *ctx, uint32_t domid,
     return rc;
 }
 
+static void domain_resume_done(libxl__egc *egc,
+                               libxl__dm_resume_state *,
+                               int rc);
+
 int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid, int suspend_cancel,
                         const libxl_asyncop_how *ao_how)
 {
     AO_CREATE(ctx, domid, ao_how);
-    int rc = libxl__domain_resume_deprecated(gc, domid, suspend_cancel);
-    libxl__ao_complete(egc, ao, rc);
+    libxl__dm_resume_state *dmrs;
+
+    GCNEW(dmrs);
+    dmrs->ao = ao;
+    dmrs->domid = domid;
+    dmrs->callback = domain_resume_done;
+    libxl__domain_resume(egc, dmrs, suspend_cancel);
     return AO_INPROGRESS;
 }
 
+static void domain_resume_done(libxl__egc *egc,
+                               libxl__dm_resume_state *dmrs,
+                               int rc)
+{
+    STATE_AO_GC(dmrs->ao);
+    libxl__ao_complete(egc, ao, rc);
+}
+
 /*
  * Preserves a domain but rewrites xenstore etc to make it unique so
  * that the domain can be restarted.
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 12/35] libxl: Re-introduce libxl__domain_unpause
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (10 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 11/35] libxl_domain: Convert libxl_domain_resume to use libxl__domain_resume Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 13/35] libxl_dm: Update libxl__spawn_stub_dm to use libxl__domain_unpause Anthony PERARD
                   ` (23 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

libxl__domain_unpause is a reimplementation of
libxl__domain_unpause_deprecated with asynchronous operation.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_domain.c   | 52 ++++++++++++++++++++++++++++++++++++
 tools/libxl/libxl_internal.h |  5 +++-
 2 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c
index d78ffa6b6019..52a8bd7895cb 100644
--- a/tools/libxl/libxl_domain.c
+++ b/tools/libxl/libxl_domain.c
@@ -639,6 +639,58 @@ int libxl__domain_unpause_deprecated(libxl__gc *gc, libxl_domid domid)
     return rc;
 }
 
+static void domain_unpause_done(libxl__egc *egc,
+                                libxl__dm_resume_state *,
+                                int rc);
+
+void libxl__domain_unpause(libxl__egc *egc,
+                           libxl__dm_resume_state *dmrs)
+{
+    STATE_AO_GC(dmrs->ao);
+    int rc = 0;
+
+    /* Convenience aliases */
+    libxl_domid domid = dmrs->domid;
+
+    libxl_domain_type type = libxl__domain_type(gc, domid);
+    if (type == LIBXL_DOMAIN_TYPE_INVALID) {
+        rc = ERROR_FAIL;
+        goto out;
+    }
+
+    if (type == LIBXL_DOMAIN_TYPE_HVM) {
+        dmrs->dm_resumed_callback = domain_unpause_done;
+        libxl__dm_resume(egc, dmrs); /* must be last */
+        return;
+    }
+    rc = 0;
+out:
+    domain_unpause_done(egc, dmrs, rc);
+}
+
+static void domain_unpause_done(libxl__egc *egc,
+                                libxl__dm_resume_state *dmrs,
+                                int rc)
+{
+    EGC_GC;
+    int r;
+
+    /* Convenience aliases */
+    libxl_domid domid = dmrs->domid;
+
+    if (rc) goto out;
+
+    r = xc_domain_unpause(CTX->xch, domid);
+    if (r < 0) {
+        LOGED(ERROR, domid, "Unpausing domain");
+        rc = ERROR_FAIL;
+        goto out;
+    }
+    rc = 0;
+out:
+    dmrs->callback(egc, dmrs, rc);
+}
+
 int libxl_domain_unpause(libxl_ctx *ctx, uint32_t domid,
                          const libxl_asyncop_how *ao_how)
 {
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 6bb6d6d2e166..a0cb6d28858f 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1351,9 +1351,10 @@ struct libxl__dm_resume_state {
     libxl_domid domid;
     void (*callback)(libxl__egc *, libxl__dm_resume_state *, int rc);
 
-    /* private to libxl__domain_resume */
+    /* private to libxl__domain_resume and libxl__domain_unpause */
     void (*dm_resumed_callback)(libxl__egc *,
                                 libxl__dm_resume_state *, int rc);
+    /* private to libxl__domain_resume */
     bool suspend_cancel;
 
     /* private to libxl__dm_resume */
@@ -1366,6 +1367,8 @@ _hidden void libxl__dm_resume(libxl__egc *egc,
 _hidden void libxl__domain_resume(libxl__egc *egc,
                                   libxl__dm_resume_state *dmrs,
                                   bool suspend_cancel);
+_hidden void libxl__domain_unpause(libxl__egc *,
+                                   libxl__dm_resume_state *dmrs);
 
 /* returns 0 or 1, or a libxl error code */
 _hidden int libxl__domain_pvcontrol_available(libxl__gc *gc, uint32_t domid);
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 13/35] libxl_dm: Update libxl__spawn_stub_dm to use libxl__domain_unpause
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (11 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 12/35] libxl: Re-introduce libxl__domain_unpause Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 14/35] libxl_domain: Convert libxl_domain_unpause " Anthony PERARD
                   ` (22 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_dm.c       | 22 +++++++++++++++++++++-
 tools/libxl/libxl_internal.h |  1 +
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index 246c570121d3..c00356a2f16a 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -2082,6 +2082,9 @@ static void spawn_stub_launch_dm(libxl__egc *egc,
 static void stubdom_pvqemu_cb(libxl__egc *egc,
                               libxl__multidev *aodevs,
                               int rc);
+static void stubdom_pvqemu_unpaused(libxl__egc *egc,
+                                    libxl__dm_resume_state *dmrs,
+                                    int rc);
 
 static void stubdom_xswait_cb(libxl__egc *egc, libxl__xswait_state *xswait,
                               int rc, const char *p);
@@ -2404,7 +2407,24 @@ static void stubdom_pvqemu_cb(libxl__egc *egc,
         goto out;
     }
 
-    rc = libxl__domain_unpause_deprecated(gc, dm_domid);
+    sdss->pvqemu.dmrs.ao = ao;
+    sdss->pvqemu.dmrs.domid = dm_domid;
+    sdss->pvqemu.dmrs.callback = stubdom_pvqemu_unpaused;
+    libxl__domain_unpause(egc, &sdss->pvqemu.dmrs); /* must be last */
+    return;
+out:
+    stubdom_pvqemu_unpaused(egc, &sdss->pvqemu.dmrs, rc);
+}
+
+static void stubdom_pvqemu_unpaused(libxl__egc *egc,
+                                    libxl__dm_resume_state *dmrs,
+                                    int rc)
+{
+    libxl__stub_dm_spawn_state *sdss =
+        CONTAINER_OF(dmrs, *sdss, pvqemu.dmrs);
+    STATE_AO_GC(sdss->dm.spawn.ao);
+    uint32_t dm_domid = sdss->pvqemu.guest_domid;
+
     if (rc) goto out;
 
     sdss->xswait.ao = ao;
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index a0cb6d28858f..1144aaa3a569 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3985,6 +3985,7 @@ struct libxl__dm_spawn_state {
     libxl__spawn_state spawn;
     libxl__ev_qmp qmp;
     libxl__ev_time timeout;
+    libxl__dm_resume_state dmrs;
     /* filled in by user, must remain valid: */
     uint32_t guest_domid; /* domain being served */
     libxl_domain_config *guest_config;
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 14/35] libxl_domain: Convert libxl_domain_unpause to use libxl__domain_unpause
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (12 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 13/35] libxl_dm: Update libxl__spawn_stub_dm to use libxl__domain_unpause Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 15/35] libxl: Inline do_usbdev_add into libxl__device_usbdev_add Anthony PERARD
                   ` (21 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_domain.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c
index 52a8bd7895cb..f3c39fa86fc9 100644
--- a/tools/libxl/libxl_domain.c
+++ b/tools/libxl/libxl_domain.c
@@ -691,20 +691,31 @@ static void domain_unpause_done(libxl__egc *egc,
     dmrs->callback(egc, dmrs, rc);
 }
 
+static void domain_unpause_ao_done(libxl__egc *egc,
+                                   libxl__dm_resume_state *,
+                                   int rc);
+
 int libxl_domain_unpause(libxl_ctx *ctx, uint32_t domid,
                          const libxl_asyncop_how *ao_how)
 {
     AO_CREATE(ctx, domid, ao_how);
-    int rc = 0;
-
-    rc = libxl__domain_unpause_deprecated(gc, domid);
-    if (rc) goto out;
+    libxl__dm_resume_state *dmrs;
 
-    libxl__ao_complete(egc, ao, rc);
+    GCNEW(dmrs);
+    dmrs->ao = ao;
+    dmrs->domid = domid;
+    dmrs->callback = domain_unpause_ao_done;
+    libxl__domain_unpause(egc, dmrs); /* must be last */
     return AO_INPROGRESS;
+}
 
- out:
-    return AO_CREATE_FAIL(rc);
+static void domain_unpause_ao_done(libxl__egc *egc,
+                                   libxl__dm_resume_state *dmrs,
+                                   int rc)
+{
+    STATE_AO_GC(dmrs->ao);
+
+    libxl__ao_complete(egc, ao, rc);
 }
 
 int libxl__domain_pvcontrol_available(libxl__gc *gc, uint32_t domid)
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 15/35] libxl: Inline do_usbdev_add into libxl__device_usbdev_add
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (13 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 14/35] libxl_domain: Convert libxl_domain_unpause " Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 16/35] libxl: Inline do_usbdev_remove into libxl__device_usbdev_remove Anthony PERARD
                   ` (20 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

Having the function do_usbdev_add makes it harder to add asynchronous
calls into it. Move its body back into libxl__device_usbdev_add and
adjust the latter as there are no reason to have a separated function.

No functional changes.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_usb.c | 121 ++++++++++++++++++----------------------
 1 file changed, 53 insertions(+), 68 deletions(-)

diff --git a/tools/libxl/libxl_usb.c b/tools/libxl/libxl_usb.c
index f6a98860c8dc..0da7a725a720 100644
--- a/tools/libxl/libxl_usb.c
+++ b/tools/libxl/libxl_usb.c
@@ -1517,72 +1517,6 @@ static int usbback_dev_assign(libxl__gc *gc, const char *busid)
     return rc;
 }
 
-static int do_usbdev_add(libxl__gc *gc, uint32_t domid,
-                         libxl_device_usbdev *usbdev,
-                         bool update_json)
-{
-    int rc;
-    char *busid;
-    libxl_device_usbctrl usbctrl;
-
-    libxl_device_usbctrl_init(&usbctrl);
-    rc = libxl_devid_to_device_usbctrl(CTX, domid, usbdev->ctrl, &usbctrl);
-    if (rc) goto out;
-
-    switch (usbctrl.type) {
-    case LIBXL_USBCTRL_TYPE_PV:
-        busid = usbdev_busaddr_to_busid(gc, usbdev->u.hostdev.hostbus,
-                                        usbdev->u.hostdev.hostaddr);
-        if (!busid) {
-            rc = ERROR_FAIL;
-            goto out;
-        }
-
-        rc = libxl__device_usbdev_add_xenstore(gc, domid, usbdev,
-                                               LIBXL_USBCTRL_TYPE_PV,
-                                               update_json);
-        if (rc) goto out;
-
-        rc = usbback_dev_assign(gc, busid);
-        if (rc) {
-            libxl__device_usbdev_remove_xenstore(gc, domid, usbdev,
-                                                 LIBXL_USBCTRL_TYPE_PV);
-            goto out;
-        }
-        break;
-    case LIBXL_USBCTRL_TYPE_QUSB:
-        rc = libxl__device_usbdev_add_xenstore(gc, domid, usbdev,
-                                               LIBXL_USBCTRL_TYPE_QUSB,
-                                               update_json);
-        if (rc) goto out;
-
-        break;
-    case LIBXL_USBCTRL_TYPE_DEVICEMODEL:
-        rc = libxl__device_usbdev_add_xenstore(gc, domid, usbdev,
-                                               LIBXL_USBCTRL_TYPE_DEVICEMODEL,
-                                               update_json);
-        if (rc) goto out;
-
-        rc = libxl__device_usbdev_add_hvm(gc, domid, usbdev);
-        if (rc) {
-            libxl__device_usbdev_remove_xenstore(gc, domid, usbdev,
-                                             LIBXL_USBCTRL_TYPE_DEVICEMODEL);
-            goto out;
-        }
-        break;
-    default:
-        LOGD(ERROR, domid, "Unsupported usb controller type");
-        rc = ERROR_FAIL;
-        goto out;
-    }
-
-    rc = 0;
-
-out:
-    libxl_device_usbctrl_dispose(&usbctrl);
-    return rc;
-}
-
 /* AO operation to add a usb device.
  *
  * Generally, it does:
@@ -1608,6 +1542,7 @@ static void libxl__device_usbdev_add(libxl__egc *egc, uint32_t domid,
     libxl_device_usbdev *assigned;
     int num_assigned;
     libxl_device_usbctrl usbctrl;
+    char *busid;
 
     libxl_device_usbctrl_init(&usbctrl);
 
@@ -1626,6 +1561,7 @@ static void libxl__device_usbdev_add(libxl__egc *egc, uint32_t domid,
             rc = ERROR_INVAL;
             goto out;
         }
+        libxl_device_usbctrl_dispose(&usbctrl);
     }
 
     /* check usb device is assignable type */
@@ -1655,14 +1591,63 @@ static void libxl__device_usbdev_add(libxl__egc *egc, uint32_t domid,
                                          aodev->update_json);
     if (rc) goto out;
 
+    rc = libxl_devid_to_device_usbctrl(CTX, domid, usbdev->ctrl, &usbctrl);
+    if (rc) goto out;
+
     /* do actual adding usb device operation */
-    rc = do_usbdev_add(gc, domid, usbdev, aodev->update_json);
+    switch (usbctrl.type) {
+    case LIBXL_USBCTRL_TYPE_PV:
+        busid = usbdev_busaddr_to_busid(gc, usbdev->u.hostdev.hostbus,
+                                        usbdev->u.hostdev.hostaddr);
+        if (!busid) {
+            rc = ERROR_FAIL;
+            goto out;
+        }
+
+        rc = libxl__device_usbdev_add_xenstore(gc, domid, usbdev,
+                                               LIBXL_USBCTRL_TYPE_PV,
+                                               aodev->update_json);
+        if (rc) goto out;
+
+        rc = usbback_dev_assign(gc, busid);
+        if (rc) {
+            libxl__device_usbdev_remove_xenstore(gc, domid, usbdev,
+                                                 LIBXL_USBCTRL_TYPE_PV);
+            goto out;
+        }
+        break;
+    case LIBXL_USBCTRL_TYPE_QUSB:
+        rc = libxl__device_usbdev_add_xenstore(gc, domid, usbdev,
+                                               LIBXL_USBCTRL_TYPE_QUSB,
+                                               aodev->update_json);
+        if (rc) goto out;
+
+        break;
+    case LIBXL_USBCTRL_TYPE_DEVICEMODEL:
+        rc = libxl__device_usbdev_add_xenstore(gc, domid, usbdev,
+                                               LIBXL_USBCTRL_TYPE_DEVICEMODEL,
+                                               aodev->update_json);
+        if (rc) goto out;
+
+        rc = libxl__device_usbdev_add_hvm(gc, domid, usbdev);
+        if (rc) {
+            libxl__device_usbdev_remove_xenstore(gc, domid, usbdev,
+                                             LIBXL_USBCTRL_TYPE_DEVICEMODEL);
+            goto out;
+        }
+        break;
+    default:
+        LOGD(ERROR, domid, "Unsupported usb controller type");
+        rc = ERROR_FAIL;
+        goto out;
+    }
+
+    rc = 0;
 
 out:
     libxl_device_usbctrl_dispose(&usbctrl);
     aodev->rc = rc;
     aodev->callback(egc, aodev);
-    return;
 }
 
 LIBXL_DEFINE_DEVICE_ADD(usbdev)
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 16/35] libxl: Inline do_usbdev_remove into libxl__device_usbdev_remove
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (14 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 15/35] libxl: Inline do_usbdev_add into libxl__device_usbdev_add Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 17/35] libxl: Add libxl__ev_qmp to libxl__ao_device Anthony PERARD
                   ` (19 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

Having the function do_usbdev_remove makes it harder to add asynchronous
calls into it. Move its body back into libxl__device_usbdev_remove and
adjust the latter as there are no reason to have a separated function.

No functional changes.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_usb.c | 63 +++++++++++++++--------------------------
 1 file changed, 23 insertions(+), 40 deletions(-)

diff --git a/tools/libxl/libxl_usb.c b/tools/libxl/libxl_usb.c
index 0da7a725a720..de8122dc57e9 100644
--- a/tools/libxl/libxl_usb.c
+++ b/tools/libxl/libxl_usb.c
@@ -1653,17 +1653,38 @@ static void libxl__device_usbdev_add(libxl__egc *egc, uint32_t domid,
 LIBXL_DEFINE_DEVICE_ADD(usbdev)
 static LIBXL_DEFINE_DEVICES_ADD(usbdev)
 
-static int do_usbdev_remove(libxl__gc *gc, uint32_t domid,
-                            libxl_device_usbdev *usbdev)
+/* Operation to remove usb device.
+ *
+ * Generally, it does:
+ * 1) check if the usb device is assigned to the domain
+ * 2) remove the usb device from xenstore controller/port.
+ * 3) unbind usb device from usbback and rebind to its original driver.
+ *    If usb device has many interfaces, do it to each interface.
+ */
+static int libxl__device_usbdev_remove(libxl__gc *gc, uint32_t domid,
+                                       libxl_device_usbdev *usbdev)
 {
     int rc;
     char *busid;
     libxl_device_usbctrl usbctrl;
 
+    if (usbdev->ctrl < 0 || usbdev->port < 1) {
+        LOGD(ERROR, domid, "Invalid USB device");
+        return ERROR_FAIL;
+    }
+
     libxl_device_usbctrl_init(&usbctrl);
     rc = libxl_devid_to_device_usbctrl(CTX, domid, usbdev->ctrl, &usbctrl);
     if (rc) goto out;
 
+    if (usbctrl.backend_domid != LIBXL_TOOLSTACK_DOMID) {
+        LOGD(ERROR, domid,
+             "Don't support removing USB device from non-Dom0 backend");
+        rc = ERROR_INVAL;
+        goto out;
+    }
+
+    /* do actual removing usb device operation */
     switch (usbctrl.type) {
     case LIBXL_USBCTRL_TYPE_PV:
         busid = usbdev_busid_from_ctrlport(gc, domid, usbdev, usbctrl.type);
@@ -1741,44 +1762,6 @@ static int do_usbdev_remove(libxl__gc *gc, uint32_t domid,
     return rc;
 }
 
-/* Operation to remove usb device.
- *
- * Generally, it does:
- * 1) check if the usb device is assigned to the domain
- * 2) remove the usb device from xenstore controller/port.
- * 3) unbind usb device from usbback and rebind to its original driver.
- *    If usb device has many interfaces, do it to each interface.
- */
-static int libxl__device_usbdev_remove(libxl__gc *gc, uint32_t domid,
-                                       libxl_device_usbdev *usbdev)
-{
-    libxl_device_usbctrl usbctrl;
-    int rc;
-
-    if (usbdev->ctrl < 0 || usbdev->port < 1) {
-        LOGD(ERROR, domid, "Invalid USB device");
-        return ERROR_FAIL;
-    }
-
-    libxl_device_usbctrl_init(&usbctrl);
-    rc = libxl_devid_to_device_usbctrl(CTX, domid, usbdev->ctrl, &usbctrl);
-    if (rc) goto out;
-
-    if (usbctrl.backend_domid != LIBXL_TOOLSTACK_DOMID) {
-        LOGD(ERROR, domid,
-             "Don't support removing USB device from non-Dom0 backend");
-        rc = ERROR_INVAL;
-        goto out;
-    }
-
-    /* do actual removing usb device operation */
-    rc = do_usbdev_remove(gc, domid, usbdev);
-
-out:
-    libxl_device_usbctrl_dispose(&usbctrl);
-    return rc;
-}
-
 int libxl_device_usbdev_remove(libxl_ctx *ctx, uint32_t domid,
                                libxl_device_usbdev *usbdev,
                                const libxl_asyncop_how *ao_how)
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 17/35] libxl: Add libxl__ev_qmp to libxl__ao_device
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (15 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 16/35] libxl: Inline do_usbdev_remove into libxl__device_usbdev_remove Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 18/35] libxl: Add device_{config, type} " Anthony PERARD
                   ` (18 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

`aodev->qmp' is initialised in libxl__prepare_ao_device(), but since
there isn't a single exit path for a `libxl__ao_device', users of this
new `qmp' field will have to disposed of it.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---

Notes:
    v2:
    - Added a comment to libxl__prepare_ao_device about fields like `qmp'
      which might needs to be cleaned up by the caller.

 tools/libxl/libxl_device.c   | 2 ++
 tools/libxl/libxl_internal.h | 5 +++++
 2 files changed, 7 insertions(+)

diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
index 1941fe780ac0..1402b61a810b 100644
--- a/tools/libxl/libxl_device.c
+++ b/tools/libxl/libxl_device.c
@@ -644,6 +644,8 @@ void libxl__prepare_ao_device(libxl__ao *ao, libxl__ao_device *aodev)
      * without actually calling any hotplug script */
     libxl__async_exec_init(&aodev->aes);
     libxl__ev_child_init(&aodev->child);
+
+    libxl__ev_qmp_init(&aodev->qmp);
 }
 
 /* multidev */
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 1144aaa3a569..43a431f53565 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -2592,6 +2592,10 @@ typedef void libxl__device_callback(libxl__egc*, libxl__ao_device*);
  * Once _prepare has been called on a libxl__ao_device, it is safe to just
  * discard this struct, there's no need to call any destroy function.
  * _prepare can also be called multiple times with the same libxl__ao_device.
+ *
+ * But if any of the fields `backend_ds', `timeout', `xswait', `qmp' is
+ * used by a caller of _prepare, the caller will have to arrange to clean
+ * or dispose of them.
  */
 _hidden void libxl__prepare_ao_device(libxl__ao *ao, libxl__ao_device *aodev);
 
@@ -2623,6 +2627,7 @@ struct libxl__ao_device {
     bool update_json;
     /* for asynchronous execution of synchronous-only syscalls etc. */
     libxl__ev_child child;
+    libxl__ev_qmp qmp;
 };
 
 /*
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 18/35] libxl: Add device_{config, type} to libxl__ao_device
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (16 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 17/35] libxl: Add libxl__ev_qmp to libxl__ao_device Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 19/35] libxl_usb: Make libxl__device_usbctrl_add uses ev_qmp Anthony PERARD
                   ` (17 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

These two fields help to give more information about the device been
hotplug/hotunplug to callbacks.

There is already `dev' of type `libxl__device', but it is mostly
useful when the backend/frontend is xenstore. Some device (like
`usbdev') don't have devid, so `dev' can't be used.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_internal.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 43a431f53565..6c09b93f91f1 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -2628,6 +2628,12 @@ struct libxl__ao_device {
     /* for asynchronous execution of synchronous-only syscalls etc. */
     libxl__ev_child child;
     libxl__ev_qmp qmp;
+    /* 'device_config' can be used to to pass to callbacks a pointer of one
+     * of the type 'libxl_device_$type' corresponding to the device been
+     * hotplug. 'device_type' should have the corresponding
+     * 'libxl__$type_devtype'. */
+    void *device_config;
+    const libxl__device_type *device_type;
 };
 
 /*
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 19/35] libxl_usb: Make libxl__device_usbctrl_add uses ev_qmp
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (17 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 18/35] libxl: Add device_{config, type} " Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 20/35] libxl_usb: Make libxl__initiate_device_usbctrl_remove " Anthony PERARD
                   ` (16 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_usb.c | 93 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 77 insertions(+), 16 deletions(-)

diff --git a/tools/libxl/libxl_usb.c b/tools/libxl/libxl_usb.c
index de8122dc57e9..506dbdcf5ee4 100644
--- a/tools/libxl/libxl_usb.c
+++ b/tools/libxl/libxl_usb.c
@@ -349,33 +349,36 @@ static char *pvusb_get_device_type(libxl_usbctrl_type type)
  * - usb-ehci       (version=2), always 6 ports
  * - nec-usb-xhci   (version=3), up to 15 ports
  */
-static int libxl__device_usbctrl_add_hvm(libxl__gc *gc, uint32_t domid,
+static int libxl__device_usbctrl_add_hvm(libxl__gc *gc, libxl__ev_qmp *qmp,
                                          libxl_device_usbctrl *usbctrl)
 {
-    flexarray_t *qmp_args;
-
-    qmp_args = flexarray_make(gc, 8, 1);
+    libxl__json_object *qmp_args = NULL;
 
     switch (usbctrl->version) {
     case 1:
-        flexarray_append_pair(qmp_args, "driver", "piix3-usb-uhci");
+        libxl__qmp_param_add_string(gc, &qmp_args,
+                                    "driver", "piix3-usb-uhci");
         break;
     case 2:
-        flexarray_append_pair(qmp_args, "driver", "usb-ehci");
+        libxl__qmp_param_add_string(gc, &qmp_args,
+                                    "driver", "usb-ehci");
         break;
     case 3:
-        flexarray_append_pair(qmp_args, "driver", "nec-usb-xhci");
-        flexarray_append_pair(qmp_args, "p2", GCSPRINTF("%d", usbctrl->ports));
-        flexarray_append_pair(qmp_args, "p3", GCSPRINTF("%d", usbctrl->ports));
+        libxl__qmp_param_add_string(gc, &qmp_args,
+                                    "driver", "nec-usb-xhci");
+        libxl__qmp_param_add_string(gc, &qmp_args, "p2",
+                                    GCSPRINTF("%d", usbctrl->ports));
+        libxl__qmp_param_add_string(gc, &qmp_args, "p3",
+                                    GCSPRINTF("%d", usbctrl->ports));
         break;
     default:
         abort(); /* Should not be possible. */
     }
 
-    flexarray_append_pair(qmp_args, "id",
-                          GCSPRINTF("xenusb-%d", usbctrl->devid));
+    libxl__qmp_param_add_string(gc, &qmp_args, "id",
+                                GCSPRINTF("xenusb-%d", usbctrl->devid));
 
-    return libxl__qmp_run_command_flexarray(gc, domid, "device_add", qmp_args);
+    return libxl__ev_qmp_send(gc, qmp, "device_add", qmp_args);
 }
 
 /* Send qmp commands to delete a usb controller in qemu.  */
@@ -430,6 +433,13 @@ static int libxl__device_usbdev_del_hvm(libxl__gc *gc, uint32_t domid,
 
 static LIBXL_DEFINE_UPDATE_DEVID(usbctrl)
 
+static void device_usbctrl_add_timeout(libxl__egc *egc,
+    libxl__ev_time *ev, const struct timeval *requested_abs, int rc);
+static void device_usbctrl_add_qmp_cb(libxl__egc *egc,
+    libxl__ev_qmp *qmp, const libxl__json_object *r, int rc);
+static void device_usbctrl_add_done(libxl__egc *egc,
+    libxl__ao_device *aodev, int rc);
+
 /* AO operation to add a usb controller.
  *
  * Generally, it does:
@@ -450,6 +460,10 @@ static void libxl__device_usbctrl_add(libxl__egc *egc, uint32_t domid,
     libxl__device *device;
     int rc;
 
+    /* Store *usbctrl to be used by callbacks */
+    aodev->device_config = usbctrl;
+    aodev->device_type = &libxl__usbctrl_devtype;
+
     rc = libxl__device_usbctrl_setdefault(gc, domid, usbctrl,
                                           aodev->update_json);
     if (rc < 0) goto out;
@@ -464,14 +478,25 @@ static void libxl__device_usbctrl_add(libxl__egc *egc, uint32_t domid,
     GCNEW(device);
     rc = libxl__device_from_usbctrl(gc, domid, usbctrl, device);
     if (rc) goto outrm;
+    aodev->dev = device;
 
     if (device->backend_kind == LIBXL__DEVICE_KIND_NONE) {
-        rc = libxl__device_usbctrl_add_hvm(gc, domid, usbctrl);
+        libxl__ev_qmp *const qmp = &aodev->qmp;
+
+        rc = libxl__ev_time_register_rel(ao, &aodev->timeout,
+                                         device_usbctrl_add_timeout,
+                                         LIBXL_QMP_CMD_TIMEOUT * 1000);
         if (rc) goto outrm;
-        goto out;
+
+        qmp->ao = ao;
+        qmp->domid = domid;
+        qmp->payload_fd = -1;
+        qmp->callback = device_usbctrl_add_qmp_cb;
+        rc = libxl__device_usbctrl_add_hvm(gc, qmp, usbctrl);
+        if (rc) goto outrm;
+        return;
     }
 
-    aodev->dev = device;
     aodev->action = LIBXL__DEVICE_ACTION_ADD;
     libxl__wait_device_connection(egc, aodev);
     return;
@@ -479,9 +504,45 @@ static void libxl__device_usbctrl_add(libxl__egc *egc, uint32_t domid,
 outrm:
     libxl__device_usbctrl_del_xenstore(gc, domid, usbctrl);
 out:
+    device_usbctrl_add_done(egc, aodev, rc);
+}
+
+static void device_usbctrl_add_timeout(libxl__egc *egc, libxl__ev_time *ev,
+                                       const struct timeval *requested_abs,
+                                       int rc)
+{
+    EGC_GC;
+    libxl__ao_device *aodev = CONTAINER_OF(ev, *aodev, timeout);
+
+    if (rc == ERROR_TIMEDOUT)
+        LOGD(ERROR, aodev->dev->domid, "Adding usbctrl to QEMU timed out");
+    device_usbctrl_add_qmp_cb(egc, &aodev->qmp, NULL, rc);
+}
+
+static void device_usbctrl_add_qmp_cb(libxl__egc *egc,
+                                      libxl__ev_qmp *qmp,
+                                      const libxl__json_object *r,
+                                      int rc)
+{
+    EGC_GC;
+    libxl__ao_device *aodev = CONTAINER_OF(qmp, *aodev, qmp);
+    libxl_device_usbctrl *const usbctrl = aodev->device_config;
+
+    if (rc)
+        libxl__device_usbctrl_del_xenstore(gc, aodev->dev->domid, usbctrl);
+
+    device_usbctrl_add_done(egc, aodev, rc);
+}
+
+static void device_usbctrl_add_done(libxl__egc *egc,
+                                    libxl__ao_device *aodev,
+                                    int rc)
+{
+    EGC_GC;
+    libxl__ev_qmp_dispose(gc, &aodev->qmp);
+    libxl__ev_time_deregister(gc, &aodev->timeout);
     aodev->rc = rc;
     aodev->callback(egc, aodev);
-    return;
 }
 
 LIBXL_DEFINE_DEVICE_ADD(usbctrl)
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 20/35] libxl_usb: Make libxl__initiate_device_usbctrl_remove uses ev_qmp
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (18 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 19/35] libxl_usb: Make libxl__device_usbctrl_add uses ev_qmp Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 21/35] libxl_usb: Make libxl__device_usbdev_add " Anthony PERARD
                   ` (15 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_usb.c | 97 +++++++++++++++++++++++++++++++++--------
 1 file changed, 79 insertions(+), 18 deletions(-)

diff --git a/tools/libxl/libxl_usb.c b/tools/libxl/libxl_usb.c
index 506dbdcf5ee4..373b37d7159a 100644
--- a/tools/libxl/libxl_usb.c
+++ b/tools/libxl/libxl_usb.c
@@ -382,15 +382,16 @@ static int libxl__device_usbctrl_add_hvm(libxl__gc *gc, libxl__ev_qmp *qmp,
 }
 
 /* Send qmp commands to delete a usb controller in qemu.  */
-static int libxl__device_usbctrl_del_hvm(libxl__gc *gc, uint32_t domid,
+static int libxl__device_usbctrl_del_hvm(libxl__gc *gc,
+                                         libxl__ev_qmp *qmp,
                                          int devid)
 {
-    flexarray_t *qmp_args;
+    libxl__json_object *qmp_args = NULL;
 
-    qmp_args = flexarray_make(gc, 2, 1);
-    flexarray_append_pair(qmp_args, "id", GCSPRINTF("xenusb-%d", devid));
+    libxl__qmp_param_add_string(gc, &qmp_args,
+                                "id", GCSPRINTF("xenusb-%d", devid));
 
-    return libxl__qmp_run_command_flexarray(gc, domid, "device_del", qmp_args);
+    return libxl__ev_qmp_send(gc, qmp, "device_del", qmp_args);
 }
 
 /* Send qmp commands to create a usb device in qemu. */
@@ -557,6 +558,13 @@ static int libxl__device_usbdev_list_for_usbctrl(libxl__gc *gc, uint32_t domid,
 static int libxl__device_usbdev_remove(libxl__gc *gc, uint32_t domid,
                                        libxl_device_usbdev *usbdev);
 
+static void device_usbctrl_remove_timeout(libxl__egc *egc,
+    libxl__ev_time *ev, const struct timeval *requested_abs, int rc);
+static void device_usbctrl_remove_qmp_cb(libxl__egc *egc,
+    libxl__ev_qmp *qmp, const libxl__json_object *resp, int rc);
+static void device_usbctrl_remove_done(libxl__egc *egc,
+    libxl__ao_device *, int rc);
+
 /* AO function to remove a usb controller.
  *
  * Generally, it does:
@@ -576,13 +584,18 @@ void libxl__initiate_device_usbctrl_remove(libxl__egc *egc,
     int i, rc;
     uint32_t domid = aodev->dev->domid;
     int usbctrl_devid = aodev->dev->devid;
-    libxl_device_usbctrl usbctrl;
+    libxl_device_usbctrl *usbctrl;
 
-    libxl_device_usbctrl_init(&usbctrl);
+    GCNEW(usbctrl);
+    libxl_device_usbctrl_init(usbctrl);
     rc = libxl_devid_to_device_usbctrl(CTX, domid, usbctrl_devid,
-                                       &usbctrl);
+                                       usbctrl);
     if (rc) goto out;
 
+    /* Store *usbctrl to be used by callbacks */
+    aodev->device_config = usbctrl;
+    aodev->device_type = &libxl__usbctrl_devtype;
+
     /* Remove usb devices first */
     rc = libxl__device_usbdev_list_for_usbctrl(gc, domid, usbctrl_devid,
                                                &usbdevs, &num_usbdev);
@@ -597,24 +610,72 @@ void libxl__initiate_device_usbctrl_remove(libxl__egc *egc,
         }
     }
 
-    if (usbctrl.type == LIBXL_USBCTRL_TYPE_DEVICEMODEL) {
-        rc = libxl__device_usbctrl_del_hvm(gc, domid, usbctrl_devid);
-        if (!rc)
-            libxl__device_usbctrl_del_xenstore(gc, domid, &usbctrl);
-        goto out;
+    if (usbctrl->type == LIBXL_USBCTRL_TYPE_DEVICEMODEL) {
+        libxl__ev_qmp *const qmp = &aodev->qmp;
+
+        rc = libxl__ev_time_register_rel(ao, &aodev->timeout,
+                                         device_usbctrl_remove_timeout,
+                                         LIBXL_QMP_CMD_TIMEOUT * 1000);
+        if (rc) goto out;
+
+        qmp->ao = ao;
+        qmp->domid = domid;
+        qmp->callback = device_usbctrl_remove_qmp_cb;
+        qmp->payload_fd = -1;
+        rc = libxl__device_usbctrl_del_hvm(gc, qmp, usbctrl_devid);
+        if (rc) goto out;
+        return;
     }
 
-    libxl_device_usbctrl_dispose(&usbctrl);
+    libxl_device_usbctrl_dispose(usbctrl);
 
     /* Remove usbctrl */
-    libxl__initiate_device_generic_remove(egc, aodev);
+    libxl__initiate_device_generic_remove(egc, aodev); /* must be last */
     return;
-
 out:
-    libxl_device_usbctrl_dispose(&usbctrl);
+    device_usbctrl_remove_done(egc, aodev, rc); /* must be last */
+}
+
+static void device_usbctrl_remove_timeout(libxl__egc *egc,
+    libxl__ev_time *ev, const struct timeval *requested_abs, int rc)
+{
+    EGC_GC;
+    libxl__ao_device *aodev = CONTAINER_OF(ev, *aodev, timeout);
+
+    if (rc == ERROR_TIMEDOUT)
+        LOGD(ERROR, aodev->dev->domid,
+             "Removing usbctrl from QEMU timed out");
+    device_usbctrl_remove_qmp_cb(egc, &aodev->qmp, NULL, rc);
+}
+
+static void device_usbctrl_remove_qmp_cb(libxl__egc *egc,
+                                         libxl__ev_qmp *qmp,
+                                         const libxl__json_object *resp,
+                                         int rc)
+{
+    EGC_GC;
+    libxl__ao_device *aodev = CONTAINER_OF(qmp, *aodev, qmp);
+    libxl_device_usbctrl *const usbctrl = aodev->device_config;
+
+    if (!rc)
+        libxl__device_usbctrl_del_xenstore(gc, aodev->dev->domid, usbctrl);
+
+    device_usbctrl_remove_done(egc, aodev, rc);
+}
+
+static void device_usbctrl_remove_done(libxl__egc *egc,
+                                       libxl__ao_device *aodev,
+                                       int rc)
+{
+    EGC_GC;
+    libxl_device_usbctrl *const usbctrl = aodev->device_config;
+
+    libxl_device_usbctrl_dispose(usbctrl);
+    libxl__ev_qmp_dispose(gc, &aodev->qmp);
+    libxl__ev_time_deregister(gc, &aodev->timeout);
+
     aodev->rc = rc;
     aodev->callback(egc, aodev);
-    return;
 }
 
 static int libxl__usbctrl_from_xenstore(libxl__gc *gc,
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 21/35] libxl_usb: Make libxl__device_usbdev_add uses ev_qmp
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (19 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 20/35] libxl_usb: Make libxl__initiate_device_usbctrl_remove " Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 22/35] libxl: Use aodev for libxl__device_usbdev_remove Anthony PERARD
                   ` (14 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_usb.c | 99 +++++++++++++++++++++++++++++++++--------
 1 file changed, 81 insertions(+), 18 deletions(-)

diff --git a/tools/libxl/libxl_usb.c b/tools/libxl/libxl_usb.c
index 373b37d7159a..b9a31f96ebe3 100644
--- a/tools/libxl/libxl_usb.c
+++ b/tools/libxl/libxl_usb.c
@@ -395,26 +395,25 @@ static int libxl__device_usbctrl_del_hvm(libxl__gc *gc,
 }
 
 /* Send qmp commands to create a usb device in qemu. */
-static int libxl__device_usbdev_add_hvm(libxl__gc *gc, uint32_t domid,
+static int libxl__device_usbdev_add_hvm(libxl__gc *gc, libxl__ev_qmp *qmp,
                                         libxl_device_usbdev *usbdev)
 {
-    flexarray_t *qmp_args;
+    libxl__json_object *qmp_args = NULL;
 
-    qmp_args = flexarray_make(gc, 12, 1);
-    flexarray_append_pair(qmp_args, "id",
-                          GCSPRINTF("xenusb-%d-%d",
-                                    usbdev->u.hostdev.hostbus,
-                                    usbdev->u.hostdev.hostaddr));
-    flexarray_append_pair(qmp_args, "driver", "usb-host");
-    flexarray_append_pair(qmp_args, "bus",
-                          GCSPRINTF("xenusb-%d.0", usbdev->ctrl));
-    flexarray_append_pair(qmp_args, "port", GCSPRINTF("%d", usbdev->port));
-    flexarray_append_pair(qmp_args, "hostbus",
-                          GCSPRINTF("%d", usbdev->u.hostdev.hostbus));
-    flexarray_append_pair(qmp_args, "hostaddr",
-                          GCSPRINTF("%d", usbdev->u.hostdev.hostaddr));
-
-    return libxl__qmp_run_command_flexarray(gc, domid, "device_add", qmp_args);
+    libxl__qmp_param_add_string(gc, &qmp_args, "id",
+        GCSPRINTF("xenusb-%d-%d", usbdev->u.hostdev.hostbus,
+                  usbdev->u.hostdev.hostaddr));
+    libxl__qmp_param_add_string(gc, &qmp_args, "driver", "usb-host");
+    libxl__qmp_param_add_string(gc, &qmp_args, "bus",
+        GCSPRINTF("xenusb-%d.0", usbdev->ctrl));
+    libxl__qmp_param_add_string(gc, &qmp_args, "port",
+        GCSPRINTF("%d", usbdev->port));
+    libxl__qmp_param_add_string(gc, &qmp_args, "hostbus",
+        GCSPRINTF("%d", usbdev->u.hostdev.hostbus));
+    libxl__qmp_param_add_string(gc, &qmp_args, "hostaddr",
+        GCSPRINTF("%d", usbdev->u.hostdev.hostaddr));
+
+    return libxl__ev_qmp_send(gc, qmp, "device_add", qmp_args);
 }
 
 /* Send qmp commands to delete a usb device in qemu. */
@@ -1639,6 +1638,13 @@ static int usbback_dev_assign(libxl__gc *gc, const char *busid)
     return rc;
 }
 
+static void device_usbdev_add_qmp_cb(libxl__egc *egc,
+    libxl__ev_qmp *qmp, const libxl__json_object *r, int rc);
+static void device_usbdev_add_timeout(libxl__egc *egc,
+    libxl__ev_time *ev, const struct timeval *requested_abs, int rc);
+static void device_usbdev_add_done(libxl__egc *egc,
+    libxl__ao_device *aodev, int rc);
+
 /* AO operation to add a usb device.
  *
  * Generally, it does:
@@ -1665,9 +1671,14 @@ static void libxl__device_usbdev_add(libxl__egc *egc, uint32_t domid,
     int num_assigned;
     libxl_device_usbctrl usbctrl;
     char *busid;
+    bool has_callback = false;
 
     libxl_device_usbctrl_init(&usbctrl);
 
+    /* Store *usbdev to be used by callbacks */
+    aodev->device_config = usbdev;
+    aodev->device_type = &libxl__usbdev_devtype;
+
     /* Currently only support adding USB device from Dom0 backend.
      * So, if USB controller is specified, check its backend domain,
      * if it's not Dom0, report error.
@@ -1751,12 +1762,22 @@ static void libxl__device_usbdev_add(libxl__egc *egc, uint32_t domid,
                                                aodev->update_json);
         if (rc) goto out;
 
-        rc = libxl__device_usbdev_add_hvm(gc, domid, usbdev);
+        rc = libxl__ev_time_register_rel(ao, &aodev->timeout,
+                                         device_usbdev_add_timeout,
+                                         LIBXL_QMP_CMD_TIMEOUT * 1000);
+        if (rc) goto out;
+
+        aodev->qmp.ao = ao;
+        aodev->qmp.domid = domid;
+        aodev->qmp.callback = device_usbdev_add_qmp_cb;
+        aodev->qmp.payload_fd = -1;
+        rc = libxl__device_usbdev_add_hvm(gc, &aodev->qmp, usbdev);
         if (rc) {
             libxl__device_usbdev_remove_xenstore(gc, domid, usbdev,
                                              LIBXL_USBCTRL_TYPE_DEVICEMODEL);
             goto out;
         }
+        has_callback = true;
         break;
     default:
         LOGD(ERROR, domid, "Unsupported usb controller type");
@@ -1768,6 +1789,48 @@ static void libxl__device_usbdev_add(libxl__egc *egc, uint32_t domid,
 
 out:
     libxl_device_usbctrl_dispose(&usbctrl);
+    /* Only call _done if no callback have been setup */
+    if (!has_callback)
+        device_usbdev_add_done(egc, aodev, rc); /* must be last */
+}
+
+static void device_usbdev_add_timeout(libxl__egc *egc,
+                                      libxl__ev_time *ev,
+                                      const struct timeval *requested_abs,
+                                      int rc)
+{
+    EGC_GC;
+    libxl__ao_device *aodev = CONTAINER_OF(ev, *aodev, timeout);
+
+    if (rc == ERROR_TIMEDOUT)
+        LOGD(ERROR, aodev->qmp.domid,
+             "Adding usbdev to QEMU timed out");
+    device_usbdev_add_qmp_cb(egc, &aodev->qmp, NULL, rc);
+}
+
+static void device_usbdev_add_qmp_cb(libxl__egc *egc,
+                                     libxl__ev_qmp *qmp,
+                                     const libxl__json_object *r,
+                                     int rc)
+{
+    EGC_GC;
+    libxl__ao_device *aodev = CONTAINER_OF(qmp, *aodev, qmp);
+    libxl_device_usbdev *const usbdev = aodev->device_config;
+
+    if (rc)
+        libxl__device_usbdev_remove_xenstore(gc, qmp->domid,
+            usbdev, LIBXL_USBCTRL_TYPE_DEVICEMODEL);
+    device_usbdev_add_done(egc, aodev, rc); /* must be last */
+}
+
+static void device_usbdev_add_done(libxl__egc *egc,
+                                   libxl__ao_device *aodev,
+                                   int rc)
+{
+    EGC_GC;
+
+    libxl__ev_time_deregister(gc, &aodev->timeout);
+    libxl__ev_qmp_dispose(gc, &aodev->qmp);
     aodev->rc = rc;
     aodev->callback(egc, aodev);
 }
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 22/35] libxl: Use aodev for libxl__device_usbdev_remove
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (20 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 21/35] libxl_usb: Make libxl__device_usbdev_add " Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 23/35] libxl: libxl__initiate_device_usbdev_remove now use ev_qmp Anthony PERARD
                   ` (13 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

This also mean libxl__initiate_device_usbctrl_remove, which uses
libxl__device_usbdev_remove synchronously, needs to be updated to use
it with multidev.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_usb.c | 79 +++++++++++++++++++++++++++++++----------
 1 file changed, 61 insertions(+), 18 deletions(-)

diff --git a/tools/libxl/libxl_usb.c b/tools/libxl/libxl_usb.c
index b9a31f96ebe3..3b432231ea85 100644
--- a/tools/libxl/libxl_usb.c
+++ b/tools/libxl/libxl_usb.c
@@ -554,9 +554,11 @@ static int libxl__device_usbdev_list_for_usbctrl(libxl__gc *gc, uint32_t domid,
                                                  libxl_device_usbdev **usbdevs,
                                                  int *num);
 
-static int libxl__device_usbdev_remove(libxl__gc *gc, uint32_t domid,
-                                       libxl_device_usbdev *usbdev);
+static void libxl__device_usbdev_remove(libxl__egc *egc,
+    uint32_t domid, libxl_device_usbdev *usbdev, libxl__ao_device *aodev);
 
+static void device_usbctrl_usbdevs_removed(libxl__egc *,
+    libxl__multidev *, int rc);
 static void device_usbctrl_remove_timeout(libxl__egc *egc,
     libxl__ev_time *ev, const struct timeval *requested_abs, int rc);
 static void device_usbctrl_remove_qmp_cb(libxl__egc *egc,
@@ -564,6 +566,11 @@ static void device_usbctrl_remove_qmp_cb(libxl__egc *egc,
 static void device_usbctrl_remove_done(libxl__egc *egc,
     libxl__ao_device *, int rc);
 
+typedef struct {
+    libxl__multidev multidev;
+    libxl__ao_device *aodev;
+} usbctrl_remove_state;
+
 /* AO function to remove a usb controller.
  *
  * Generally, it does:
@@ -584,6 +591,12 @@ void libxl__initiate_device_usbctrl_remove(libxl__egc *egc,
     uint32_t domid = aodev->dev->domid;
     int usbctrl_devid = aodev->dev->devid;
     libxl_device_usbctrl *usbctrl;
+    usbctrl_remove_state *ucrs;
+
+    GCNEW(ucrs);
+    ucrs->aodev = aodev;
+    ucrs->multidev.callback = device_usbctrl_usbdevs_removed;
+    libxl__multidev_begin(ao, &ucrs->multidev);
 
     GCNEW(usbctrl);
     libxl_device_usbctrl_init(usbctrl);
@@ -601,14 +614,29 @@ void libxl__initiate_device_usbctrl_remove(libxl__egc *egc,
     if (rc) goto out;
 
     for (i = 0; i < num_usbdev; i++) {
-        rc = libxl__device_usbdev_remove(gc, domid, &usbdevs[i]);
-        if (rc) {
-            LOGD(ERROR, domid, "libxl__device_usbdev_remove failed: controller %d, "
-                "port %d", usbdevs[i].ctrl, usbdevs[i].port);
-            goto out;
-        }
+        libxl__ao_device *usbdev_aodev =
+            libxl__multidev_prepare(&ucrs->multidev);
+        usbdev_aodev->action = LIBXL__DEVICE_ACTION_REMOVE;
+        libxl__device_usbdev_remove(egc, domid, &usbdevs[i], usbdev_aodev);
     }
 
+out:
+    libxl__multidev_prepared(egc, &ucrs->multidev, rc); /* must be last */
+}
+
+static void device_usbctrl_usbdevs_removed(libxl__egc *egc,
+                                           libxl__multidev *multidev,
+                                           int rc)
+{
+    usbctrl_remove_state *ucrs =
+        CONTAINER_OF(multidev, *ucrs, multidev);
+    libxl__ao_device *aodev = ucrs->aodev;
+    STATE_AO_GC(aodev->ao);
+    libxl_device_usbctrl *const usbctrl = aodev->device_config;
+
+    if (rc) goto out;
+
+    /* Remove usbctrl */
     if (usbctrl->type == LIBXL_USBCTRL_TYPE_DEVICEMODEL) {
         libxl__ev_qmp *const qmp = &aodev->qmp;
 
@@ -618,10 +646,10 @@ void libxl__initiate_device_usbctrl_remove(libxl__egc *egc,
         if (rc) goto out;
 
         qmp->ao = ao;
-        qmp->domid = domid;
+        qmp->domid = aodev->dev->domid;
         qmp->callback = device_usbctrl_remove_qmp_cb;
         qmp->payload_fd = -1;
-        rc = libxl__device_usbctrl_del_hvm(gc, qmp, usbctrl_devid);
+        rc = libxl__device_usbctrl_del_hvm(gc, qmp, aodev->dev->devid);
         if (rc) goto out;
         return;
     }
@@ -1845,20 +1873,31 @@ static LIBXL_DEFINE_DEVICES_ADD(usbdev)
  * 2) remove the usb device from xenstore controller/port.
  * 3) unbind usb device from usbback and rebind to its original driver.
  *    If usb device has many interfaces, do it to each interface.
+ *
+ * Before calling this function, aodev should be properly filled:
+ * aodev->ao, aodev->callback, ...
  */
-static int libxl__device_usbdev_remove(libxl__gc *gc, uint32_t domid,
-                                       libxl_device_usbdev *usbdev)
+static void libxl__device_usbdev_remove(libxl__egc *egc, uint32_t domid,
+                                        libxl_device_usbdev *usbdev,
+                                        libxl__ao_device *aodev)
 {
+    STATE_AO_GC(aodev->ao);
     int rc;
     char *busid;
     libxl_device_usbctrl usbctrl;
 
+    /* Store *usbdev to be used by callbacks */
+    aodev->device_config = usbdev;
+    aodev->device_type = &libxl__usbdev_devtype;
+
+    libxl_device_usbctrl_init(&usbctrl);
+
     if (usbdev->ctrl < 0 || usbdev->port < 1) {
         LOGD(ERROR, domid, "Invalid USB device");
-        return ERROR_FAIL;
+        rc = ERROR_FAIL;
+        goto out;
     }
 
-    libxl_device_usbctrl_init(&usbctrl);
     rc = libxl_devid_to_device_usbctrl(CTX, domid, usbdev->ctrl, &usbctrl);
     if (rc) goto out;
 
@@ -1944,7 +1983,8 @@ static int libxl__device_usbdev_remove(libxl__gc *gc, uint32_t domid,
 
 out:
     libxl_device_usbctrl_dispose(&usbctrl);
-    return rc;
+    aodev->rc = rc;
+    aodev->callback(egc, aodev);
 }
 
 int libxl_device_usbdev_remove(libxl_ctx *ctx, uint32_t domid,
@@ -1953,11 +1993,14 @@ int libxl_device_usbdev_remove(libxl_ctx *ctx, uint32_t domid,
 
 {
     AO_CREATE(ctx, domid, ao_how);
-    int rc;
+    libxl__ao_device *aodev;
 
-    rc = libxl__device_usbdev_remove(gc, domid, usbdev);
+    GCNEW(aodev);
+    libxl__prepare_ao_device(ao, aodev);
+    aodev->action = LIBXL__DEVICE_ACTION_REMOVE;
+    aodev->callback = device_addrm_aocomplete;
+    libxl__device_usbdev_remove(egc, domid, usbdev, aodev);
 
-    libxl__ao_complete(egc, ao, rc);
     return AO_INPROGRESS;
 }
 
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 23/35] libxl: libxl__initiate_device_usbdev_remove now use ev_qmp
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (21 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 22/35] libxl: Use aodev for libxl__device_usbdev_remove Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 24/35] libxl: Remove libxl__qmp_run_command_flexarray Anthony PERARD
                   ` (12 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_usb.c | 78 +++++++++++++++++++++++++++++++++++------
 1 file changed, 68 insertions(+), 10 deletions(-)

diff --git a/tools/libxl/libxl_usb.c b/tools/libxl/libxl_usb.c
index 3b432231ea85..1fc7ccf41f86 100644
--- a/tools/libxl/libxl_usb.c
+++ b/tools/libxl/libxl_usb.c
@@ -417,18 +417,16 @@ static int libxl__device_usbdev_add_hvm(libxl__gc *gc, libxl__ev_qmp *qmp,
 }
 
 /* Send qmp commands to delete a usb device in qemu. */
-static int libxl__device_usbdev_del_hvm(libxl__gc *gc, uint32_t domid,
+static int libxl__device_usbdev_del_hvm(libxl__gc *gc, libxl__ev_qmp *qmp,
                                         libxl_device_usbdev *usbdev)
 {
-    flexarray_t *qmp_args;
+    libxl__json_object *qmp_args = NULL;
 
-    qmp_args = flexarray_make(gc, 2, 1);
-    flexarray_append_pair(qmp_args, "id",
-                          GCSPRINTF("xenusb-%d-%d",
-                                    usbdev->u.hostdev.hostbus,
-                                    usbdev->u.hostdev.hostaddr));
+    libxl__qmp_param_add_string(gc, &qmp_args, "id",
+        GCSPRINTF("xenusb-%d-%d", usbdev->u.hostdev.hostbus,
+                  usbdev->u.hostdev.hostaddr));
 
-    return libxl__qmp_run_command_flexarray(gc, domid, "device_del", qmp_args);
+    return libxl__ev_qmp_send(gc, qmp, "device_del", qmp_args);
 }
 
 static LIBXL_DEFINE_UPDATE_DEVID(usbctrl)
@@ -1866,6 +1864,13 @@ static void device_usbdev_add_done(libxl__egc *egc,
 LIBXL_DEFINE_DEVICE_ADD(usbdev)
 static LIBXL_DEFINE_DEVICES_ADD(usbdev)
 
+static void device_usbdev_remove_timeout(libxl__egc *egc,
+    libxl__ev_time *ev, const struct timeval *requested_abs, int rc);
+static void device_usbdev_remove_qmp_cb(libxl__egc *egc,
+    libxl__ev_qmp *qmp, const libxl__json_object *r, int rc);
+static void device_usbdev_remove_done(libxl__egc *egc,
+    libxl__ao_device *aodev, int rc);
+
 /* Operation to remove usb device.
  *
  * Generally, it does:
@@ -1885,6 +1890,7 @@ static void libxl__device_usbdev_remove(libxl__egc *egc, uint32_t domid,
     int rc;
     char *busid;
     libxl_device_usbctrl usbctrl;
+    bool has_callback = false;
 
     /* Store *usbdev to be used by callbacks */
     aodev->device_config = usbdev;
@@ -1964,14 +1970,23 @@ static void libxl__device_usbdev_remove(libxl__egc *egc, uint32_t domid,
                                               LIBXL_USBCTRL_TYPE_DEVICEMODEL);
         if (rc) goto out;
 
-        rc = libxl__device_usbdev_del_hvm(gc, domid, usbdev);
+        rc = libxl__ev_time_register_rel(ao, &aodev->timeout,
+                                         device_usbdev_remove_timeout,
+                                         LIBXL_QMP_CMD_TIMEOUT * 1000);
+        if (rc) goto out;
+
+        aodev->qmp.ao = ao;
+        aodev->qmp.domid = domid;
+        aodev->qmp.callback = device_usbdev_remove_qmp_cb;
+        aodev->qmp.payload_fd = -1;
+        rc = libxl__device_usbdev_del_hvm(gc, &aodev->qmp, usbdev);
         if (rc) {
             libxl__device_usbdev_add_xenstore(gc, domid, usbdev,
                                               LIBXL_USBCTRL_TYPE_DEVICEMODEL,
                                               false);
             goto out;
         }
-
+        has_callback = true;
         break;
     default:
         LOGD(ERROR, domid, "Unsupported usb controller type");
@@ -1983,6 +1998,49 @@ static void libxl__device_usbdev_remove(libxl__egc *egc, uint32_t domid,
 
 out:
     libxl_device_usbctrl_dispose(&usbctrl);
+    /* Only call _done if no callback have been setup */
+    if (!has_callback)
+        device_usbdev_remove_done(egc, aodev, rc); /* must be last */
+}
+
+static void device_usbdev_remove_timeout(libxl__egc *egc,
+    libxl__ev_time *ev, const struct timeval *requested_abs, int rc)
+{
+    EGC_GC;
+    libxl__ao_device *aodev = CONTAINER_OF(ev, *aodev, timeout);
+
+    if (rc == ERROR_TIMEDOUT)
+        LOGD(ERROR, aodev->qmp.domid,
+             "Removing usbdev from QEMU timed out");
+    device_usbdev_remove_qmp_cb(egc, &aodev->qmp, NULL, rc);
+}
+
+static void device_usbdev_remove_qmp_cb(libxl__egc *egc,
+                                        libxl__ev_qmp *qmp,
+                                        const libxl__json_object *r,
+                                        int rc)
+{
+    EGC_GC;
+    libxl__ao_device *aodev = CONTAINER_OF(qmp, *aodev, qmp);
+    libxl_device_usbdev *const usbdev = aodev->device_config;
+
+    if (rc) {
+        libxl__device_usbdev_add_xenstore(gc, qmp->domid, usbdev,
+                                          LIBXL_USBCTRL_TYPE_DEVICEMODEL,
+                                          false);
+    }
+
+    device_usbdev_remove_done(egc, aodev, rc); /* must be last */
+}
+
+static void device_usbdev_remove_done(libxl__egc *egc,
+                                      libxl__ao_device *aodev,
+                                      int rc)
+{
+    EGC_GC;
+
+    libxl__ev_time_deregister(gc, &aodev->timeout);
+    libxl__ev_qmp_dispose(gc, &aodev->qmp);
     aodev->rc = rc;
     aodev->callback(egc, aodev);
 }
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 24/35] libxl: Remove libxl__qmp_run_command_flexarray
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (22 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 23/35] libxl: libxl__initiate_device_usbdev_remove now use ev_qmp Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 25/35] libxl_pci: Coding style of do_pci_add Anthony PERARD
                   ` (11 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

There are no more users.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_internal.h |  3 ---
 tools/libxl/libxl_qmp.c      | 16 ----------------
 2 files changed, 19 deletions(-)

diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 6c09b93f91f1..571301a5d5d8 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1980,9 +1980,6 @@ typedef struct libxl__qmp_handler libxl__qmp_handler;
  */
 _hidden libxl__qmp_handler *libxl__qmp_initialize(libxl__gc *gc,
                                                   uint32_t domid);
-_hidden int libxl__qmp_run_command_flexarray(libxl__gc *gc, int domid,
-                                             const char *cmd,
-                                             flexarray_t *array);
 _hidden int libxl__qmp_pci_add(libxl__gc *gc, int d, libxl_device_pci *pcidev);
 _hidden int libxl__qmp_pci_del(libxl__gc *gc, int domid,
                                libxl_device_pci *pcidev);
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index 0d6aedcc7d3c..c78ef4637d0a 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -833,22 +833,6 @@ static int qmp_run_command(libxl__gc *gc, int domid,
     return rc;
 }
 
-int libxl__qmp_run_command_flexarray(libxl__gc *gc, int domid,
-                                     const char *cmd, flexarray_t *array)
-{
-    libxl__json_object *args = NULL;
-    int i;
-    void *name, *value;
-
-    for (i = 0; i < array->count; i += 2) {
-        flexarray_get(array, i, &name);
-        flexarray_get(array, i + 1, &value);
-        libxl__qmp_param_add_string(gc, &args, (char *)name, (char *)value);
-    }
-
-    return qmp_run_command(gc, domid, cmd, args, NULL, NULL);
-}
-
 int libxl__qmp_pci_add(libxl__gc *gc, int domid, libxl_device_pci *pcidev)
 {
     libxl__qmp_handler *qmp = NULL;
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 25/35] libxl_pci: Coding style of do_pci_add
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (23 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 24/35] libxl: Remove libxl__qmp_run_command_flexarray Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 26/35] libxl_pci: Only check if qemu-dm is running in qemu-trad case Anthony PERARD
                   ` (10 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

do_pci_add is going to be asynchronous, so we start by having a single
path out of the function. All `return`s instead set rc and goto out.

While here, some use of `rc' was used to store the return value of
libxc calls, change them to store into `r'. Also, add the value of `r'
in the error message of those calls.

There were an `out' label that was use it seems to skip setting up the
IRQ, the label has been renamed to `out_no_irq'.

No functional changes.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_pci.c | 79 ++++++++++++++++++++++++-----------------
 1 file changed, 46 insertions(+), 33 deletions(-)

diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c
index 4b1aed1895cc..b9ca69f5f0b3 100644
--- a/tools/libxl/libxl_pci.c
+++ b/tools/libxl/libxl_pci.c
@@ -995,15 +995,19 @@ static int do_pci_add(libxl__gc *gc, uint32_t domid,
     uint32_t flag = XEN_DOMCTL_DEV_RDM_RELAXED;
     uint32_t domainid = domid;
     bool isstubdom = libxl_is_stubdom(ctx, domid, &domainid);
+    int r;
 
-    if (type == LIBXL_DOMAIN_TYPE_INVALID)
-        return ERROR_FAIL;
+    if (type == LIBXL_DOMAIN_TYPE_INVALID) {
+        rc = ERROR_FAIL;
+        goto out;
+    }
 
     if (type == LIBXL_DOMAIN_TYPE_HVM) {
         hvm = 1;
         if (libxl__wait_for_device_model_deprecated(gc, domid, "running",
                                          NULL, NULL, NULL) < 0) {
-            return ERROR_FAIL;
+            rc = ERROR_FAIL;
+            goto out;
         }
         switch (libxl__device_model_version_running(gc, domid)) {
             case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL:
@@ -1013,10 +1017,10 @@ static int do_pci_add(libxl__gc *gc, uint32_t domid,
                 rc = libxl__qmp_pci_add(gc, domid, pcidev);
                 break;
             default:
-                return ERROR_INVAL;
+                rc = ERROR_INVAL;
         }
         if ( rc )
-            return ERROR_FAIL;
+            goto out;
     }
 
     sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain,
@@ -1027,7 +1031,8 @@ static int do_pci_add(libxl__gc *gc, uint32_t domid,
 
     if (f == NULL) {
         LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path);
-        return ERROR_FAIL;
+        rc = ERROR_FAIL;
+        goto out;
     }
     for (i = 0; i < PROC_PCI_NUM_RESOURCES; i++) {
         if (fscanf(f, "0x%llx 0x%llx 0x%llx\n", &start, &end, &flags) != 3)
@@ -1035,25 +1040,25 @@ static int do_pci_add(libxl__gc *gc, uint32_t domid,
         size = end - start + 1;
         if (start) {
             if (flags & PCI_BAR_IO) {
-                rc = xc_domain_ioport_permission(ctx->xch, domid, start, size, 1);
-                if (rc < 0) {
+                r = xc_domain_ioport_permission(ctx->xch, domid, start, size, 1);
+                if (r < 0) {
                     LOGED(ERROR, domainid,
-                          "Error: xc_domain_ioport_permission error 0x%llx/0x%llx",
-                          start,
-                          size);
+                          "xc_domain_ioport_permission 0x%llx/0x%llx (error %d)",
+                          start, size, r);
                     fclose(f);
-                    return ERROR_FAIL;
+                    rc = ERROR_FAIL;
+                    goto out;
                 }
             } else {
-                rc = xc_domain_iomem_permission(ctx->xch, domid, start>>XC_PAGE_SHIFT,
+                r = xc_domain_iomem_permission(ctx->xch, domid, start>>XC_PAGE_SHIFT,
                                                 (size+(XC_PAGE_SIZE-1))>>XC_PAGE_SHIFT, 1);
-                if (rc < 0) {
+                if (r < 0) {
                     LOGED(ERROR, domainid,
-                          "Error: xc_domain_iomem_permission error 0x%llx/0x%llx",
-                          start,
-                          size);
+                          "xc_domain_iomem_permission 0x%llx/0x%llx (error %d)",
+                          start, size, r);
                     fclose(f);
-                    return ERROR_FAIL;
+                    rc = ERROR_FAIL;
+                    goto out;
                 }
             }
         }
@@ -1064,20 +1069,24 @@ static int do_pci_add(libxl__gc *gc, uint32_t domid,
     f = fopen(sysfs_path, "r");
     if (f == NULL) {
         LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path);
-        goto out;
+        goto out_no_irq;
     }
     if ((fscanf(f, "%u", &irq) == 1) && irq) {
-        rc = xc_physdev_map_pirq(ctx->xch, domid, irq, &irq);
-        if (rc < 0) {
-            LOGED(ERROR, domainid, "Error: xc_physdev_map_pirq irq=%d", irq);
+        r = xc_physdev_map_pirq(ctx->xch, domid, irq, &irq);
+        if (r < 0) {
+            LOGED(ERROR, domainid, "xc_physdev_map_pirq irq=%d (error=%d)",
+                  irq, r);
             fclose(f);
-            return ERROR_FAIL;
+            rc = ERROR_FAIL;
+            goto out;
         }
-        rc = xc_domain_irq_permission(ctx->xch, domid, irq, 1);
-        if (rc < 0) {
-            LOGED(ERROR, domainid, "Error: xc_domain_irq_permission irq=%d", irq);
+        r = xc_domain_irq_permission(ctx->xch, domid, irq, 1);
+        if (r < 0) {
+            LOGED(ERROR, domainid,
+                  "xc_domain_irq_permission irq=%d (error=%d)", irq, r);
             fclose(f);
-            return ERROR_FAIL;
+            rc = ERROR_FAIL;
+            goto out;
         }
     }
     fclose(f);
@@ -1087,22 +1096,25 @@ static int do_pci_add(libxl__gc *gc, uint32_t domid,
         if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/permissive",
                              pcidev) < 0 ) {
             LOGD(ERROR, domainid, "Setting permissive for device");
-            return ERROR_FAIL;
+            rc = ERROR_FAIL;
+            goto out;
         }
     }
 
-out:
+out_no_irq:
     if (!isstubdom) {
         if (pcidev->rdm_policy == LIBXL_RDM_RESERVE_POLICY_STRICT) {
             flag &= ~XEN_DOMCTL_DEV_RDM_RELAXED;
         } else if (pcidev->rdm_policy != LIBXL_RDM_RESERVE_POLICY_RELAXED) {
             LOGED(ERROR, domainid, "unknown rdm check flag.");
-            return ERROR_FAIL;
+            rc = ERROR_FAIL;
+            goto out;
         }
-        rc = xc_assign_device(ctx->xch, domid, pcidev_encode_bdf(pcidev), flag);
-        if (rc < 0 && (hvm || errno != ENOSYS)) {
+        r = xc_assign_device(ctx->xch, domid, pcidev_encode_bdf(pcidev), flag);
+        if (r < 0 && (hvm || errno != ENOSYS)) {
             LOGED(ERROR, domainid, "xc_assign_device failed");
-            return ERROR_FAIL;
+            rc = ERROR_FAIL;
+            goto out;
         }
     }
 
@@ -1110,6 +1122,7 @@ static int do_pci_add(libxl__gc *gc, uint32_t domid,
         rc = libxl__device_pci_add_xenstore(gc, domid, pcidev, starting);
     else
         rc = 0;
+out:
     return rc;
 }
 
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 26/35] libxl_pci: Only check if qemu-dm is running in qemu-trad case
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (24 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 25/35] libxl_pci: Coding style of do_pci_add Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 27/35] libxl_pci: Use libxl__ao_device with libxl__device_pci_add Anthony PERARD
                   ` (9 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

QEMU upstream (or qemu-xen) may not have set "running" state in
xenstore. "running" with QEMU doesn't mean that the binary is
running, it means that the emulation have started. When adding a
pci-passthrough device to QEMU, we do so via QMP, we have a direct
answer to whether QEMU is running or not, no need to check ahead.

Moving the check to do it only with qemu-trad makes upcoming changes
simpler.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_pci.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c
index b9ca69f5f0b3..071880b8556b 100644
--- a/tools/libxl/libxl_pci.c
+++ b/tools/libxl/libxl_pci.c
@@ -1004,13 +1004,13 @@ static int do_pci_add(libxl__gc *gc, uint32_t domid,
 
     if (type == LIBXL_DOMAIN_TYPE_HVM) {
         hvm = 1;
-        if (libxl__wait_for_device_model_deprecated(gc, domid, "running",
-                                         NULL, NULL, NULL) < 0) {
-            rc = ERROR_FAIL;
-            goto out;
-        }
         switch (libxl__device_model_version_running(gc, domid)) {
             case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL:
+                if (libxl__wait_for_device_model_deprecated(gc, domid,
+                        "running", NULL, NULL, NULL) < 0) {
+                    rc = ERROR_FAIL;
+                    goto out;
+                }
                 rc = qemu_pci_add_xenstore(gc, domid, pcidev);
                 break;
             case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
@@ -1395,12 +1395,11 @@ static int do_pci_remove(libxl__gc *gc, uint32_t domid,
     rc = ERROR_FAIL;
     if (type == LIBXL_DOMAIN_TYPE_HVM) {
         hvm = 1;
-        if (libxl__wait_for_device_model_deprecated(gc, domid, "running",
-                                         NULL, NULL, NULL) < 0)
-            goto out_fail;
-
         switch (libxl__device_model_version_running(gc, domid)) {
         case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL:
+            if (libxl__wait_for_device_model_deprecated(gc, domid,
+                    "running", NULL, NULL, NULL) < 0)
+                goto out_fail;
             rc = qemu_pci_remove_xenstore(gc, domid, pcidev, force);
             break;
         case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 27/35] libxl_pci: Use libxl__ao_device with libxl__device_pci_add
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (25 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 26/35] libxl_pci: Only check if qemu-dm is running in qemu-trad case Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 28/35] libxl_pci: Use ev_qmp in do_pci_add Anthony PERARD
                   ` (8 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_internal.h |   7 +-
 tools/libxl/libxl_pci.c      | 170 ++++++++++++++++++++++++++++++-----
 2 files changed, 150 insertions(+), 27 deletions(-)

diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 571301a5d5d8..18c665d3dbe2 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -198,6 +198,7 @@ typedef struct libxl__json_object libxl__json_object;
 typedef struct libxl__carefd libxl__carefd;
 typedef struct libxl__ev_devlock libxl__ev_devlock;
 typedef struct libxl__dm_resume_state libxl__dm_resume_state;
+typedef struct libxl__ao_device libxl__ao_device;
 
 typedef struct libxl__domain_create_state libxl__domain_create_state;
 typedef void libxl__domain_create_cb(struct libxl__egc *egc,
@@ -1593,8 +1594,9 @@ _hidden int libxl__pci_topology_init(libxl__gc *gc,
 
 /* from libxl_pci */
 
-_hidden int libxl__device_pci_add(libxl__gc *gc, uint32_t domid,
-                                  libxl_device_pci *pcidev, bool starting);
+_hidden void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
+                                   libxl_device_pci *pcidev, bool starting,
+                                   libxl__ao_device *aodev);
 _hidden int libxl__device_pci_destroy_all(libxl__gc *gc, uint32_t domid);
 _hidden bool libxl__is_igd_vga_passthru(libxl__gc *gc,
                                         const libxl_domain_config *d_config);
@@ -2572,7 +2574,6 @@ _hidden void libxl__kill(libxl__gc *gc, pid_t pid, int sig, const char *what);
 
 /*----- device addition/removal -----*/
 
-typedef struct libxl__ao_device libxl__ao_device;
 typedef struct libxl__multidev libxl__multidev;
 typedef void libxl__device_callback(libxl__egc*, libxl__ao_device*);
 
diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c
index 071880b8556b..503db6c26043 100644
--- a/tools/libxl/libxl_pci.c
+++ b/tools/libxl/libxl_pci.c
@@ -983,9 +983,24 @@ static int qemu_pci_add_xenstore(libxl__gc *gc, uint32_t domid,
     return rc;
 }
 
-static int do_pci_add(libxl__gc *gc, uint32_t domid,
-                      libxl_device_pci *pcidev, bool starting)
+typedef struct pci_add_state {
+    /* filled by user of do_pci_add */
+    libxl__ao_device *aodev;
+    libxl_domid domid;
+    bool starting;
+    void (*callback)(libxl__egc *, struct pci_add_state *, int rc);
+
+    /* private to do_pci_add */
+    libxl_device_pci *pcidev;
+    int pci_domid;
+} pci_add_state;
+
+static void do_pci_add(libxl__egc *egc,
+                       libxl_domid domid,
+                       libxl_device_pci *pcidev,
+                       pci_add_state *pas)
 {
+    STATE_AO_GC(pas->aodev->ao);
     libxl_ctx *ctx = libxl__gc_owner(gc);
     libxl_domain_type type = libxl__domain_type(gc, domid);
     char *sysfs_path;
@@ -997,6 +1012,13 @@ static int do_pci_add(libxl__gc *gc, uint32_t domid,
     bool isstubdom = libxl_is_stubdom(ctx, domid, &domainid);
     int r;
 
+    /* Convenience aliases */
+    bool starting = pas->starting;
+
+    /* init pci_add_state */
+    pas->pcidev = pcidev;
+    pas->pci_domid = domid;
+
     if (type == LIBXL_DOMAIN_TYPE_INVALID) {
         rc = ERROR_FAIL;
         goto out;
@@ -1123,7 +1145,7 @@ static int do_pci_add(libxl__gc *gc, uint32_t domid,
     else
         rc = 0;
 out:
-    return rc;
+    pas->callback(egc, pas, rc);
 }
 
 static int libxl__device_pci_reset(libxl__gc *gc, unsigned int domain, unsigned int bus,
@@ -1177,9 +1199,14 @@ int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid,
                          const libxl_asyncop_how *ao_how)
 {
     AO_CREATE(ctx, domid, ao_how);
-    int rc;
-    rc = libxl__device_pci_add(gc, domid, pcidev, false);
-    libxl__ao_complete(egc, ao, rc);
+    libxl__ao_device *aodev;
+
+    GCNEW(aodev);
+    libxl__prepare_ao_device(ao, aodev);
+    aodev->action = LIBXL__DEVICE_ACTION_ADD;
+    aodev->callback = device_addrm_aocomplete;
+    aodev->update_json = true;
+    libxl__device_pci_add(egc, domid, pcidev, false, aodev);
     return AO_INPROGRESS;
 }
 
@@ -1200,14 +1227,31 @@ static int libxl_pcidev_assignable(libxl_ctx *ctx, libxl_device_pci *pcidev)
     return i != num;
 }
 
-int libxl__device_pci_add(libxl__gc *gc, uint32_t domid,
-                          libxl_device_pci *pcidev, bool starting)
+static void device_pci_add_stubdom_done(libxl__egc *egc,
+    pci_add_state *, int rc);
+static void device_pci_add_done(libxl__egc *egc,
+    pci_add_state *, int rc);
+
+void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
+                           libxl_device_pci *pcidev, bool starting,
+                           libxl__ao_device *aodev)
 {
+    STATE_AO_GC(aodev->ao);
     libxl_ctx *ctx = libxl__gc_owner(gc);
-    unsigned int orig_vdev, pfunc_mask;
     libxl_device_pci *assigned;
-    int num_assigned, i, rc;
+    int num_assigned, rc;
     int stubdomid = 0;
+    pci_add_state *pas;
+
+    /* Store *pcidev to be used by callbacks */
+    aodev->device_config = pcidev;
+    aodev->device_type = &libxl__pcidev_devtype;
+
+    GCNEW(pas);
+    pas->aodev = aodev;
+    pas->domid = domid;
+    pas->starting = starting;
+    pas->callback = device_pci_add_stubdom_done;
 
     if (libxl__domain_type(gc, domid) == LIBXL_DOMAIN_TYPE_HVM) {
         rc = xc_test_assign_device(ctx->xch, domid, pcidev_encode_bdf(pcidev));
@@ -1254,13 +1298,39 @@ int libxl__device_pci_add(libxl__gc *gc, uint32_t domid,
 
     stubdomid = libxl_get_stubdom_id(ctx, domid);
     if (stubdomid != 0) {
-        libxl_device_pci pcidev_s = *pcidev;
+        libxl_device_pci *pcidev_s;
+
+        GCNEW(pcidev_s);
+        libxl_device_pci_init(pcidev_s);
+        libxl_device_pci_copy(CTX, pcidev_s, pcidev);
         /* stubdomain is always running by now, even at create time */
-        rc = do_pci_add(gc, stubdomid, &pcidev_s, false);
-        if ( rc )
-            goto out;
+        pas->callback = device_pci_add_stubdom_done;
+        do_pci_add(egc, stubdomid, pcidev_s, pas); /* must be last */
+        return;
     }
 
+    device_pci_add_stubdom_done(egc, pas, 0); /* must be last */
+    return;
+
+out:
+    device_pci_add_done(egc, pas, rc); /* must be last */
+}
+
+static void device_pci_add_stubdom_done(libxl__egc *egc,
+                                        pci_add_state *pas,
+                                        int rc)
+{
+    STATE_AO_GC(pas->aodev->ao);
+    unsigned int orig_vdev, pfunc_mask;
+    int i;
+
+    /* Convenience aliases */
+    libxl__ao_device *aodev = pas->aodev;
+    libxl_domid domid = pas->domid;
+    libxl_device_pci *pcidev = aodev->device_config;
+
+    if (rc) goto out;
+
     orig_vdev = pcidev->vdevfn & ~7U;
 
     if ( pcidev->vfunc_mask == LIBXL_PCI_FUNC_ALL ) {
@@ -1291,31 +1361,83 @@ int libxl__device_pci_add(libxl__gc *gc, uint32_t domid,
                  */
                 pcidev->vdevfn = orig_vdev;
             }
-            if ( do_pci_add(gc, domid, pcidev, starting) )
-                rc = ERROR_FAIL;
+            pas->callback = device_pci_add_done;
+            do_pci_add(egc, domid, pcidev, pas); /* must be last */
+            return;
         }
     }
 
 out:
-    return rc;
+    device_pci_add_done(egc, pas, rc);
+}
+
+static void device_pci_add_done(libxl__egc *egc,
+                                pci_add_state *pas,
+                                int rc)
+{
+    EGC_GC;
+    libxl__ao_device *aodev = pas->aodev;
+    libxl_domid domid = pas->domid;
+    libxl_device_pci *pcidev = aodev->device_config;
+
+    if (rc) {
+        LOGD(ERROR, domid,
+             "libxl__device_pci_add  failed for "
+             "PCI device %x:%x:%x.%x (rc %d)",
+             pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func,
+             rc);
+    }
+    aodev->rc = rc;
+    aodev->callback(egc, aodev);
 }
 
+typedef struct {
+    libxl__multidev multidev;
+    libxl__ao_device *outer_aodev;
+    libxl_domain_config *d_config;
+    libxl_domid domid;
+} add_pcidevs_state;
+
+static void add_pcidevs_done(libxl__egc *, libxl__multidev *, int rc);
+
 static void libxl__add_pcidevs(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
                                libxl_domain_config *d_config,
                                libxl__multidev *multidev)
 {
     AO_GC;
-    libxl__ao_device *aodev = libxl__multidev_prepare(multidev);
-    int i, rc = 0;
+    add_pcidevs_state *apds;
+    int i;
+
+    /* We need to start a new multidev in order to be able to execute
+     * libxl__create_pci_backend only once. */
+
+    GCNEW(apds);
+    apds->outer_aodev = libxl__multidev_prepare(multidev);
+    apds->d_config = d_config;
+    apds->domid = domid;
+    apds->multidev.callback = add_pcidevs_done;
+    libxl__multidev_begin(ao, &apds->multidev);
 
     for (i = 0; i < d_config->num_pcidevs; i++) {
-        rc = libxl__device_pci_add(gc, domid, &d_config->pcidevs[i], true);
-        if (rc < 0) {
-            LOGD(ERROR, domid, "libxl_device_pci_add failed: %d", rc);
-            goto out;
-        }
+        libxl__ao_device *aodev = libxl__multidev_prepare(&apds->multidev);
+        libxl__device_pci_add(egc, domid, &d_config->pcidevs[i],
+                              true, aodev);
     }
 
+    libxl__multidev_prepared(egc, &apds->multidev, 0);
+}
+
+static void add_pcidevs_done(libxl__egc *egc, libxl__multidev *multidev,
+                             int rc)
+{
+    EGC_GC;
+    add_pcidevs_state *apds = CONTAINER_OF(multidev, *apds, multidev);
+
+    /* Convenience aliases */
+    libxl_domain_config *d_config = apds->d_config;
+    libxl_domid domid = apds->domid;
+    libxl__ao_device *aodev = apds->outer_aodev;
+
     if (d_config->num_pcidevs > 0) {
         rc = libxl__create_pci_backend(gc, domid, d_config->pcidevs,
             d_config->num_pcidevs);
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 28/35] libxl_pci: Use ev_qmp in do_pci_add
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (26 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 27/35] libxl_pci: Use libxl__ao_device with libxl__device_pci_add Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 29/35] libxl_pci: Use libxl__ao_device with pci_remove Anthony PERARD
                   ` (7 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

This patch also replaces the use of
libxl__wait_for_device_model_deprecated() by its equivalent
without the need for a thread.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_internal.h |   1 -
 tools/libxl/libxl_pci.c      | 288 ++++++++++++++++++++++++++++++++---
 tools/libxl/libxl_qmp.c      |  96 ------------
 3 files changed, 265 insertions(+), 120 deletions(-)

diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 18c665d3dbe2..d60b9c416abf 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1982,7 +1982,6 @@ typedef struct libxl__qmp_handler libxl__qmp_handler;
  */
 _hidden libxl__qmp_handler *libxl__qmp_initialize(libxl__gc *gc,
                                                   uint32_t domid);
-_hidden int libxl__qmp_pci_add(libxl__gc *gc, int d, libxl_device_pci *pcidev);
 _hidden int libxl__qmp_pci_del(libxl__gc *gc, int domid,
                                libxl_device_pci *pcidev);
 /* Resume hvm domain */
diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c
index 503db6c26043..3477f3aba605 100644
--- a/tools/libxl/libxl_pci.c
+++ b/tools/libxl/libxl_pci.c
@@ -23,6 +23,7 @@
 #define PCI_BDF_VDEVFN         "%04x:%02x:%02x.%01x@%02x"
 #define PCI_OPTIONS            "msitranslate=%d,power_mgmt=%d"
 #define PCI_BDF_XSPATH         "%04x-%02x-%02x-%01x"
+#define PCI_PT_QDEV_ID         "pci-pt-%02x_%02x.%01x"
 
 static unsigned int pcidev_encode_bdf(libxl_device_pci *pcidev)
 {
@@ -991,33 +992,40 @@ typedef struct pci_add_state {
     void (*callback)(libxl__egc *, struct pci_add_state *, int rc);
 
     /* private to do_pci_add */
+    libxl__xswait_state xswait;
+    libxl__ev_qmp qmp;
+    libxl__ev_time timeout;
     libxl_device_pci *pcidev;
     int pci_domid;
 } pci_add_state;
 
+static void pci_add_qemu_trad_watch_state_cb(libxl__egc *egc,
+    libxl__xswait_state *xswa, int rc, const char *state);
+static void pci_add_qmp_device_add(libxl__egc *, pci_add_state *);
+static void pci_add_qmp_device_add_cb(libxl__egc *,
+    libxl__ev_qmp *, const libxl__json_object *, int rc);
+static void pci_add_qmp_query_pci_cb(libxl__egc *,
+    libxl__ev_qmp *, const libxl__json_object *, int rc);
+static void pci_add_timeout(libxl__egc *egc, libxl__ev_time *ev,
+    const struct timeval *requested_abs, int rc);
+static void pci_add_dm_done(libxl__egc *,
+    pci_add_state *, int rc);
+
 static void do_pci_add(libxl__egc *egc,
                        libxl_domid domid,
                        libxl_device_pci *pcidev,
                        pci_add_state *pas)
 {
     STATE_AO_GC(pas->aodev->ao);
-    libxl_ctx *ctx = libxl__gc_owner(gc);
     libxl_domain_type type = libxl__domain_type(gc, domid);
-    char *sysfs_path;
-    FILE *f;
-    unsigned long long start, end, flags, size;
-    int irq, i, rc, hvm = 0;
-    uint32_t flag = XEN_DOMCTL_DEV_RDM_RELAXED;
-    uint32_t domainid = domid;
-    bool isstubdom = libxl_is_stubdom(ctx, domid, &domainid);
-    int r;
-
-    /* Convenience aliases */
-    bool starting = pas->starting;
+    int rc;
 
     /* init pci_add_state */
+    libxl__xswait_init(&pas->xswait);
+    libxl__ev_qmp_init(&pas->qmp);
     pas->pcidev = pcidev;
     pas->pci_domid = domid;
+    libxl__ev_time_init(&pas->timeout);
 
     if (type == LIBXL_DOMAIN_TYPE_INVALID) {
         rc = ERROR_FAIL;
@@ -1025,26 +1033,259 @@ static void do_pci_add(libxl__egc *egc,
     }
 
     if (type == LIBXL_DOMAIN_TYPE_HVM) {
-        hvm = 1;
         switch (libxl__device_model_version_running(gc, domid)) {
             case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL:
-                if (libxl__wait_for_device_model_deprecated(gc, domid,
-                        "running", NULL, NULL, NULL) < 0) {
-                    rc = ERROR_FAIL;
-                    goto out;
-                }
-                rc = qemu_pci_add_xenstore(gc, domid, pcidev);
-                break;
+                pas->xswait.ao = ao;
+                pas->xswait.what = "Device Model";
+                pas->xswait.path = DEVICE_MODEL_XS_PATH(gc,
+                    libxl_get_stubdom_id(CTX, domid), domid, "/state");
+                pas->xswait.timeout_ms = LIBXL_DEVICE_MODEL_START_TIMEOUT * 1000;
+                pas->xswait.callback = pci_add_qemu_trad_watch_state_cb;
+                rc = libxl__xswait_start(gc, &pas->xswait);
+                if (rc) goto out;
+                return;
             case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
-                rc = libxl__qmp_pci_add(gc, domid, pcidev);
-                break;
+                pci_add_qmp_device_add(egc, pas); /* must be last */
+                return;
             default:
                 rc = ERROR_INVAL;
+                break;
         }
-        if ( rc )
+    }
+
+    rc = 0;
+
+out:
+    pci_add_dm_done(egc, pas, rc); /* must be last */
+}
+
+static void pci_add_qemu_trad_watch_state_cb(libxl__egc *egc,
+                                             libxl__xswait_state *xswa,
+                                             int rc,
+                                             const char *state)
+{
+    pci_add_state *pas = CONTAINER_OF(xswa, *pas, xswait);
+    STATE_AO_GC(pas->aodev->ao);
+
+    /* Convenience aliases */
+    libxl_domid domid = pas->domid;
+    libxl_device_pci *pcidev = pas->pcidev;
+
+    if (rc) {
+        if (rc == ERROR_TIMEDOUT) {
+            LOGD(ERROR, domid, "%s not ready", xswa->what);
+        }
+        goto out;
+    }
+
+    if (!state)
+        return;
+    if (strcmp(state, "running"))
+        return;
+
+    rc = qemu_pci_add_xenstore(gc, domid, pcidev);
+out:
+    libxl__xswait_stop(gc, xswa);
+    pci_add_dm_done(egc, pas, rc); /* must be last */
+}
+
+static void pci_add_qmp_device_add(libxl__egc *egc, pci_add_state *pas)
+{
+    STATE_AO_GC(pas->aodev->ao);
+    libxl__json_object *args = NULL;
+    int rc;
+
+    /* Convenience aliases */
+    libxl_domid domid = pas->domid;
+    libxl_device_pci *pcidev = pas->pcidev;
+    libxl__ev_qmp *const qmp = &pas->qmp;
+
+    rc = libxl__ev_time_register_rel(ao, &pas->timeout,
+                                     pci_add_timeout,
+                                     LIBXL_QMP_CMD_TIMEOUT * 1000);
+    if (rc) goto out;
+
+    libxl__qmp_param_add_string(gc, &args, "driver",
+                                "xen-pci-passthrough");
+    QMP_PARAMETERS_SPRINTF(&args, "id", PCI_PT_QDEV_ID,
+                           pcidev->bus, pcidev->dev, pcidev->func);
+    QMP_PARAMETERS_SPRINTF(&args, "hostaddr",
+                           "%04x:%02x:%02x.%01x", pcidev->domain,
+                           pcidev->bus, pcidev->dev, pcidev->func);
+    if (pcidev->vdevfn) {
+        QMP_PARAMETERS_SPRINTF(&args, "addr", "%x.%x",
+                               PCI_SLOT(pcidev->vdevfn),
+                               PCI_FUNC(pcidev->vdevfn));
+    }
+    /*
+     * Version of QEMU prior to the XSA-131 fix did not support
+     * this property and were effectively always in permissive
+     * mode. The fix for XSA-131 switched the default to be
+     * restricted by default and added the permissive property.
+     *
+     * Therefore in order to support both old and new QEMU we only
+     * set the permissive flag if it is true. Users of older QEMU
+     * have no reason to set the flag so this is ok.
+     */
+    if (pcidev->permissive)
+        libxl__qmp_param_add_bool(gc, &args, "permissive", true);
+
+    qmp->ao = pas->aodev->ao;
+    qmp->domid = domid;
+    qmp->payload_fd = -1;
+    qmp->callback = pci_add_qmp_device_add_cb;
+    rc = libxl__ev_qmp_send(gc, qmp, "device_add", args);
+    if (rc) goto out;
+    return;
+
+out:
+    pci_add_dm_done(egc, pas, rc); /* must be last */
+}
+
+static void pci_add_qmp_device_add_cb(libxl__egc *egc,
+                                      libxl__ev_qmp *qmp,
+                                      const libxl__json_object *response,
+                                      int rc)
+{
+    EGC_GC;
+    pci_add_state *pas = CONTAINER_OF(qmp, *pas, qmp);
+
+    if (rc) goto out;
+
+    qmp->callback = pci_add_qmp_query_pci_cb;
+    rc = libxl__ev_qmp_send(gc, qmp, "query-pci", NULL);
+    if (rc) goto out;
+    return;
+
+out:
+    pci_add_dm_done(egc, pas, rc); /* must be last */
+}
+
+static void pci_add_qmp_query_pci_cb(libxl__egc *egc,
+                                     libxl__ev_qmp *qmp,
+                                     const libxl__json_object *response,
+                                     int rc)
+{
+    EGC_GC;
+    pci_add_state *pas = CONTAINER_OF(qmp, *pas, qmp);
+    const libxl__json_object *bus = NULL;
+    char *asked_id;
+    int i, j;
+    const libxl__json_object *devices = NULL;
+    const libxl__json_object *device = NULL;
+    const libxl__json_object *o = NULL;
+    const char *id = NULL;
+    int dev_slot, dev_func;
+
+    /* Convenience aliases */
+    libxl_device_pci *pcidev = pas->pcidev;
+
+    if (rc) goto out;
+
+    /* `query-pci' returns:
+     * [
+     *   {'bus': 'int',
+     *    'devices': [
+     *       {'bus': 'int', 'slot': 'int', 'function': 'int',
+     *        'class_info': 'PciDeviceClass', 'id': 'PciDeviceId',
+     *        '*irq': 'int', 'qdev_id': 'str',
+     *        '*pci_bridge': 'PciBridgeInfo',
+     *        'regions': ['PciMemoryRegion']
+     *       }
+     *    ]
+     *   }
+     * ]
+     * (See qemu.git/qapi/ for the struct that aren't detailed here)
+     */
+
+    asked_id = GCSPRINTF(PCI_PT_QDEV_ID,
+                         pcidev->bus, pcidev->dev, pcidev->func);
+
+    for (i = 0; (bus = libxl__json_array_get(response, i)); i++) {
+        devices = libxl__json_map_get("devices", bus, JSON_ARRAY);
+        if (!devices) {
+            rc = ERROR_QEMU_API;
             goto out;
+        }
+
+        for (j = 0; (device = libxl__json_array_get(devices, j)); j++) {
+             o = libxl__json_map_get("qdev_id", device, JSON_STRING);
+             if (!o) {
+                 rc = ERROR_QEMU_API;
+                 goto out;
+             }
+             id = libxl__json_object_get_string(o);
+             if (!id || strcmp(asked_id, id))
+                 continue;
+
+             o = libxl__json_map_get("slot", device, JSON_INTEGER);
+             if (!o) {
+                 rc = ERROR_QEMU_API;
+                 goto out;
+             }
+             dev_slot = libxl__json_object_get_integer(o);
+             o = libxl__json_map_get("function", device, JSON_INTEGER);
+             if (!o) {
+                 rc = ERROR_QEMU_API;
+                 goto out;
+             }
+             dev_func = libxl__json_object_get_integer(o);
+
+             pcidev->vdevfn = PCI_DEVFN(dev_slot, dev_func);
+
+             rc = 0;
+             goto out;
+        }
     }
 
+    rc = ERROR_FAIL;
+    LOGD(ERROR, qmp->domid,
+         "PCI device id '%s' wasn't found in QEMU's 'query-pci' response.",
+         asked_id);
+
+out:
+    if (rc == ERROR_QEMU_API) {
+        LOGD(ERROR, qmp->domid,
+             "Unexpected response to QMP cmd 'query-pci', received:\n%s",
+             JSON(response));
+    }
+    pci_add_dm_done(egc, pas, rc); /* must be last */
+}
+
+static void pci_add_timeout(libxl__egc *egc, libxl__ev_time *ev,
+                            const struct timeval *requested_abs,
+                            int rc)
+{
+    pci_add_state *pas = CONTAINER_OF(ev, *pas, timeout);
+
+    pci_add_dm_done(egc, pas, rc);
+}
+
+static void pci_add_dm_done(libxl__egc *egc,
+                            pci_add_state *pas,
+                            int rc)
+{
+    STATE_AO_GC(pas->aodev->ao);
+    libxl_ctx *ctx = libxl__gc_owner(gc);
+    libxl_domid domid = pas->pci_domid;
+    char *sysfs_path;
+    FILE *f;
+    unsigned long long start, end, flags, size;
+    int irq, i;
+    int r;
+    uint32_t flag = XEN_DOMCTL_DEV_RDM_RELAXED;
+    uint32_t domainid = domid;
+    bool isstubdom = libxl_is_stubdom(ctx, domid, &domainid);
+
+    /* Convenience aliases */
+    bool starting = pas->starting;
+    libxl_device_pci *pcidev = pas->pcidev;
+    bool hvm = libxl__domain_type(gc, domid) == LIBXL_DOMAIN_TYPE_HVM;
+
+    libxl__ev_qmp_dispose(gc, &pas->qmp);
+
+    if (rc) goto out;
+
     sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain,
                            pcidev->bus, pcidev->dev, pcidev->func);
     f = fopen(sysfs_path, "r");
@@ -1145,6 +1386,7 @@ static void do_pci_add(libxl__egc *egc,
     else
         rc = 0;
 out:
+    libxl__ev_time_deregister(gc, &pas->timeout);
     pas->callback(egc, pas, rc);
 }
 
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index c78ef4637d0a..38ba63d5b920 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -736,54 +736,6 @@ void libxl__qmp_cleanup(libxl__gc *gc, uint32_t domid)
     }
 }
 
-static int pci_add_callback(libxl__qmp_handler *qmp,
-                            const libxl__json_object *response, void *opaque)
-{
-    libxl_device_pci *pcidev = opaque;
-    const libxl__json_object *bus = NULL;
-    GC_INIT(qmp->ctx);
-    int i, j, rc = -1;
-    char *asked_id = GCSPRINTF(PCI_PT_QDEV_ID,
-                               pcidev->bus, pcidev->dev, pcidev->func);
-
-    for (i = 0; (bus = libxl__json_array_get(response, i)); i++) {
-        const libxl__json_object *devices = NULL;
-        const libxl__json_object *device = NULL;
-        const libxl__json_object *o = NULL;
-        const char *id = NULL;
-
-        devices = libxl__json_map_get("devices", bus, JSON_ARRAY);
-
-        for (j = 0; (device = libxl__json_array_get(devices, j)); j++) {
-             o = libxl__json_map_get("qdev_id", device, JSON_STRING);
-             id = libxl__json_object_get_string(o);
-
-             if (id && strcmp(asked_id, id) == 0) {
-                 int dev_slot, dev_func;
-
-                 o = libxl__json_map_get("slot", device, JSON_INTEGER);
-                 if (!o)
-                     goto out;
-                 dev_slot = libxl__json_object_get_integer(o);
-                 o = libxl__json_map_get("function", device, JSON_INTEGER);
-                 if (!o)
-                     goto out;
-                 dev_func = libxl__json_object_get_integer(o);
-
-                 pcidev->vdevfn = PCI_DEVFN(dev_slot, dev_func);
-
-                 rc = 0;
-                 goto out;
-             }
-        }
-    }
-
-
-out:
-    GC_FREE;
-    return rc;
-}
-
 static int pci_del_callback(libxl__qmp_handler *qmp,
                             const libxl__json_object *response, void *opaque)
 {
@@ -833,54 +785,6 @@ static int qmp_run_command(libxl__gc *gc, int domid,
     return rc;
 }
 
-int libxl__qmp_pci_add(libxl__gc *gc, int domid, libxl_device_pci *pcidev)
-{
-    libxl__qmp_handler *qmp = NULL;
-    libxl__json_object *args = NULL;
-    char *hostaddr = NULL;
-    int rc = 0;
-
-    qmp = libxl__qmp_initialize(gc, domid);
-    if (!qmp)
-        return -1;
-
-    hostaddr = GCSPRINTF("%04x:%02x:%02x.%01x", pcidev->domain,
-                         pcidev->bus, pcidev->dev, pcidev->func);
-    if (!hostaddr)
-        return -1;
-
-    libxl__qmp_param_add_string(gc, &args, "driver", "xen-pci-passthrough");
-    QMP_PARAMETERS_SPRINTF(&args, "id", PCI_PT_QDEV_ID,
-                           pcidev->bus, pcidev->dev, pcidev->func);
-    libxl__qmp_param_add_string(gc, &args, "hostaddr", hostaddr);
-    if (pcidev->vdevfn) {
-        QMP_PARAMETERS_SPRINTF(&args, "addr", "%x.%x",
-                               PCI_SLOT(pcidev->vdevfn), PCI_FUNC(pcidev->vdevfn));
-    }
-    /*
-     * Version of QEMU prior to the XSA-131 fix did not support this
-     * property and were effectively always in permissive mode. The
-     * fix for XSA-131 switched the default to be restricted by
-     * default and added the permissive property.
-     *
-     * Therefore in order to support both old and new QEMU we only set
-     * the permissive flag if it is true. Users of older QEMU have no
-     * reason to set the flag so this is ok.
-     */
-    if (pcidev->permissive)
-        libxl__qmp_param_add_bool(gc, &args, "permissive", true);
-
-    rc = qmp_synchronous_send(qmp, "device_add", args,
-                              NULL, NULL, qmp->timeout);
-    if (rc == 0) {
-        rc = qmp_synchronous_send(qmp, "query-pci", NULL,
-                                  pci_add_callback, pcidev, qmp->timeout);
-    }
-
-    libxl__qmp_close(qmp);
-    return rc;
-}
-
 static int qmp_device_del(libxl__gc *gc, int domid, char *id)
 {
     libxl__json_object *args = NULL;
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 29/35] libxl_pci: Use libxl__ao_device with pci_remove
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (27 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 28/35] libxl_pci: Use ev_qmp in do_pci_add Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 30/35] libxl_pci: Use ev_qmp for pci_remove Anthony PERARD
                   ` (6 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

This is in preparation of using asynchronous operation to communicate
with QEMU via QMP (libxl__ev_qmp).

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_domain.c   |  49 ++++++--
 tools/libxl/libxl_internal.h |   6 +-
 tools/libxl/libxl_pci.c      | 221 ++++++++++++++++++++++++++---------
 3 files changed, 210 insertions(+), 66 deletions(-)

diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c
index f3c39fa86fc9..cd7190035005 100644
--- a/tools/libxl/libxl_domain.c
+++ b/tools/libxl/libxl_domain.c
@@ -1104,6 +1104,9 @@ static void destroy_finish_check(libxl__egc *egc,
 }
 
 /* Callbacks for libxl__destroy_domid */
+static void destroy_domid_pci_done(libxl__egc *egc,
+                                   libxl__multidev *multidev,
+                                   int rc);
 static void dm_destroy_cb(libxl__egc *egc,
                           libxl__destroy_devicemodel_state *ddms,
                           int rc);
@@ -1120,8 +1123,7 @@ void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis)
 {
     STATE_AO_GC(dis->ao);
     uint32_t domid = dis->domid;
-    int rc, dm_present;
-    int r;
+    int rc;
 
     libxl__ev_child_init(&dis->destroyer);
 
@@ -1135,6 +1137,41 @@ void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis)
         goto out;
     }
 
+    libxl__multidev_begin(ao, &dis->multidev);
+    dis->multidev.callback = destroy_domid_pci_done;
+    libxl__device_pci_destroy_all(egc, domid, &dis->multidev);
+    libxl__multidev_prepared(egc, &dis->multidev, 0);
+    return;
+
+out:
+    assert(rc);
+    dis->callback(egc, dis, rc);
+}
+
+static void destroy_domid_pci_done(libxl__egc *egc,
+                                   libxl__multidev *multidev,
+                                   int rc)
+{
+    STATE_AO_GC(multidev->ao);
+    libxl__destroy_domid_state *dis =
+        CONTAINER_OF(multidev, *dis, multidev);
+    int dm_present;
+    int r;
+
+    /* Convenience aliases */
+    libxl_domid domid = dis->domid;
+
+    if (rc) {
+        LOGD(ERROR, domid, "Pci shutdown failed");
+        goto out;
+    }
+
+    r = xc_domain_pause(CTX->xch, domid);
+    if (r < 0) {
+        LOGEVD(ERROR, r, domid, "xc_domain_pause failed");
+        rc = ERROR_FAIL;
+    }
+
     switch (libxl__domain_type(gc, domid)) {
     case LIBXL_DOMAIN_TYPE_HVM:
         if (libxl_get_stubdom_id(CTX, domid)) {
@@ -1153,14 +1190,6 @@ void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis)
         abort();
     }
 
-    if (libxl__device_pci_destroy_all(gc, domid) < 0)
-        LOGD(ERROR, domid, "Pci shutdown failed");
-    r = xc_domain_pause(CTX->xch, domid);
-    if (r < 0) {
-        LOGEVD(ERROR, r, domid, "xc_domain_pause failed");
-        rc = ERROR_FAIL;
-    }
-
     if (dm_present) {
         dis->ddms.ao = ao;
         dis->ddms.domid = domid;
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index d60b9c416abf..782cbfc09afb 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -199,6 +199,7 @@ typedef struct libxl__carefd libxl__carefd;
 typedef struct libxl__ev_devlock libxl__ev_devlock;
 typedef struct libxl__dm_resume_state libxl__dm_resume_state;
 typedef struct libxl__ao_device libxl__ao_device;
+typedef struct libxl__multidev libxl__multidev;
 
 typedef struct libxl__domain_create_state libxl__domain_create_state;
 typedef void libxl__domain_create_cb(struct libxl__egc *egc,
@@ -1597,7 +1598,8 @@ _hidden int libxl__pci_topology_init(libxl__gc *gc,
 _hidden void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
                                    libxl_device_pci *pcidev, bool starting,
                                    libxl__ao_device *aodev);
-_hidden int libxl__device_pci_destroy_all(libxl__gc *gc, uint32_t domid);
+_hidden void libxl__device_pci_destroy_all(libxl__egc *egc, uint32_t domid,
+                                           libxl__multidev *);
 _hidden bool libxl__is_igd_vga_passthru(libxl__gc *gc,
                                         const libxl_domain_config *d_config);
 
@@ -2573,7 +2575,6 @@ _hidden void libxl__kill(libxl__gc *gc, pid_t pid, int sig, const char *what);
 
 /*----- device addition/removal -----*/
 
-typedef struct libxl__multidev libxl__multidev;
 typedef void libxl__device_callback(libxl__egc*, libxl__ao_device*);
 
 /* This functions sets the necessary libxl__ao_device struct values to use
@@ -3924,6 +3925,7 @@ struct libxl__destroy_domid_state {
     libxl__destroy_devicemodel_state ddms;
     libxl__ev_child destroyer;
     bool soft_reset;
+    libxl__multidev multidev;
 };
 
 struct libxl__domain_destroy_state {
diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c
index 3477f3aba605..a5f700f0bf64 100644
--- a/tools/libxl/libxl_pci.c
+++ b/tools/libxl/libxl_pci.c
@@ -1730,24 +1730,47 @@ static int qemu_pci_remove_xenstore(libxl__gc *gc, uint32_t domid,
     return 0;
 }
 
-static int libxl__device_pci_remove_common(libxl__gc *gc, uint32_t domid,
-                                           libxl_device_pci *pcidev, int force);
-
-static int do_pci_remove(libxl__gc *gc, uint32_t domid,
-                         libxl_device_pci *pcidev, int force)
+typedef struct pci_remove_state {
+    libxl__ao_device *aodev;
+    libxl_domid domid;
+    libxl_device_pci *pcidev;
+    bool force;
+    bool hvm;
+    unsigned int orig_vdev;
+    unsigned int pfunc_mask;
+    int next_func;
+    libxl__ao_device stubdom_aodev;
+} pci_remove_state;
+
+static void libxl__device_pci_remove_common(libxl__egc *egc,
+    uint32_t domid, libxl_device_pci *pcidev, bool force,
+    libxl__ao_device *aodev);
+static void device_pci_remove_common_next(libxl__egc *egc,
+    pci_remove_state *prs, int rc);
+static void pci_remove_detatched(libxl__egc *egc,
+    pci_remove_state *prs, int rc);
+static void pci_remove_stubdom_done(libxl__egc *egc,
+    libxl__ao_device *aodev);
+static void pci_remove_done(libxl__egc *egc,
+    pci_remove_state *prs, int rc);
+
+static void do_pci_remove(libxl__egc *egc, uint32_t domid,
+                          libxl_device_pci *pcidev, int force,
+                          pci_remove_state *prs)
 {
+    STATE_AO_GC(prs->aodev->ao);
     libxl_ctx *ctx = libxl__gc_owner(gc);
     libxl_device_pci *assigned;
     libxl_domain_type type = libxl__domain_type(gc, domid);
-    int hvm = 0, rc, num;
-    int stubdomid = 0;
+    int rc, num;
     uint32_t domainid = domid;
-    bool isstubdom = libxl_is_stubdom(ctx, domid, &domainid);
-
 
     assigned = libxl_device_pci_list(ctx, domid, &num);
-    if ( assigned == NULL )
-        return ERROR_FAIL;
+    if (assigned == NULL) {
+        rc = ERROR_FAIL;
+        goto out_fail;
+    }
+    libxl__ptr_add(gc, assigned);
 
     rc = ERROR_INVAL;
     if ( !is_pcidev_in_array(assigned, num, pcidev->domain,
@@ -1758,7 +1781,7 @@ static int do_pci_remove(libxl__gc *gc, uint32_t domid,
 
     rc = ERROR_FAIL;
     if (type == LIBXL_DOMAIN_TYPE_HVM) {
-        hvm = 1;
+        prs->hvm = true;
         switch (libxl__device_model_version_running(gc, domid)) {
         case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL:
             if (libxl__wait_for_device_model_deprecated(gc, domid,
@@ -1821,7 +1844,7 @@ static int do_pci_remove(libxl__gc *gc, uint32_t domid,
         f = fopen(sysfs_path, "r");
         if (f == NULL) {
             LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path);
-            goto out;
+            goto skip_irq;
         }
         if ((fscanf(f, "%u", &irq) == 1) && irq) {
             rc = xc_physdev_unmap_pirq(ctx->xch, domid, irq);
@@ -1835,52 +1858,134 @@ static int do_pci_remove(libxl__gc *gc, uint32_t domid,
         }
         fclose(f);
     }
-out:
+skip_irq:
+    rc = 0;
+out_fail:
+    pci_remove_detatched(egc, prs, rc);
+}
+
+static void pci_remove_detatched(libxl__egc *egc,
+                                 pci_remove_state *prs,
+                                 int rc)
+{
+    STATE_AO_GC(prs->aodev->ao);
+    int stubdomid = 0;
+    uint32_t domainid = prs->domid;
+    bool isstubdom;
+
+    /* Convenience aliases */
+    libxl_device_pci *const pcidev = prs->pcidev;
+    libxl_domid domid = prs->domid;
+
+    if (rc) goto out;
+
+    isstubdom = libxl_is_stubdom(CTX, domid, &domainid);
+
     /* don't do multiple resets while some functions are still passed through */
     if ( (pcidev->vdevfn & 0x7) == 0 ) {
         libxl__device_pci_reset(gc, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
     }
 
     if (!isstubdom) {
-        rc = xc_deassign_device(ctx->xch, domid, pcidev_encode_bdf(pcidev));
-        if (rc < 0 && (hvm || errno != ENOSYS))
+        rc = xc_deassign_device(CTX->xch, domid, pcidev_encode_bdf(pcidev));
+        if (rc < 0 && (prs->hvm || errno != ENOSYS))
             LOGED(ERROR, domainid, "xc_deassign_device failed");
     }
 
-    stubdomid = libxl_get_stubdom_id(ctx, domid);
+    stubdomid = libxl_get_stubdom_id(CTX, domid);
     if (stubdomid != 0) {
-        libxl_device_pci pcidev_s = *pcidev;
-        libxl__device_pci_remove_common(gc, stubdomid, &pcidev_s, force);
-    }
+        libxl_device_pci *pcidev_s;
+        libxl__ao_device *const stubdom_aodev = &prs->stubdom_aodev;
+
+        GCNEW(pcidev_s);
+        libxl_device_pci_init(pcidev_s);
+        libxl_device_pci_copy(CTX, pcidev_s, pcidev);
 
-    libxl__device_pci_remove_xenstore(gc, domid, pcidev);
+        libxl__prepare_ao_device(ao, stubdom_aodev);
+        stubdom_aodev->action = LIBXL__DEVICE_ACTION_REMOVE;
+        stubdom_aodev->callback = pci_remove_stubdom_done;
+        stubdom_aodev->update_json = prs->aodev->update_json;
+        libxl__device_pci_remove_common(egc, stubdomid, pcidev_s,
+                                        prs->force, stubdom_aodev);
+        return;
+    }
 
     rc = 0;
-out_fail:
-    free(assigned);
-    return rc;
+out:
+    pci_remove_done(egc, prs, rc);
+}
+
+static void pci_remove_stubdom_done(libxl__egc *egc,
+                                    libxl__ao_device *aodev)
+{
+    pci_remove_state *prs = CONTAINER_OF(aodev, *prs, stubdom_aodev);
 
+    pci_remove_done(egc, prs, 0);
 }
 
-static int libxl__device_pci_remove_common(libxl__gc *gc, uint32_t domid,
-                                           libxl_device_pci *pcidev, int force)
+static void pci_remove_done(libxl__egc *egc,
+                            pci_remove_state *prs,
+                            int rc)
 {
-    unsigned int orig_vdev, pfunc_mask;
-    int i, rc;
+    EGC_GC;
 
-    orig_vdev = pcidev->vdevfn & ~7U;
+    if (rc) goto out;
+
+    libxl__device_pci_remove_xenstore(gc, prs->domid, prs->pcidev);
+out:
+    device_pci_remove_common_next(egc, prs, rc);
+}
+
+static void libxl__device_pci_remove_common(libxl__egc *egc,
+                                            uint32_t domid,
+                                            libxl_device_pci *pcidev,
+                                            bool force,
+                                            libxl__ao_device *aodev)
+{
+    STATE_AO_GC(aodev->ao);
+    int rc;
+    pci_remove_state *prs;
+
+    GCNEW(prs);
+    prs->aodev = aodev;
+    prs->domid = domid;
+    prs->pcidev = pcidev;
+    prs->force = force;
+
+    prs->orig_vdev = pcidev->vdevfn & ~7U;
 
     if ( pcidev->vfunc_mask == LIBXL_PCI_FUNC_ALL ) {
-        if ( pci_multifunction_check(gc, pcidev, &pfunc_mask) ) {
+        if ( pci_multifunction_check(gc, pcidev, &prs->pfunc_mask) ) {
             rc = ERROR_FAIL;
             goto out;
         }
-        pcidev->vfunc_mask &= pfunc_mask;
+        pcidev->vfunc_mask &= prs->pfunc_mask;
     }else{
-        pfunc_mask = (1 << pcidev->func);
+        prs->pfunc_mask = (1 << pcidev->func);
     }
 
-    for(rc = 0, i = 7; i >= 0; --i) {
+    rc = 0;
+    prs->next_func = 7;
+out:
+    device_pci_remove_common_next(egc, prs, rc);
+}
+
+static void device_pci_remove_common_next(libxl__egc *egc,
+                                          pci_remove_state *prs,
+                                          int rc)
+{
+    /* Convenience aliases */
+    libxl_domid domid = prs->domid;
+    libxl_device_pci *const pcidev = prs->pcidev;
+    libxl__ao_device *const aodev = prs->aodev;
+    const unsigned int pfunc_mask = prs->pfunc_mask;
+    const unsigned int orig_vdev = prs->orig_vdev;
+
+    if (rc) goto out;
+
+    while (prs->next_func >= 0) {
+        const int i = prs->next_func;
+        prs->next_func--;
         if ( (1 << i) & pfunc_mask ) {
             if ( pcidev->vfunc_mask == pfunc_mask ) {
                 pcidev->func = i;
@@ -1888,13 +1993,15 @@ static int libxl__device_pci_remove_common(libxl__gc *gc, uint32_t domid,
             }else{
                 pcidev->vdevfn = orig_vdev;
             }
-            if ( do_pci_remove(gc, domid, pcidev, force) )
-                rc = ERROR_FAIL;
+            do_pci_remove(egc, domid, pcidev, prs->force, prs);
+            return;
         }
     }
 
+    rc = 0;
 out:
-    return rc;
+    aodev->rc = rc;
+    aodev->callback(egc, aodev);
 }
 
 int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid,
@@ -1903,11 +2010,14 @@ int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid,
 
 {
     AO_CREATE(ctx, domid, ao_how);
-    int rc;
-
-    rc = libxl__device_pci_remove_common(gc, domid, pcidev, 0);
+    libxl__ao_device *aodev;
 
-    libxl__ao_complete(egc, ao, rc);
+    GCNEW(aodev);
+    libxl__prepare_ao_device(ao, aodev);
+    aodev->action = LIBXL__DEVICE_ACTION_REMOVE;
+    aodev->callback = device_addrm_aocomplete;
+    aodev->update_json = true;
+    libxl__device_pci_remove_common(egc, domid, pcidev, false, aodev);
     return AO_INPROGRESS;
 }
 
@@ -1916,11 +2026,14 @@ int libxl_device_pci_destroy(libxl_ctx *ctx, uint32_t domid,
                              const libxl_asyncop_how *ao_how)
 {
     AO_CREATE(ctx, domid, ao_how);
-    int rc;
-
-    rc = libxl__device_pci_remove_common(gc, domid, pcidev, 1);
+    libxl__ao_device *aodev;
 
-    libxl__ao_complete(egc, ao, rc);
+    GCNEW(aodev);
+    libxl__prepare_ao_device(ao, aodev);
+    aodev->action = LIBXL__DEVICE_ACTION_REMOVE;
+    aodev->callback = device_addrm_aocomplete;
+    aodev->update_json = true;
+    libxl__device_pci_remove_common(egc, domid, pcidev, true, aodev);
     return AO_INPROGRESS;
 }
 
@@ -2004,27 +2117,27 @@ libxl_device_pci *libxl_device_pci_list(libxl_ctx *ctx, uint32_t domid, int *num
     return pcidevs;
 }
 
-int libxl__device_pci_destroy_all(libxl__gc *gc, uint32_t domid)
+void libxl__device_pci_destroy_all(libxl__egc *egc, uint32_t domid,
+                                   libxl__multidev *multidev)
 {
-    libxl_ctx *ctx = libxl__gc_owner(gc);
+    STATE_AO_GC(multidev->ao);
     libxl_device_pci *pcidevs;
-    int num, i, rc = 0;
+    int num, i;
 
-    pcidevs = libxl_device_pci_list(ctx, domid, &num);
+    pcidevs = libxl_device_pci_list(CTX, domid, &num);
     if ( pcidevs == NULL )
-        return 0;
+        return;
+    libxl__ptr_add(gc, pcidevs);
 
     for (i = 0; i < num; i++) {
         /* Force remove on shutdown since, on HVM, qemu will not always
          * respond to SCI interrupt because the guest kernel has shut down the
          * devices by the time we even get here!
          */
-        if (libxl__device_pci_remove_common(gc, domid, pcidevs + i, 1) < 0)
-            rc = ERROR_FAIL;
+        libxl__ao_device *aodev = libxl__multidev_prepare(multidev);
+        libxl__device_pci_remove_common(egc, domid, pcidevs + i, true,
+                                        aodev);
     }
-
-    free(pcidevs);
-    return rc;
 }
 
 int libxl__grant_vga_iomem_permission(libxl__gc *gc, const uint32_t domid,
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 30/35] libxl_pci: Use ev_qmp for pci_remove
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (28 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 29/35] libxl_pci: Use libxl__ao_device with pci_remove Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 31/35] libxl: Use ev_qmp for libxl_send_trigger Anthony PERARD
                   ` (5 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

This patch also replaces the use of
libxl__wait_for_device_model_deprecated() by its equivalent
without the need for a thread.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_internal.h |   2 -
 tools/libxl/libxl_pci.c      | 222 +++++++++++++++++++++++++++++++++--
 tools/libxl/libxl_qmp.c      |  77 ------------
 3 files changed, 210 insertions(+), 91 deletions(-)

diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 782cbfc09afb..00e3cad996c4 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1984,8 +1984,6 @@ typedef struct libxl__qmp_handler libxl__qmp_handler;
  */
 _hidden libxl__qmp_handler *libxl__qmp_initialize(libxl__gc *gc,
                                                   uint32_t domid);
-_hidden int libxl__qmp_pci_del(libxl__gc *gc, int domid,
-                               libxl_device_pci *pcidev);
 /* Resume hvm domain */
 _hidden int libxl__qmp_system_wakeup(libxl__gc *gc, int domid);
 /* Resume QEMU. */
diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c
index a5f700f0bf64..2c4e2e5cff5e 100644
--- a/tools/libxl/libxl_pci.c
+++ b/tools/libxl/libxl_pci.c
@@ -1740,6 +1740,10 @@ typedef struct pci_remove_state {
     unsigned int pfunc_mask;
     int next_func;
     libxl__ao_device stubdom_aodev;
+    libxl__xswait_state xswait;
+    libxl__ev_qmp qmp;
+    libxl__ev_time timeout;
+    libxl__ev_time retry_timer;
 } pci_remove_state;
 
 static void libxl__device_pci_remove_common(libxl__egc *egc,
@@ -1747,10 +1751,23 @@ static void libxl__device_pci_remove_common(libxl__egc *egc,
     libxl__ao_device *aodev);
 static void device_pci_remove_common_next(libxl__egc *egc,
     pci_remove_state *prs, int rc);
+
+static void pci_remove_qemu_trad_watch_state_cb(libxl__egc *egc,
+    libxl__xswait_state *xswa, int rc, const char *state);
+static void pci_remove_qmp_device_del(libxl__egc *egc,
+    pci_remove_state *prs);
+static void pci_remove_qmp_device_del_cb(libxl__egc *egc,
+    libxl__ev_qmp *qmp, const libxl__json_object *response, int rc);
+static void pci_remove_qmp_retry_timer_cb(libxl__egc *egc,
+    libxl__ev_time *ev, const struct timeval *requested_abs, int rc);
+static void pci_remove_qmp_query_cb(libxl__egc *egc,
+    libxl__ev_qmp *qmp, const libxl__json_object *response, int rc);
 static void pci_remove_detatched(libxl__egc *egc,
     pci_remove_state *prs, int rc);
 static void pci_remove_stubdom_done(libxl__egc *egc,
     libxl__ao_device *aodev);
+static void pci_remove_timeout(libxl__egc *egc,
+    libxl__ev_time *ev, const struct timeval *requested_abs, int rc);
 static void pci_remove_done(libxl__egc *egc,
     pci_remove_state *prs, int rc);
 
@@ -1784,22 +1801,22 @@ static void do_pci_remove(libxl__egc *egc, uint32_t domid,
         prs->hvm = true;
         switch (libxl__device_model_version_running(gc, domid)) {
         case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL:
-            if (libxl__wait_for_device_model_deprecated(gc, domid,
-                    "running", NULL, NULL, NULL) < 0)
-                goto out_fail;
-            rc = qemu_pci_remove_xenstore(gc, domid, pcidev, force);
-            break;
+            prs->xswait.ao = ao;
+            prs->xswait.what = "Device Model";
+            prs->xswait.path = DEVICE_MODEL_XS_PATH(gc,
+                libxl_get_stubdom_id(CTX, domid), domid, "/state");
+            prs->xswait.timeout_ms = LIBXL_DEVICE_MODEL_START_TIMEOUT * 1000;
+            prs->xswait.callback = pci_remove_qemu_trad_watch_state_cb;
+            rc = libxl__xswait_start(gc, &prs->xswait);
+            if (rc) goto out_fail;
+            return;
         case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
-            rc = libxl__qmp_pci_del(gc, domid, pcidev);
-            break;
+            pci_remove_qmp_device_del(egc, prs); /* must be last */
+            return;
         default:
             rc = ERROR_INVAL;
             goto out_fail;
         }
-        if (rc && !force) {
-            rc = ERROR_FAIL;
-            goto out_fail;
-        }
     } else {
         assert(type == LIBXL_DOMAIN_TYPE_PV);
 
@@ -1861,9 +1878,163 @@ static void do_pci_remove(libxl__egc *egc, uint32_t domid,
 skip_irq:
     rc = 0;
 out_fail:
+    pci_remove_detatched(egc, prs, rc); /* must be last */
+}
+
+static void pci_remove_qemu_trad_watch_state_cb(libxl__egc *egc,
+                                                libxl__xswait_state *xswa,
+                                                int rc,
+                                                const char *state)
+{
+    pci_remove_state *prs = CONTAINER_OF(xswa, *prs, xswait);
+    STATE_AO_GC(prs->aodev->ao);
+
+    /* Convenience aliases */
+    libxl_domid domid = prs->domid;
+    libxl_device_pci *const pcidev = prs->pcidev;
+
+    if (rc) {
+        if (rc == ERROR_TIMEDOUT) {
+            LOGD(ERROR, domid, "%s not ready", xswa->what);
+        }
+        goto out;
+    }
+
+    if (!state)
+        return;
+    if (strcmp(state, "running"))
+        return;
+
+    rc = qemu_pci_remove_xenstore(gc, domid, pcidev, prs->force);
+
+out:
+    libxl__xswait_stop(gc, xswa);
     pci_remove_detatched(egc, prs, rc);
 }
 
+static void pci_remove_qmp_device_del(libxl__egc *egc,
+                                      pci_remove_state *prs)
+{
+    STATE_AO_GC(prs->aodev->ao);
+    libxl__json_object *args = NULL;
+    int rc;
+
+    /* Convenience aliases */
+    libxl_device_pci *const pcidev = prs->pcidev;
+
+    rc = libxl__ev_time_register_rel(ao, &prs->timeout,
+                                     pci_remove_timeout,
+                                     LIBXL_QMP_CMD_TIMEOUT * 1000);
+    if (rc) goto out;
+
+    QMP_PARAMETERS_SPRINTF(&args, "id", PCI_PT_QDEV_ID,
+                           pcidev->bus, pcidev->dev, pcidev->func);
+    prs->qmp.callback = pci_remove_qmp_device_del_cb;
+    rc = libxl__ev_qmp_send(gc, &prs->qmp, "device_del", args);
+    if (rc) goto out;
+    return;
+
+out:
+    pci_remove_detatched(egc, prs, rc);
+}
+
+static void pci_remove_qmp_device_del_cb(libxl__egc *egc,
+                                         libxl__ev_qmp *qmp,
+                                         const libxl__json_object *response,
+                                         int rc)
+{
+    EGC_GC;
+    pci_remove_state *prs = CONTAINER_OF(qmp, *prs, qmp);
+
+    if (rc) goto out;
+
+    /* Now that the command is sent, we want to wait until QEMU has
+     * confirmed that the device is removed. */
+    /* TODO: Instead of using a poll loop { ev_timer ; query-pci }, it
+     * could be possible to listen to events sent by QEMU via QMP in order
+     * to wait for the passthrough pci-device to be removed from QEMU.  */
+    pci_remove_qmp_retry_timer_cb(egc, &prs->retry_timer, NULL,
+                                  ERROR_TIMEDOUT);
+    return;
+
+out:
+    pci_remove_detatched(egc, prs, rc);
+}
+
+static void pci_remove_qmp_retry_timer_cb(libxl__egc *egc, libxl__ev_time *ev,
+                                          const struct timeval *requested_abs,
+                                          int rc)
+{
+    EGC_GC;
+    pci_remove_state *prs = CONTAINER_OF(ev, *prs, retry_timer);
+
+    prs->qmp.callback = pci_remove_qmp_query_cb;
+    rc = libxl__ev_qmp_send(gc, &prs->qmp, "query-pci", NULL);
+    if (rc) goto out;
+    return;
+
+out:
+    pci_remove_detatched(egc, prs, rc);
+}
+
+static void pci_remove_qmp_query_cb(libxl__egc *egc,
+                                    libxl__ev_qmp *qmp,
+                                    const libxl__json_object *response,
+                                    int rc)
+{
+    EGC_GC;
+    pci_remove_state *prs = CONTAINER_OF(qmp, *prs, qmp);
+    const libxl__json_object *bus = NULL;
+    const char *asked_id;
+    int i, j;
+
+    /* Convenience aliases */
+    libxl__ao *const ao = prs->aodev->ao;
+    libxl_device_pci *const pcidev = prs->pcidev;
+
+    if (rc) goto out;
+
+    asked_id = GCSPRINTF(PCI_PT_QDEV_ID,
+                         pcidev->bus, pcidev->dev, pcidev->func);
+
+    /* query-pci response:
+     * [{ 'devices': [ 'qdev_id': 'str', ...  ], ... }]
+     * */
+
+    for (i = 0; (bus = libxl__json_array_get(response, i)); i++) {
+        const libxl__json_object *devices = NULL;
+        const libxl__json_object *device = NULL;
+        const libxl__json_object *o = NULL;
+        const char *id = NULL;
+
+        devices = libxl__json_map_get("devices", bus, JSON_ARRAY);
+        if (!devices) {
+            rc = ERROR_QEMU_API;
+            goto out;
+        }
+
+        for (j = 0; (device = libxl__json_array_get(devices, j)); j++) {
+             o = libxl__json_map_get("qdev_id", device, JSON_STRING);
+             if (!o) {
+                 rc = ERROR_QEMU_API;
+                 goto out;
+             }
+             id = libxl__json_object_get_string(o);
+
+             if (id && !strcmp(asked_id, id)) {
+                 /* Device still in QEMU, need to wait longuer. */
+                 rc = libxl__ev_time_register_rel(ao, &prs->retry_timer,
+                     pci_remove_qmp_retry_timer_cb, 1000);
+                 if (rc) goto out;
+                 return;
+             }
+        }
+    }
+
+out:
+    pci_remove_detatched(egc, prs, rc); /* must be last */
+}
+
 static void pci_remove_detatched(libxl__egc *egc,
                                  pci_remove_state *prs,
                                  int rc)
@@ -1877,7 +2048,8 @@ static void pci_remove_detatched(libxl__egc *egc,
     libxl_device_pci *const pcidev = prs->pcidev;
     libxl_domid domid = prs->domid;
 
-    if (rc) goto out;
+    if (rc && !prs->force)
+        goto out;
 
     isstubdom = libxl_is_stubdom(CTX, domid, &domainid);
 
@@ -1923,6 +2095,15 @@ static void pci_remove_stubdom_done(libxl__egc *egc,
     pci_remove_done(egc, prs, 0);
 }
 
+static void pci_remove_timeout(libxl__egc *egc, libxl__ev_time *ev,
+                               const struct timeval *requested_abs,
+                               int rc)
+{
+    pci_remove_state *prs = CONTAINER_OF(ev, *prs, timeout);
+
+    pci_remove_done(egc, prs, rc);
+}
+
 static void pci_remove_done(libxl__egc *egc,
                             pci_remove_state *prs,
                             int rc)
@@ -1931,6 +2112,10 @@ static void pci_remove_done(libxl__egc *egc,
 
     if (rc) goto out;
 
+    libxl__ev_qmp_dispose(gc, &prs->qmp);
+    libxl__ev_time_deregister(gc, &prs->timeout);
+    libxl__ev_time_deregister(gc, &prs->retry_timer);
+
     libxl__device_pci_remove_xenstore(gc, prs->domid, prs->pcidev);
 out:
     device_pci_remove_common_next(egc, prs, rc);
@@ -1951,6 +2136,13 @@ static void libxl__device_pci_remove_common(libxl__egc *egc,
     prs->domid = domid;
     prs->pcidev = pcidev;
     prs->force = force;
+    libxl__xswait_init(&prs->xswait);
+    libxl__ev_qmp_init(&prs->qmp);
+    prs->qmp.ao = prs->aodev->ao;
+    prs->qmp.domid = prs->domid;
+    prs->qmp.payload_fd = -1;
+    libxl__ev_time_init(&prs->timeout);
+    libxl__ev_time_init(&prs->retry_timer);
 
     prs->orig_vdev = pcidev->vdevfn & ~7U;
 
@@ -1974,6 +2166,8 @@ static void device_pci_remove_common_next(libxl__egc *egc,
                                           pci_remove_state *prs,
                                           int rc)
 {
+    EGC_GC;
+
     /* Convenience aliases */
     libxl_domid domid = prs->domid;
     libxl_device_pci *const pcidev = prs->pcidev;
@@ -2000,6 +2194,10 @@ static void device_pci_remove_common_next(libxl__egc *egc,
 
     rc = 0;
 out:
+    libxl__ev_qmp_dispose(gc, &prs->qmp);
+    libxl__xswait_stop(gc, &prs->xswait);
+    libxl__ev_time_deregister(gc, &prs->timeout);
+    libxl__ev_time_deregister(gc, &prs->retry_timer);
     aodev->rc = rc;
     aodev->callback(egc, aodev);
 }
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index 38ba63d5b920..8fac737fad03 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -87,7 +87,6 @@
 
 #define QMP_RECEIVE_BUFFER_SIZE 4096
 #define QMP_MAX_SIZE_RX_BUF MB(1)
-#define PCI_PT_QDEV_ID "pci-pt-%02x_%02x.%01x"
 
 /*
  * qmp_callback_t is call whenever a message from QMP contain the "id"
@@ -736,38 +735,6 @@ void libxl__qmp_cleanup(libxl__gc *gc, uint32_t domid)
     }
 }
 
-static int pci_del_callback(libxl__qmp_handler *qmp,
-                            const libxl__json_object *response, void *opaque)
-{
-    const char *asked_id = opaque;
-    const libxl__json_object *bus = NULL;
-    GC_INIT(qmp->ctx);
-    int i, j, rc = 0;
-
-    for (i = 0; (bus = libxl__json_array_get(response, i)); i++) {
-        const libxl__json_object *devices = NULL;
-        const libxl__json_object *device = NULL;
-        const libxl__json_object *o = NULL;
-        const char *id = NULL;
-
-        devices = libxl__json_map_get("devices", bus, JSON_ARRAY);
-
-        for (j = 0; (device = libxl__json_array_get(devices, j)); j++) {
-             o = libxl__json_map_get("qdev_id", device, JSON_STRING);
-             id = libxl__json_object_get_string(o);
-
-             if (id && strcmp(asked_id, id) == 0) {
-                 rc = 1;
-                 goto out;
-             }
-        }
-    }
-
-out:
-    GC_FREE;
-    return rc;
-}
-
 static int qmp_run_command(libxl__gc *gc, int domid,
                            const char *cmd, libxl__json_object *args,
                            qmp_callback_t callback, void *opaque)
@@ -785,50 +752,6 @@ static int qmp_run_command(libxl__gc *gc, int domid,
     return rc;
 }
 
-static int qmp_device_del(libxl__gc *gc, int domid, char *id)
-{
-    libxl__json_object *args = NULL;
-    libxl__qmp_handler *qmp = NULL;
-    int rc = 0;
-
-    qmp = libxl__qmp_initialize(gc, domid);
-    if (!qmp)
-        return ERROR_FAIL;
-
-    libxl__qmp_param_add_string(gc, &args, "id", id);
-    rc = qmp_synchronous_send(qmp, "device_del", args,
-                              NULL, NULL, qmp->timeout);
-    if (rc == 0) {
-        unsigned int retry = 0;
-
-        do {
-            rc = qmp_synchronous_send(qmp, "query-pci", NULL,
-                                      pci_del_callback, id, qmp->timeout);
-            if (rc != 1) {
-                break;
-            }
-            sleep(1);
-        } while (retry++ < 5);
-
-        if (rc != 0) {
-            LOGD(WARN, qmp->domid,
-                 "device model may not complete removing device %s", id);
-        }
-    }
-
-    libxl__qmp_close(qmp);
-    return rc;
-}
-
-int libxl__qmp_pci_del(libxl__gc *gc, int domid, libxl_device_pci *pcidev)
-{
-    char *id = NULL;
-
-    id = GCSPRINTF(PCI_PT_QDEV_ID, pcidev->bus, pcidev->dev, pcidev->func);
-
-    return qmp_device_del(gc, domid, id);
-}
-
 int libxl__qmp_system_wakeup(libxl__gc *gc, int domid)
 {
     return qmp_run_command(gc, domid, "system_wakeup", NULL, NULL, NULL);
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 31/35] libxl: Use ev_qmp for libxl_send_trigger
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (29 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 30/35] libxl_pci: Use ev_qmp for pci_remove Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 32/35] libxl: Use ev_qmp in libxl_set_vcpuonline Anthony PERARD
                   ` (4 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_domain.c   | 49 ++++++++++++++++++++++++++++++------
 tools/libxl/libxl_internal.h |  2 --
 tools/libxl/libxl_qmp.c      |  5 ----
 3 files changed, 42 insertions(+), 14 deletions(-)

diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c
index cd7190035005..08d3fc9fbc03 100644
--- a/tools/libxl/libxl_domain.c
+++ b/tools/libxl/libxl_domain.c
@@ -1556,19 +1556,39 @@ int libxl_set_vcpuonline(libxl_ctx *ctx, uint32_t domid,
     return AO_INPROGRESS;
 }
 
-static int libxl__domain_s3_resume(libxl__gc *gc, int domid)
+static void domain_s3_resume_done(libxl__egc *egc, libxl__ev_qmp *qmp,
+                                  const libxl__json_object *response,
+                                  int rc);
+
+static void domain_s3_resume(libxl__ao *ao, libxl__egc *egc, int domid)
 {
+    AO_GC;
+    libxl__ev_qmp *qmp;
     int rc = 0;
+    int r;
+
+    GCNEW(qmp);
+    libxl__ev_qmp_init(qmp);
+    qmp->ao = ao;
+    qmp->domid = domid;
+    qmp->payload_fd = -1;
+    qmp->callback = domain_s3_resume_done;
 
     switch (libxl__domain_type(gc, domid)) {
     case LIBXL_DOMAIN_TYPE_HVM:
         switch (libxl__device_model_version_running(gc, domid)) {
         case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL:
-            rc = xc_hvm_param_set(CTX->xch, domid, HVM_PARAM_ACPI_S_STATE, 0);
+            r = xc_hvm_param_set(CTX->xch, domid, HVM_PARAM_ACPI_S_STATE, 0);
+            if (r) {
+                LOGED(ERROR, domid, "Send trigger '%s' failed",
+                      libxl_trigger_to_string(LIBXL_TRIGGER_S3RESUME));
+                rc = ERROR_FAIL;
+            }
             break;
         case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
-            rc = libxl__qmp_system_wakeup(gc, domid);
-            break;
+            rc = libxl__ev_qmp_send(gc, qmp, "system_wakeup", NULL);
+            if (rc) goto out;
+            return;
         default:
             rc = ERROR_INVAL;
             break;
@@ -1579,7 +1599,22 @@ static int libxl__domain_s3_resume(libxl__gc *gc, int domid)
         break;
     }
 
-    return rc;
+out:
+    domain_s3_resume_done(egc, qmp, NULL, rc);
+}
+
+static void domain_s3_resume_done(libxl__egc *egc, libxl__ev_qmp *qmp,
+                                  const libxl__json_object *response,
+                                  int rc)
+{
+    EGC_GC;
+
+    if (rc)
+        LOGD(ERROR, qmp->domid, "Send trigger '%s' failed, rc=%d",
+              libxl_trigger_to_string(LIBXL_TRIGGER_S3RESUME), rc);
+
+    libxl__ev_qmp_dispose(gc, qmp);
+    libxl__ao_complete(egc, qmp->ao, rc);
 }
 
 int libxl_send_trigger(libxl_ctx *ctx, uint32_t domid,
@@ -1611,8 +1646,8 @@ int libxl_send_trigger(libxl_ctx *ctx, uint32_t domid,
                                     XEN_DOMCTL_SENDTRIGGER_RESET, vcpuid);
         break;
     case LIBXL_TRIGGER_S3RESUME:
-        rc = libxl__domain_s3_resume(gc, domid);
-        break;
+        domain_s3_resume(ao, egc, domid); /* must be last */
+        return AO_INPROGRESS;
     default:
         rc = -1;
         errno = EINVAL;
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 00e3cad996c4..7aa1a6a92409 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1984,8 +1984,6 @@ typedef struct libxl__qmp_handler libxl__qmp_handler;
  */
 _hidden libxl__qmp_handler *libxl__qmp_initialize(libxl__gc *gc,
                                                   uint32_t domid);
-/* Resume hvm domain */
-_hidden int libxl__qmp_system_wakeup(libxl__gc *gc, int domid);
 /* Resume QEMU. */
 _hidden int libxl__qmp_resume(libxl__gc *gc, int domid);
 /* Load current QEMU state from file. */
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index 8fac737fad03..40043a0a45b2 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -752,11 +752,6 @@ static int qmp_run_command(libxl__gc *gc, int domid,
     return rc;
 }
 
-int libxl__qmp_system_wakeup(libxl__gc *gc, int domid)
-{
-    return qmp_run_command(gc, domid, "system_wakeup", NULL, NULL, NULL);
-}
-
 int libxl__qmp_restore(libxl__gc *gc, int domid, const char *state_file)
 {
     libxl__json_object *args = NULL;
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 32/35] libxl: Use ev_qmp in libxl_set_vcpuonline
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (30 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 31/35] libxl: Use ev_qmp for libxl_send_trigger Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 19:17   ` [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) [and 1 more messages] Ian Jackson
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 33/35] libxl: libxl_retrieve_domain_configuration now uses ev_qmp Anthony PERARD
                   ` (3 subsequent siblings)
  35 siblings, 1 reply; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

Removed libxl__qmp_cpu_add since it's not used anymore.

`cpumap' arg of libxl__set_vcpuonline_xenstore is constified.

The QMP command "query-cpus" is going to be called from different
places, so the algorithm that parse the answer is in a separate
function, qmp_parse_query_cpus.

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

Notes:
    v2:
    - the patch "libxl: Extract qmp_parse_query_cpus" have been squashed
      into this one.

 tools/libxl/libxl_domain.c   | 204 +++++++++++++++++++++++++++--------
 tools/libxl/libxl_internal.h |   2 -
 tools/libxl/libxl_qmp.c      |   9 --
 3 files changed, 158 insertions(+), 57 deletions(-)

diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c
index 08d3fc9fbc03..b97e874a9c05 100644
--- a/tools/libxl/libxl_domain.c
+++ b/tools/libxl/libxl_domain.c
@@ -1432,8 +1432,8 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ctx *ctx, uint32_t domid,
 }
 
 static int libxl__set_vcpuonline_xenstore(libxl__gc *gc, uint32_t domid,
-                                         libxl_bitmap *cpumap,
-                                         const libxl_dominfo *info)
+                                          const libxl_bitmap *cpumap,
+                                          const libxl_dominfo *info)
 {
     char *dompath;
     xs_transaction_t t;
@@ -1457,55 +1457,76 @@ static int libxl__set_vcpuonline_xenstore(libxl__gc *gc, uint32_t domid,
     return rc;
 }
 
-static int libxl__set_vcpuonline_qmp(libxl__gc *gc, uint32_t domid,
-                                     libxl_bitmap *cpumap,
-                                     const libxl_dominfo *info)
+static int qmp_parse_query_cpus(libxl__gc *gc,
+                                libxl_domid domid,
+                                const libxl__json_object *response,
+                                libxl_bitmap *const map)
 {
-    int i, rc;
-    libxl_bitmap current_map, final_map;
+    int i;
+    const libxl__json_object *cpu;
 
-    libxl_bitmap_init(&current_map);
-    libxl_bitmap_init(&final_map);
-
-    libxl_bitmap_alloc(CTX, &current_map, info->vcpu_max_id + 1);
-    libxl_bitmap_set_none(&current_map);
-    rc = libxl__qmp_query_cpus(gc, domid, &current_map);
-    if (rc) {
-        LOGD(ERROR, domid, "Failed to query cpus");
-        goto out;
-    }
-
-    libxl_bitmap_copy_alloc(CTX, &final_map, cpumap);
-
-    libxl_for_each_set_bit(i, current_map)
-        libxl_bitmap_reset(&final_map, i);
-
-    libxl_for_each_set_bit(i, final_map) {
-        rc = libxl__qmp_cpu_add(gc, domid, i);
-        if (rc) {
-            LOGD(ERROR, domid, "Failed to add cpu %d", i);
-            goto out;
+    libxl_bitmap_set_none(map);
+    /* Parse response to QMP command "query-cpus":
+     * [ { 'CPU': 'int',...} ]
+     */
+    for (i = 0; (cpu = libxl__json_array_get(response, i)); i++) {
+        unsigned int cpu_index;
+        const libxl__json_object *o;
+
+        o = libxl__json_map_get("CPU", cpu, JSON_INTEGER);
+        if (!o) {
+            LOGD(ERROR, domid, "Failed to retrieve CPU index.");
+            return ERROR_QEMU_API;
         }
+
+        cpu_index = libxl__json_object_get_integer(o);
+        libxl_bitmap_set(map, cpu_index);
     }
 
-    rc = 0;
-out:
-    libxl_bitmap_dispose(&current_map);
-    libxl_bitmap_dispose(&final_map);
-    return rc;
+    return 0;
 }
 
+typedef struct set_vcpuonline_state {
+    libxl__ev_qmp qmp;
+    libxl__ev_time timeout;
+    const libxl_bitmap *cpumap;
+    libxl_dominfo info;
+    libxl_bitmap final_map;
+    int index; /* for loop on final_map */
+} set_vcpuonline_state;
+
+static void set_vcpuonline_qmp_cpus_queried(libxl__egc *,
+    libxl__ev_qmp *, const libxl__json_object *, int rc);
+static void set_vcpuonline_qmp_add_cpu(libxl__egc *,
+    libxl__ev_qmp *, const libxl__json_object *response, int rc);
+static void set_vcpuonline_timeout(libxl__egc *egc,
+    libxl__ev_time *ev, const struct timeval *requested_abs, int rc);
+static void set_vcpuonline_done(libxl__egc *egc,
+    set_vcpuonline_state *svos, int rc);
+
 int libxl_set_vcpuonline(libxl_ctx *ctx, uint32_t domid,
                          libxl_bitmap *cpumap,
                          const libxl_asyncop_how *ao_how)
 {
     AO_CREATE(ctx, domid, ao_how);
     int rc, maxcpus;
-    libxl_dominfo info;
+    set_vcpuonline_state *svos;
+
+    GCNEW(svos);
+    libxl__ev_qmp_init(&svos->qmp);
+    svos->qmp.ao = ao;
+    svos->qmp.domid = domid;
+    svos->qmp.payload_fd = -1;
+    libxl__ev_time_init(&svos->timeout);
+    svos->cpumap = cpumap;
+    libxl_dominfo_init(&svos->info);
+    libxl_bitmap_init(&svos->final_map);
 
-    libxl_dominfo_init(&info);
+    /* Convenience aliases */
+    libxl_dominfo *info = &svos->info;
+    libxl__ev_qmp *qmp = &svos->qmp;
 
-    rc = libxl_domain_info(CTX, &info, domid);
+    rc = libxl_domain_info(CTX, info, domid);
     if (rc < 0) {
         LOGED(ERROR, domid, "Getting domain info list");
         goto out;
@@ -1518,10 +1539,10 @@ int libxl_set_vcpuonline(libxl_ctx *ctx, uint32_t domid,
         rc = ERROR_FAIL;
         goto out;
     }
-    if (maxcpus > info.vcpu_max_id + 1)
+    if (maxcpus > info->vcpu_max_id + 1)
     {
         LOGED(ERROR, domid, "Requested %d VCPUs, however maxcpus is %d!",
-              maxcpus, info.vcpu_max_id + 1);
+              maxcpus, info->vcpu_max_id + 1);
         rc = ERROR_FAIL;
         goto out;
     }
@@ -1532,8 +1553,14 @@ int libxl_set_vcpuonline(libxl_ctx *ctx, uint32_t domid,
         case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL:
             break;
         case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
-            rc = libxl__set_vcpuonline_qmp(gc, domid, cpumap, &info);
-            break;
+            rc = libxl__ev_time_register_rel(ao, &svos->timeout,
+                                             set_vcpuonline_timeout,
+                                             LIBXL_QMP_CMD_TIMEOUT * 1000);
+            if (rc) goto out;
+            qmp->callback = set_vcpuonline_qmp_cpus_queried;
+            rc = libxl__ev_qmp_send(gc, qmp, "query-cpus", NULL);
+            if (rc) goto out;
+            return AO_INPROGRESS;
         default:
             rc = ERROR_INVAL;
         }
@@ -1545,15 +1572,100 @@ int libxl_set_vcpuonline(libxl_ctx *ctx, uint32_t domid,
         rc = ERROR_INVAL;
     }
 
-    if (!rc)
-        rc = libxl__set_vcpuonline_xenstore(gc, domid, cpumap, &info);
+out:
+    set_vcpuonline_done(egc, svos, rc); /* must be last */
+    return AO_INPROGRESS;
+}
+
+static void set_vcpuonline_qmp_cpus_queried(libxl__egc *egc,
+    libxl__ev_qmp *qmp, const libxl__json_object *response, int rc)
+{
+    EGC_GC;
+    set_vcpuonline_state *svos = CONTAINER_OF(qmp, *svos, qmp);
+    int i;
+    libxl_bitmap current_map;
+
+    /* Convenience aliases */
+    libxl_bitmap *final_map = &svos->final_map;
+
+    libxl_bitmap_init(&current_map);
+
+    if (rc) goto out;
+
+    libxl_bitmap_alloc(CTX, &current_map, svos->info.vcpu_max_id + 1);
+    rc = qmp_parse_query_cpus(gc, qmp->domid, response, &current_map);
+    if (rc) goto out;
+
+    libxl_bitmap_copy_alloc(CTX, final_map, svos->cpumap);
+
+    libxl_for_each_set_bit(i, current_map) {
+        libxl_bitmap_reset(final_map, i);
+    }
 
 out:
-    libxl_dominfo_dispose(&info);
-    if (rc)
-        return AO_CREATE_FAIL(rc);
+    libxl_bitmap_dispose(&current_map);
+    svos->index = -1;
+    set_vcpuonline_qmp_add_cpu(egc, qmp, NULL, rc); /* must be last */
+}
+
+static void set_vcpuonline_qmp_add_cpu(libxl__egc *egc,
+    libxl__ev_qmp *qmp, const libxl__json_object *response, int rc)
+{
+    STATE_AO_GC(qmp->ao);
+    set_vcpuonline_state *svos = CONTAINER_OF(qmp, *svos, qmp);
+    libxl__json_object *args = NULL;
+
+    /* Convenience aliases */
+    libxl_bitmap *map = &svos->final_map;
+
+    if (rc) goto out;
+
+    while (libxl_bitmap_cpu_valid(map, ++svos->index)) {
+        if (libxl_bitmap_test(map, svos->index)) {
+            qmp->callback = set_vcpuonline_qmp_add_cpu;
+            libxl__qmp_param_add_integer(gc, &args, "id", svos->index);
+            rc = libxl__ev_qmp_send(gc, qmp, "cpu-add", args);
+            if (rc) goto out;
+            return;
+        }
+    }
+
+out:
+    set_vcpuonline_done(egc, svos, rc);
+}
+
+static void set_vcpuonline_timeout(libxl__egc *egc, libxl__ev_time *ev,
+                                   const struct timeval *requested_abs,
+                                   int rc)
+{
+    EGC_GC;
+    set_vcpuonline_state *svos = CONTAINER_OF(ev, *svos, timeout);
+
+    if (rc == ERROR_TIMEDOUT)
+        LOGD(ERROR, svos->qmp.domid,
+             "Setting CPU online in QEMU timed out");
+
+    set_vcpuonline_done(egc, svos, rc);
+}
+
+static void set_vcpuonline_done(libxl__egc *egc,
+                                set_vcpuonline_state *svos,
+                                int rc)
+{
+    STATE_AO_GC(svos->qmp.ao);
+
+    /* Convenience aliases */
+    libxl_domid domid = svos->qmp.domid;
+
+    if (!rc)
+        rc = libxl__set_vcpuonline_xenstore(gc, domid, svos->cpumap,
+                                            &svos->info);
+
+    libxl_bitmap_dispose(&svos->final_map);
+    libxl_dominfo_dispose(&svos->info);
+    libxl__ev_time_deregister(gc, &svos->timeout);
+    libxl__ev_qmp_dispose(gc, &svos->qmp);
     libxl__ao_complete(egc, ao, rc);
-    return AO_INPROGRESS;
 }
 
 static void domain_s3_resume_done(libxl__egc *egc, libxl__ev_qmp *qmp,
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 7aa1a6a92409..1ecebf136984 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1988,8 +1988,6 @@ _hidden libxl__qmp_handler *libxl__qmp_initialize(libxl__gc *gc,
 _hidden int libxl__qmp_resume(libxl__gc *gc, int domid);
 /* Load current QEMU state from file. */
 _hidden int libxl__qmp_restore(libxl__gc *gc, int domid, const char *filename);
-/* Add a virtual CPU */
-_hidden int libxl__qmp_cpu_add(libxl__gc *gc, int domid, int index);
 /* Query the bitmap of CPUs */
 _hidden int libxl__qmp_query_cpus(libxl__gc *gc, int domid,
                                   libxl_bitmap *map);
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index 40043a0a45b2..27183bc6c4a3 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -767,15 +767,6 @@ int libxl__qmp_resume(libxl__gc *gc, int domid)
     return qmp_run_command(gc, domid, "cont", NULL, NULL, NULL);
 }
 
-int libxl__qmp_cpu_add(libxl__gc *gc, int domid, int idx)
-{
-    libxl__json_object *args = NULL;
-
-    libxl__qmp_param_add_integer(gc, &args, "id", idx);
-
-    return qmp_run_command(gc, domid, "cpu-add", args, NULL, NULL);
-}
-
 static int query_cpus_callback(libxl__qmp_handler *qmp,
                                const libxl__json_object *response,
                                void *opaque)
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 33/35] libxl: libxl_retrieve_domain_configuration now uses ev_qmp
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (31 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 32/35] libxl: Use ev_qmp in libxl_set_vcpuonline Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 34/35] libxl: libxl_qemu_monitor_command " Anthony PERARD
                   ` (2 subsequent siblings)
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

This was the last user of libxl__qmp_query_cpus which can now be
removed.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---

Notes:
    v3:
    - following rename of ev_lock to ev_devlock, renamed field rdcs.ev_lock
      to rdcs.devlock

 tools/libxl/libxl_domain.c   | 163 ++++++++++++++++++++++++++++-------
 tools/libxl/libxl_internal.h |   3 -
 tools/libxl/libxl_qmp.c      |  38 --------
 3 files changed, 131 insertions(+), 73 deletions(-)

diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c
index b97e874a9c05..0dd5b7ffa963 100644
--- a/tools/libxl/libxl_domain.c
+++ b/tools/libxl/libxl_domain.c
@@ -1800,27 +1800,6 @@ uint32_t libxl_vm_get_start_time(libxl_ctx *ctx, uint32_t domid)
     return ret;
 }
 
-/* For QEMU upstream we always need to provide the number of cpus present to
- * QEMU whether they are online or not; otherwise QEMU won't accept the saved
- * state. See implementation of libxl__qmp_query_cpus.
- */
-static int libxl__update_avail_vcpus_qmp(libxl__gc *gc, uint32_t domid,
-                                         unsigned int max_vcpus,
-                                         libxl_bitmap *map)
-{
-    int rc;
-
-    rc = libxl__qmp_query_cpus(gc, domid, map);
-    if (rc) {
-        LOGD(ERROR, domid, "Fail to get number of cpus");
-        goto out;
-    }
-
-    rc = 0;
-out:
-    return rc;
-}
-
 static int libxl__update_avail_vcpus_xenstore(libxl__gc *gc, uint32_t domid,
                                               unsigned int max_vcpus,
                                               libxl_bitmap *map)
@@ -1849,13 +1828,61 @@ static int libxl__update_avail_vcpus_xenstore(libxl__gc *gc, uint32_t domid,
     return rc;
 }
 
+typedef struct {
+    libxl__ev_qmp qmp;
+    libxl__ev_time timeout;
+    libxl_domain_config *d_config; /* user pointer */
+    libxl__ev_devlock devlock;
+    libxl_bitmap qemuu_cpus;
+} retrieve_domain_configuration_state;
+
+static void retrieve_domain_configuration_lock_acquired(
+    libxl__egc *egc, libxl__ev_devlock *, int rc);
+static void retrieve_domain_configuration_cpu_queried(
+    libxl__egc *egc, libxl__ev_qmp *qmp,
+    const libxl__json_object *response, int rc);
+static void retrieve_domain_configuration_timeout(libxl__egc *egc,
+    libxl__ev_time *ev, const struct timeval *requested_abs, int rc);
+static void retrieve_domain_configuration_end(libxl__egc *egc,
+    retrieve_domain_configuration_state *rdcs, int rc);
+
 int libxl_retrieve_domain_configuration(libxl_ctx *ctx, uint32_t domid,
                                         libxl_domain_config *d_config,
                                         const libxl_asyncop_how *ao_how)
 {
     AO_CREATE(ctx, domid, ao_how);
-    int rc;
+    retrieve_domain_configuration_state *rdcs;
+
+    GCNEW(rdcs);
+    libxl__ev_qmp_init(&rdcs->qmp);
+    rdcs->qmp.ao = ao;
+    rdcs->qmp.domid = domid;
+    rdcs->qmp.payload_fd = -1;
+    libxl__ev_time_init(&rdcs->timeout);
+    rdcs->d_config = d_config;
+    libxl_bitmap_init(&rdcs->qemuu_cpus);
+    libxl__ev_devlock_init(&rdcs->devlock);
+    rdcs->devlock.ao = ao;
+    rdcs->devlock.domid = domid;
+    rdcs->devlock.callback = retrieve_domain_configuration_lock_acquired;
+    libxl__ev_devlock_lock(egc, &rdcs->devlock);
+    return AO_INPROGRESS;
+}
+
+static void retrieve_domain_configuration_lock_acquired(
+    libxl__egc *egc, libxl__ev_devlock *devlock, int rc)
+{
+    retrieve_domain_configuration_state *rdcs =
+        CONTAINER_OF(devlock, *rdcs, devlock);
+    STATE_AO_GC(rdcs->qmp.ao);
     libxl__domain_userdata_lock *lock = NULL;
+    bool has_callback = false;
+
+    /* Convenience aliases */
+    libxl_domid domid = rdcs->qmp.domid;
+    libxl_domain_config *const d_config = rdcs->d_config;
+
+    if (rc) goto out;
 
     lock = libxl__lock_domain_userdata(gc, domid);
     if (!lock) {
@@ -1870,10 +1897,81 @@ int libxl_retrieve_domain_configuration(libxl_ctx *ctx, uint32_t domid,
         goto out;
     }
 
+    libxl__unlock_domain_userdata(lock);
+    lock = NULL;
+
+    /* We start by querying QEMU, if it is running, for its cpumap as this
+     * is a long operation. */
+    if (d_config->b_info.type == LIBXL_DOMAIN_TYPE_HVM &&
+        libxl__device_model_version_running(gc, domid) ==
+            LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN) {
+        /* For QEMU upstream we always need to provide the number
+         * of cpus present to QEMU whether they are online or not;
+         * otherwise QEMU won't accept the saved state.
+         */
+        rc = libxl__ev_time_register_rel(ao, &rdcs->timeout,
+            retrieve_domain_configuration_timeout,
+            LIBXL_QMP_CMD_TIMEOUT * 1000);
+        if (rc) goto out;
+        libxl_bitmap_alloc(CTX, &rdcs->qemuu_cpus,
+                           d_config->b_info.max_vcpus);
+        rdcs->qmp.callback = retrieve_domain_configuration_cpu_queried;
+        rc = libxl__ev_qmp_send(gc, &rdcs->qmp, "query-cpus", NULL);
+        if (rc) goto out;
+        has_callback = true;
+    }
+
+out:
+    if (lock) libxl__unlock_domain_userdata(lock);
+    if (!has_callback)
+        retrieve_domain_configuration_end(egc, rdcs, rc);
+}
+
+static void retrieve_domain_configuration_cpu_queried(
+    libxl__egc *egc, libxl__ev_qmp *qmp,
+    const libxl__json_object *response, int rc)
+{
+    EGC_GC;
+    retrieve_domain_configuration_state *rdcs =
+        CONTAINER_OF(qmp, *rdcs, qmp);
+
+    if (rc) goto out;
+
+    rc = qmp_parse_query_cpus(gc, qmp->domid, response, &rdcs->qemuu_cpus);
+
+out:
+    retrieve_domain_configuration_end(egc, rdcs, rc);
+}
+
+static void retrieve_domain_configuration_timeout(libxl__egc *egc,
+    libxl__ev_time *ev, const struct timeval *requested_abs, int rc)
+{
+    retrieve_domain_configuration_state *rdcs =
+        CONTAINER_OF(ev, *rdcs, timeout);
+
+    retrieve_domain_configuration_end(egc, rdcs, rc);
+}
+
+static void retrieve_domain_configuration_end(libxl__egc *egc,
+    retrieve_domain_configuration_state *rdcs, int rc)
+{
+    STATE_AO_GC(rdcs->qmp.ao);
+    libxl__domain_userdata_lock *lock;
+
+    /* Convenience aliases */
+    libxl_domain_config *const d_config = rdcs->d_config;
+    libxl_domid domid = rdcs->qmp.domid;
+
+    lock = libxl__lock_domain_userdata(gc, domid);
+    if (!lock) {
+        rc = ERROR_LOCK_FAIL;
+        goto out;
+    }
+
     /* Domain name */
     {
         char *domname;
-        domname = libxl_domid_to_name(ctx, domid);
+        domname = libxl_domid_to_name(CTX, domid);
         if (!domname) {
             LOGD(ERROR, domid, "Fail to get domain name");
             goto out;
@@ -1886,13 +1984,13 @@ int libxl_retrieve_domain_configuration(libxl_ctx *ctx, uint32_t domid,
     {
         libxl_dominfo info;
         libxl_dominfo_init(&info);
-        rc = libxl_domain_info(ctx, &info, domid);
+        rc = libxl_domain_info(CTX, &info, domid);
         if (rc) {
             LOGD(ERROR, domid, "Fail to get domain info");
             libxl_dominfo_dispose(&info);
             goto out;
         }
-        libxl_uuid_copy(ctx, &d_config->c_info.uuid, &info.uuid);
+        libxl_uuid_copy(CTX, &d_config->c_info.uuid, &info.uuid);
         libxl_dominfo_dispose(&info);
     }
 
@@ -1913,8 +2011,7 @@ int libxl_retrieve_domain_configuration(libxl_ctx *ctx, uint32_t domid,
             assert(version != LIBXL_DEVICE_MODEL_VERSION_UNKNOWN);
             switch (version) {
             case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
-                rc = libxl__update_avail_vcpus_qmp(gc, domid,
-                                                   max_vcpus, map);
+                libxl_bitmap_copy(CTX, map, &rdcs->qemuu_cpus);
                 break;
             case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL:
                 rc = libxl__update_avail_vcpus_xenstore(gc, domid,
@@ -1939,6 +2036,7 @@ int libxl_retrieve_domain_configuration(libxl_ctx *ctx, uint32_t domid,
         }
     }
 
+
     /* Memory limits:
      *
      * Currently there are three memory limits:
@@ -1972,7 +2070,7 @@ int libxl_retrieve_domain_configuration(libxl_ctx *ctx, uint32_t domid,
     /* Scheduler params */
     {
         libxl_domain_sched_params_dispose(&d_config->b_info.sched_params);
-        rc = libxl_domain_sched_params_get(ctx, domid,
+        rc = libxl_domain_sched_params_get(CTX, domid,
                                            &d_config->b_info.sched_params);
         if (rc) {
             LOGD(ERROR, domid, "Fail to get scheduler parameters");
@@ -2034,7 +2132,7 @@ int libxl_retrieve_domain_configuration(libxl_ctx *ctx, uint32_t domid,
 
                 if (j < num) {         /* found in xenstore */
                     if (dt->merge)
-                        dt->merge(ctx, p + dt->dev_elem_size * j, q);
+                        dt->merge(CTX, p + dt->dev_elem_size * j, q);
                 } else {                /* not found in xenstore */
                     LOGD(WARN, domid,
                          "Device present in JSON but not in xenstore, ignored");
@@ -2062,11 +2160,12 @@ int libxl_retrieve_domain_configuration(libxl_ctx *ctx, uint32_t domid,
     }
 
 out:
+    libxl__ev_devlock_unlock(gc, &rdcs->devlock);
     if (lock) libxl__unlock_domain_userdata(lock);
-    if (rc)
-        return AO_CREATE_FAIL(rc);
+    libxl_bitmap_dispose(&rdcs->qemuu_cpus);
+    libxl__ev_qmp_dispose(gc, &rdcs->qmp);
+    libxl__ev_time_deregister(gc, &rdcs->timeout);
     libxl__ao_complete(egc, ao, rc);
-    return AO_INPROGRESS;
 }
 
 /*
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 1ecebf136984..bfeb38e0eda3 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1988,9 +1988,6 @@ _hidden libxl__qmp_handler *libxl__qmp_initialize(libxl__gc *gc,
 _hidden int libxl__qmp_resume(libxl__gc *gc, int domid);
 /* Load current QEMU state from file. */
 _hidden int libxl__qmp_restore(libxl__gc *gc, int domid, const char *filename);
-/* Query the bitmap of CPUs */
-_hidden int libxl__qmp_query_cpus(libxl__gc *gc, int domid,
-                                  libxl_bitmap *map);
 /* Start NBD server */
 _hidden int libxl__qmp_nbd_server_start(libxl__gc *gc, int domid,
                                         const char *host, const char *port);
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index 27183bc6c4a3..9639d491d991 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -767,44 +767,6 @@ int libxl__qmp_resume(libxl__gc *gc, int domid)
     return qmp_run_command(gc, domid, "cont", NULL, NULL, NULL);
 }
 
-static int query_cpus_callback(libxl__qmp_handler *qmp,
-                               const libxl__json_object *response,
-                               void *opaque)
-{
-    libxl_bitmap *map = opaque;
-    unsigned int i;
-    const libxl__json_object *cpu = NULL;
-    int rc;
-    GC_INIT(qmp->ctx);
-
-    libxl_bitmap_set_none(map);
-    for (i = 0; (cpu = libxl__json_array_get(response, i)); i++) {
-        unsigned int idx;
-        const libxl__json_object *o;
-
-        o = libxl__json_map_get("CPU", cpu, JSON_INTEGER);
-        if (!o) {
-            LOGD(ERROR, qmp->domid, "Failed to retrieve CPU index.");
-            rc = ERROR_FAIL;
-            goto out;
-        }
-
-        idx = libxl__json_object_get_integer(o);
-        libxl_bitmap_set(map, idx);
-    }
-
-    rc = 0;
-out:
-    GC_FREE;
-    return rc;
-}
-
-int libxl__qmp_query_cpus(libxl__gc *gc, int domid, libxl_bitmap *map)
-{
-    return qmp_run_command(gc, domid, "query-cpus", NULL,
-                           query_cpus_callback, map);
-}
-
 int libxl__qmp_nbd_server_start(libxl__gc *gc, int domid,
                                 const char *host, const char *port)
 {
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 34/35] libxl: libxl_qemu_monitor_command now uses ev_qmp
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (32 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 33/35] libxl: libxl_retrieve_domain_configuration now uses ev_qmp Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 35/35] libxl_pci: Extract common part of *qemu_trad_watch_state_cb Anthony PERARD
  2019-09-19 19:19 ` [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Ian Jackson
  35 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_qmp.c | 52 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 50 insertions(+), 2 deletions(-)

diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index 9639d491d991..9aabad74fabd 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -892,19 +892,67 @@ int libxl__qmp_hmp(libxl__gc *gc, int domid, const char *command_line,
                            hmp_callback, output);
 }
 
+
+typedef struct {
+    libxl__ev_qmp qmp;
+    char **output; /* user pointer */
+} qemu_monitor_command_state;
+
+static void qemu_monitor_command_done(libxl__egc *, libxl__ev_qmp *,
+                                      const libxl__json_object *response,
+                                      int rc);
+
 int libxl_qemu_monitor_command(libxl_ctx *ctx, uint32_t domid,
                                const char *command_line, char **output,
                                const libxl_asyncop_how *ao_how)
 {
     AO_CREATE(ctx, domid, ao_how);
+    qemu_monitor_command_state *qmcs;
+    libxl__json_object *args = NULL;
     int rc;
 
-    rc = libxl__qmp_hmp(gc, domid, command_line, output);
+    if (!output) {
+        rc = ERROR_INVAL;
+        goto out;
+    }
 
-    libxl__ao_complete(egc, ao, rc);
+    GCNEW(qmcs);
+    libxl__ev_qmp_init(&qmcs->qmp);
+    qmcs->qmp.ao = ao;
+    qmcs->qmp.domid = domid;
+    qmcs->qmp.payload_fd = -1;
+    qmcs->qmp.callback = qemu_monitor_command_done;
+    qmcs->output = output;
+    libxl__qmp_param_add_string(gc, &args, "command-line", command_line);
+    rc = libxl__ev_qmp_send(gc, &qmcs->qmp, "human-monitor-command", args);
+out:
+    if (rc) return AO_CREATE_FAIL(rc);
     return AO_INPROGRESS;
 }
 
+static void qemu_monitor_command_done(libxl__egc *egc, libxl__ev_qmp *qmp,
+                                      const libxl__json_object *response,
+                                      int rc)
+{
+    STATE_AO_GC(qmp->ao);
+    qemu_monitor_command_state *qmcs = CONTAINER_OF(qmp, *qmcs, qmp);
+
+    if (rc) goto out;
+
+    if (!libxl__json_object_is_string(response)) {
+        rc = ERROR_QEMU_API;
+        LOGD(ERROR, qmp->domid, "Response has unexpected format");
+        goto out;
+    }
+
+    *(qmcs->output) =
+        libxl__strdup(NOGC, libxl__json_object_get_string(response));
+    rc = 0;
+
+out:
+    libxl__ev_qmp_dispose(gc, qmp);
+    libxl__ao_complete(egc, ao, rc);
+}
 
 /*
  * Functions using libxl__ev_qmp
-- 
Anthony PERARD


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

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

* [Xen-devel] [PATCH v2 35/35] libxl_pci: Extract common part of *qemu_trad_watch_state_cb
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (33 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 34/35] libxl: libxl_qemu_monitor_command " Anthony PERARD
@ 2019-09-19 17:16 ` Anthony PERARD
  2019-09-19 19:18   ` Ian Jackson
  2019-09-19 19:19 ` [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Ian Jackson
  35 siblings, 1 reply; 41+ messages in thread
From: Anthony PERARD @ 2019-09-19 17:16 UTC (permalink / raw)
  To: xen-devel; +Cc: Anthony PERARD, Ian Jackson, Wei Liu

Functions pci_add_qemu_trad_watch_state_cb and
pci_remove_qemu_trad_watch_state_cb are similar so the common part is
extracted in a different function.

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

Notes:
    v2:
    - new patch which attempt to combine the "basically-identical" functions
      pci_{add,remove}_qemu_trad_watch_state_cb

 tools/libxl/libxl_pci.c | 51 +++++++++++++++++++++++------------------
 1 file changed, 29 insertions(+), 22 deletions(-)

diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c
index 2c4e2e5cff5e..47258177bc71 100644
--- a/tools/libxl/libxl_pci.c
+++ b/tools/libxl/libxl_pci.c
@@ -984,6 +984,27 @@ static int qemu_pci_add_xenstore(libxl__gc *gc, uint32_t domid,
     return rc;
 }
 
+static int check_qemu_running(libxl__gc *gc,
+                              libxl_domid domid,
+                              libxl__xswait_state *xswa,
+                              int rc,
+                              const char *state)
+{
+    if (rc) {
+        if (rc == ERROR_TIMEDOUT) {
+            LOGD(ERROR, domid, "%s not ready", xswa->what);
+        }
+        goto out;
+    }
+
+    if (!state || strcmp(state, "running"))
+        return ERROR_NOT_READY;
+
+out:
+    libxl__xswait_stop(gc, xswa);
+    return rc;
+}
+
 typedef struct pci_add_state {
     /* filled by user of do_pci_add */
     libxl__ao_device *aodev;
@@ -1071,21 +1092,14 @@ static void pci_add_qemu_trad_watch_state_cb(libxl__egc *egc,
     libxl_domid domid = pas->domid;
     libxl_device_pci *pcidev = pas->pcidev;
 
-    if (rc) {
-        if (rc == ERROR_TIMEDOUT) {
-            LOGD(ERROR, domid, "%s not ready", xswa->what);
-        }
-        goto out;
-    }
-
-    if (!state)
-        return;
-    if (strcmp(state, "running"))
+    rc = check_qemu_running(gc, domid, xswa, rc, state);
+    if (rc == ERROR_NOT_READY)
         return;
+    if (rc)
+        goto out;
 
     rc = qemu_pci_add_xenstore(gc, domid, pcidev);
 out:
-    libxl__xswait_stop(gc, xswa);
     pci_add_dm_done(egc, pas, rc); /* must be last */
 }
 
@@ -1893,22 +1907,15 @@ static void pci_remove_qemu_trad_watch_state_cb(libxl__egc *egc,
     libxl_domid domid = prs->domid;
     libxl_device_pci *const pcidev = prs->pcidev;
 
-    if (rc) {
-        if (rc == ERROR_TIMEDOUT) {
-            LOGD(ERROR, domid, "%s not ready", xswa->what);
-        }
-        goto out;
-    }
-
-    if (!state)
-        return;
-    if (strcmp(state, "running"))
+    rc = check_qemu_running(gc, domid, xswa, rc, state);
+    if (rc == ERROR_NOT_READY)
         return;
+    if (rc)
+        goto out;
 
     rc = qemu_pci_remove_xenstore(gc, domid, pcidev, prs->force);
 
 out:
-    libxl__xswait_stop(gc, xswa);
     pci_remove_detatched(egc, prs, rc);
 }
 
-- 
Anthony PERARD


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

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

* Re: [Xen-devel] [PATCH v2 06/35] libxl: Use ev_qmp for switch_qemu_xen_logdirty
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 06/35] libxl: Use ev_qmp for switch_qemu_xen_logdirty Anthony PERARD
@ 2019-09-19 19:14   ` Ian Jackson
  0 siblings, 0 replies; 41+ messages in thread
From: Ian Jackson @ 2019-09-19 19:14 UTC (permalink / raw)
  To: Anthony PERARD; +Cc: xen-devel, Wei Liu

Anthony PERARD writes ("[PATCH v2 06/35] libxl: Use ev_qmp for switch_qemu_xen_logdirty"):
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>

Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>

(in line with my previous comments)

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

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

* Re: [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) [and 1 more messages]
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 32/35] libxl: Use ev_qmp in libxl_set_vcpuonline Anthony PERARD
@ 2019-09-19 19:17   ` Ian Jackson
  2019-09-20  9:48     ` Anthony PERARD
  0 siblings, 1 reply; 41+ messages in thread
From: Ian Jackson @ 2019-09-19 19:17 UTC (permalink / raw)
  To: Anthony PERARD; +Cc: xen-devel, Wei Liu

Anthony PERARD writes ("[PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes)"):
> Patches with missing ackes:
...
>     libxl: Use ev_qmp in libxl_set_vcpuonline

From my point of view I seem to have sent a ack for this,

   Message-ID: <23937.6842.426857.800866@mariner.uk.xensource.com>
   In-Reply-To: <20190802153606.32061-33-anthony.perard@citrix.com>
   References: <20190802153606.32061-1-anthony.perard@citrix.com>
           <20190802153606.32061-33-anthony.perard@citrix.com>
   From: Ian Jackson <ian.jackson@citrix.com>
   To: Anthony PERARD <anthony.perard@citrix.com>
   Cc: "xen-devel@lists.xenproject.org" <xen-devel@lists.xenproject.org>,
       Wei Liu <wl@xen.org>
   Subject: Re: [PATCH 32/35] libxl: Use ev_qmp in libxl_set_vcpuonline
   Date: Tue, 17 Sep 2019 18:41:14 +0100

?  I hope it's not mail going missing again...

Thanks,
Ian.

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

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

* Re: [Xen-devel] [PATCH v2 35/35] libxl_pci: Extract common part of *qemu_trad_watch_state_cb
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 35/35] libxl_pci: Extract common part of *qemu_trad_watch_state_cb Anthony PERARD
@ 2019-09-19 19:18   ` Ian Jackson
  0 siblings, 0 replies; 41+ messages in thread
From: Ian Jackson @ 2019-09-19 19:18 UTC (permalink / raw)
  To: Anthony PERARD; +Cc: xen-devel, Wei Liu

Anthony PERARD writes ("[PATCH v2 35/35] libxl_pci: Extract common part of *qemu_trad_watch_state_cb"):
> Functions pci_add_qemu_trad_watch_state_cb and
> pci_remove_qemu_trad_watch_state_cb are similar so the common part is
> extracted in a different function.

OK (though not quite how I would have done it; maybe simpler than what
I had in mind).

Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>

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

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

* Re: [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes)
  2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
                   ` (34 preceding siblings ...)
  2019-09-19 17:16 ` [Xen-devel] [PATCH v2 35/35] libxl_pci: Extract common part of *qemu_trad_watch_state_cb Anthony PERARD
@ 2019-09-19 19:19 ` Ian Jackson
  35 siblings, 0 replies; 41+ messages in thread
From: Ian Jackson @ 2019-09-19 19:19 UTC (permalink / raw)
  To: Anthony PERARD; +Cc: xen-devel, Wei Liu

Anthony PERARD writes ("[PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes)"):
> Patches with missing ackes:
>     libxl: Use ev_qmp for switch_qemu_xen_logdirty
>     libxl: Use ev_qmp in libxl_set_vcpuonline
>     libxl_pci: Extract common part of *qemu_trad_watch_state_cb
> 
> The series depends on "Some cleanup of libxl" series.
> Patch series available in this git branch (which is on top of the branch
> br.libxl-cleanup-v2):
> https://xenbits.xen.org/git-http/people/aperard/xen-unstable.git br.libxl-ev_qmp-refactoring-v2

So, I think this is all good now and I will commit both these
remaining series when I get into the office tomorrow.

Ian.

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

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

* Re: [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) [and 1 more messages]
  2019-09-19 19:17   ` [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) [and 1 more messages] Ian Jackson
@ 2019-09-20  9:48     ` Anthony PERARD
  0 siblings, 0 replies; 41+ messages in thread
From: Anthony PERARD @ 2019-09-20  9:48 UTC (permalink / raw)
  To: Ian Jackson; +Cc: xen-devel, Wei Liu

On Thu, Sep 19, 2019 at 08:17:43PM +0100, Ian Jackson wrote:
> Anthony PERARD writes ("[PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes)"):
> > Patches with missing ackes:
> ...
> >     libxl: Use ev_qmp in libxl_set_vcpuonline
> 
> From my point of view I seem to have sent a ack for this,
> 
>    Message-ID: <23937.6842.426857.800866@mariner.uk.xensource.com>
>    In-Reply-To: <20190802153606.32061-33-anthony.perard@citrix.com>
>    References: <20190802153606.32061-1-anthony.perard@citrix.com>
>            <20190802153606.32061-33-anthony.perard@citrix.com>
>    From: Ian Jackson <ian.jackson@citrix.com>
>    To: Anthony PERARD <anthony.perard@citrix.com>
>    Cc: "xen-devel@lists.xenproject.org" <xen-devel@lists.xenproject.org>,
>        Wei Liu <wl@xen.org>
>    Subject: Re: [PATCH 32/35] libxl: Use ev_qmp in libxl_set_vcpuonline
>    Date: Tue, 17 Sep 2019 18:41:14 +0100
> 
> ?  I hope it's not mail going missing again...

I didn't carry the acks because I've squashed a patch into this one and
I've change the commit message (adding an extra paragraph to reflect the
squashed commit).

-- 
Anthony PERARD

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

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

end of thread, other threads:[~2019-09-20  9:48 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-19 17:16 [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 01/35] libxl: Make libxl_domain_unpause async Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 02/35] libxl: Make libxl_send_trigger async Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 03/35] libxl: Make libxl_set_vcpuonline async Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 04/35] libxl: Make libxl_retrieve_domain_configuration async Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 05/35] libxl: Make libxl_qemu_monitor_command async Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 06/35] libxl: Use ev_qmp for switch_qemu_xen_logdirty Anthony PERARD
2019-09-19 19:14   ` Ian Jackson
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 07/35] libxl: Move "qmp_initializations" to libxl_dm Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 08/35] libxl: Replace libxl__qmp_initializations by ev_qmp calls Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 09/35] libxl: Deprecate libxl__domain_{unpause, resume} Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 10/35] libxl: Re-introduce libxl__domain_resume Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 11/35] libxl_domain: Convert libxl_domain_resume to use libxl__domain_resume Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 12/35] libxl: Re-introduce libxl__domain_unpause Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 13/35] libxl_dm: Update libxl__spawn_stub_dm to use libxl__domain_unpause Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 14/35] libxl_domain: Convert libxl_domain_unpause " Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 15/35] libxl: Inline do_usbdev_add into libxl__device_usbdev_add Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 16/35] libxl: Inline do_usbdev_remove into libxl__device_usbdev_remove Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 17/35] libxl: Add libxl__ev_qmp to libxl__ao_device Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 18/35] libxl: Add device_{config, type} " Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 19/35] libxl_usb: Make libxl__device_usbctrl_add uses ev_qmp Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 20/35] libxl_usb: Make libxl__initiate_device_usbctrl_remove " Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 21/35] libxl_usb: Make libxl__device_usbdev_add " Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 22/35] libxl: Use aodev for libxl__device_usbdev_remove Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 23/35] libxl: libxl__initiate_device_usbdev_remove now use ev_qmp Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 24/35] libxl: Remove libxl__qmp_run_command_flexarray Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 25/35] libxl_pci: Coding style of do_pci_add Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 26/35] libxl_pci: Only check if qemu-dm is running in qemu-trad case Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 27/35] libxl_pci: Use libxl__ao_device with libxl__device_pci_add Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 28/35] libxl_pci: Use ev_qmp in do_pci_add Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 29/35] libxl_pci: Use libxl__ao_device with pci_remove Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 30/35] libxl_pci: Use ev_qmp for pci_remove Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 31/35] libxl: Use ev_qmp for libxl_send_trigger Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 32/35] libxl: Use ev_qmp in libxl_set_vcpuonline Anthony PERARD
2019-09-19 19:17   ` [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) [and 1 more messages] Ian Jackson
2019-09-20  9:48     ` Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 33/35] libxl: libxl_retrieve_domain_configuration now uses ev_qmp Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 34/35] libxl: libxl_qemu_monitor_command " Anthony PERARD
2019-09-19 17:16 ` [Xen-devel] [PATCH v2 35/35] libxl_pci: Extract common part of *qemu_trad_watch_state_cb Anthony PERARD
2019-09-19 19:18   ` Ian Jackson
2019-09-19 19:19 ` [Xen-devel] [PATCH v2 00/35] libxl refactoring to use ev_qmp (with API changes) Ian Jackson

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.