xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Wei Liu <wei.liu2@citrix.com>
To: xen-devel@lists.xen.org
Cc: Wei Liu <wei.liu2@citrix.com>,
	ian.jackson@eu.citrix.com, ian.campbell@citrix.com
Subject: [PATCH V5 32/32] libxl: synchronize configuration when we plug / unplug device
Date: Tue, 13 May 2014 22:54:14 +0100	[thread overview]
Message-ID: <1400018054-26038-33-git-send-email-wei.liu2@citrix.com> (raw)
In-Reply-To: <1400018054-26038-1-git-send-email-wei.liu2@citrix.com>

We synchronize domain configuration in the callback, right before we
return to caller. We depends solely on the return value of AO to
determine if AO is successful.

This approach cannot deal with half-baked device state (say, if AO
returns success but for various reasons other parts just fail and we
have some xenstore entries written / resource allocated). However we
cannot make thing worse as the original code cannot handle that either.
The good side of this approach is that in the future we can compare the
stored configuration and xenstore entries to spot any half-baked device
state so it can help fix that issue in the future.

Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
 tools/libxl/libxl.c          |  152 +++++++++++++++++++++++++++++++++++-------
 tools/libxl/libxl_internal.h |    2 +
 2 files changed, 129 insertions(+), 25 deletions(-)

diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index f93096b..a7bf0a4 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -1794,29 +1794,6 @@ out:
 
 /******************************************************************************/
 
-/* generic callback for devices that only need to set ao_complete */
-static void device_addrm_aocomplete(libxl__egc *egc, libxl__ao_device *aodev)
-{
-    STATE_AO_GC(aodev->ao);
-
-    if (aodev->rc) {
-        if (aodev->dev) {
-            LOG(ERROR, "unable to %s %s with id %u",
-                        libxl__device_action_to_string(aodev->action),
-                        libxl__device_kind_to_string(aodev->dev->kind),
-                        aodev->dev->devid);
-        } else {
-            LOG(ERROR, "unable to %s device",
-                       libxl__device_action_to_string(aodev->action));
-        }
-        goto out;
-    }
-
-out:
-    libxl__ao_complete(egc, ao, aodev->rc);
-    return;
-}
-
 /* common function to get next device id */
 static int libxl__device_nextid(libxl__gc *gc, uint32_t domid, char *device)
 {
@@ -3548,6 +3525,126 @@ out:
     }                                                                   \
     libxl_domain_config_dispose(&d_config);                             \
 
+static void device_nic_fixup(libxl_ctx *ctx, libxl_device_nic *dst,
+                             libxl_device_nic *src)
+{
+    dst->devid = src->devid;
+    libxl_mac_copy(ctx, &dst->mac, &src->mac);
+}
+
+static void device_vtpm_fixup(libxl_ctx *ctx, libxl_device_vtpm *dst,
+                              libxl_device_vtpm *src)
+{
+    libxl_uuid_copy(ctx, &dst->uuid, &src->uuid);
+}
+
+static void device_disk_fixup(libxl_ctx *ctx, libxl_device_disk *dst,
+                              libxl_device_disk *src)
+{
+}
+
+#define DEVICE_AO_FAILED_MSG                                            \
+    do {                                                                \
+        if (aodev->dev) {                                               \
+            LOG(ERROR, "unable to %s %s with id %u",                    \
+                libxl__device_action_to_string(aodev->action),          \
+                libxl__device_kind_to_string(aodev->dev->kind),         \
+                aodev->dev->devid);                                     \
+        } else {                                                        \
+            LOG(ERROR, "unable to %s device",                           \
+                libxl__device_action_to_string(aodev->action));         \
+        }                                                               \
+    } while (0)
+
+
+#define DEFINE_DEVICE_ADD_AOCOMPLETE(type,ptr,cnt)                      \
+    static void device_add_##type##_aocomplete(libxl__egc *egc,         \
+                                               libxl__ao_device *aodev) \
+    {                                                                   \
+        STATE_AO_GC(aodev->ao);                                         \
+        int rc;                                                         \
+                                                                        \
+        if (aodev->rc) {                                                \
+            DEVICE_AO_FAILED_MSG;                                       \
+            goto out;                                                   \
+        } else {                                                        \
+            libxl_device_##type *p;                                     \
+                                                                        \
+            LOAD_DOMAIN_CONFIG(aodev->dev->domid);                      \
+                                                                        \
+            d_config.ptr =                                              \
+                libxl__realloc(gc, d_config.ptr,                        \
+                               (d_config.cnt + 1) *                     \
+                               sizeof(libxl_device_##type));            \
+            p = &d_config.ptr[d_config.cnt];                            \
+            d_config.cnt++;                                             \
+                                                                        \
+            libxl_device_##type##_copy(CTX, p, aodev->pdev_copy);       \
+                                                                        \
+            device_##type##_fixup(CTX, p, aodev->pdev);                 \
+                                                                        \
+            STORE_DOMAIN_CONFIG(aodev->dev->domid);                     \
+        }                                                               \
+                                                                        \
+    out:                                                                \
+        /* Dispose our internal copy, which is allocated at the entry of \
+         * this AO. */                                                  \
+        libxl_device_##type##_dispose(aodev->pdev_copy);                \
+        libxl__ao_complete(egc, ao, aodev->rc);                         \
+        return;                                                         \
+    }
+
+DEFINE_DEVICE_ADD_AOCOMPLETE(nic, nics, num_nics);
+DEFINE_DEVICE_ADD_AOCOMPLETE(vtpm, vtpms, num_vtpms);
+DEFINE_DEVICE_ADD_AOCOMPLETE(disk, disks, num_disks);
+
+#define COMPARE_DEVID(a, b) ((a)->devid == (b)->devid)
+#define COMPARE_DISK(a, b) (!strcmp((a)->vdev, (b)->vdev))
+
+#define DEFINE_DEVICE_RM_AOCOMPLETE(type,ptr,cnt,compare)               \
+    static void device_rm_##type##_aocomplete(libxl__egc *egc,          \
+                                              libxl__ao_device *aodev)  \
+    {                                                                   \
+        STATE_AO_GC(aodev->ao);                                         \
+        int rc;                                                         \
+                                                                        \
+        if (aodev->rc) {                                                \
+            DEVICE_AO_FAILED_MSG;                                       \
+            goto out;                                                   \
+        } else {                                                        \
+            int i, j;                                                   \
+            libxl_device_##type *p = aodev->pdev;                       \
+            LOAD_DOMAIN_CONFIG(aodev->dev->domid);                      \
+                                                                        \
+            for (i = j = 0; i < d_config.cnt; i++) {                    \
+                if (!compare(&d_config.ptr[i], p)) {                    \
+                    if (i != j) {                                       \
+                        libxl_device_##type##_dispose(&d_config.ptr[j]);\
+                        d_config.ptr[j] = d_config.ptr[i];              \
+                    }                                                   \
+                    j++;                                                \
+                }                                                       \
+            }                                                           \
+                                                                        \
+            d_config.ptr =                                              \
+                libxl__realloc(gc, d_config.ptr,                        \
+                               j * sizeof(libxl_device_##type));        \
+            d_config.cnt = j;                                           \
+                                                                        \
+            STORE_DOMAIN_CONFIG(aodev->dev->domid);                     \
+        }                                                               \
+                                                                        \
+    out:                                                                \
+        libxl__ao_complete(egc, ao, aodev->rc);                         \
+        return;                                                         \
+    }
+
+DEFINE_DEVICE_RM_AOCOMPLETE(nic, nics, num_nics, COMPARE_DEVID);
+DEFINE_DEVICE_RM_AOCOMPLETE(vtpm, vtpms, num_vtpms, COMPARE_DEVID);
+DEFINE_DEVICE_RM_AOCOMPLETE(disk, disks, num_disks, COMPARE_DISK);
+DEFINE_DEVICE_RM_AOCOMPLETE(vkb, vkbs, num_vkbs, COMPARE_DEVID);
+DEFINE_DEVICE_RM_AOCOMPLETE(vfb, vfbs, num_vfbs, COMPARE_DEVID);
+
 /* Macro for defining device remove/destroy functions in a compact way */
 /* The following functions are defined:
  * libxl_device_disk_remove
@@ -3577,9 +3674,11 @@ out:
                                                                         \
         GCNEW(aodev);                                                   \
         libxl__prepare_ao_device(ao, aodev);                            \
+        aodev->pdev = type;                                             \
+        aodev->pdev_copy = NULL; /* unused */                           \
         aodev->action = LIBXL__DEVICE_ACTION_REMOVE;                    \
         aodev->dev = device;                                            \
-        aodev->callback = device_addrm_aocomplete;                      \
+        aodev->callback = device_rm_##type##_aocomplete;                \
         aodev->force = f;                                               \
         libxl__initiate_device_remove(egc, aodev);                      \
                                                                         \
@@ -3631,8 +3730,11 @@ DEFINE_DEVICE_REMOVE(vtpm, destroy, 1)
         libxl__ao_device *aodev;                                        \
                                                                         \
         GCNEW(aodev);                                                   \
+        aodev->pdev = type;                                             \
+        aodev->pdev_copy = libxl__zalloc(gc, sizeof(*type));            \
+        libxl_device_##type##_copy(CTX, aodev->pdev_copy, aodev->pdev); \
         libxl__prepare_ao_device(ao, aodev);                            \
-        aodev->callback = device_addrm_aocomplete;                      \
+        aodev->callback = device_add_##type##_aocomplete;               \
         libxl__device_##type##_add(egc, domid, type, aodev);            \
                                                                         \
         return AO_INPROGRESS;                                           \
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 21bb774..06503df 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -2106,6 +2106,8 @@ struct libxl__ao_device {
     const char *what;
     int num_exec;
     libxl__ev_child child;
+    void *pdev; /* pointer to libxl_device_nic/vtpm/disk etc. */
+    void *pdev_copy; /* a copy of vanilla structure pointed to by pdev. */
 };
 
 /*
-- 
1.7.10.4

  parent reply	other threads:[~2014-05-13 21:54 UTC|newest]

Thread overview: 127+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-13 21:53 [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Wei Liu
2014-05-13 21:53 ` [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function Wei Liu
2014-05-15 16:28   ` Ian Campbell
2014-05-20 14:47     ` Ian Jackson
2014-05-20 17:24       ` Wei Liu
2014-05-21  8:27         ` Ian Campbell
2014-05-21  8:37         ` Comments on LIBXL_HAVE_* defines (Was: Re: [PATCH V5 01/32] libxl: make cpupool_qualifier_to_cpupoolid a library function) Ian Campbell
2014-05-22  9:35           ` George Dunlap
2014-05-27 23:04           ` Wei Liu
2014-05-13 21:53 ` [PATCH V5 02/32] xl / libxl: push parsing of SSID and CPU pool ID down to libxl Wei Liu
2014-05-15 16:38   ` Ian Campbell
2014-05-15 17:11     ` Wei Liu
2014-05-13 21:53 ` [PATCH V5 03/32] xl / libxl: push VCPU affinity pinning " Wei Liu
2014-05-15  0:59   ` Dario Faggioli
2014-05-15  9:24     ` Wei Liu
2014-05-15 15:31       ` Dario Faggioli
2014-05-15 15:37         ` Wei Liu
2014-05-15 16:45   ` Ian Campbell
2014-05-15 17:06     ` Wei Liu
2014-05-15 17:19       ` Wei Liu
2014-05-16  9:51         ` Ian Campbell
2014-05-16  8:10       ` Dario Faggioli
2014-05-16  9:57       ` Ian Campbell
2014-05-16 10:15         ` Wei Liu
2014-05-16 10:28           ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 04/32] libxl: libxl_uuid_copy now taks a ctx argument Wei Liu
2014-05-15 16:51   ` Ian Campbell
2014-05-15 17:13     ` Wei Liu
2014-05-16  9:46       ` Ian Campbell
2014-05-16 10:18         ` Wei Liu
2014-05-16 10:30           ` Ian Campbell
2014-05-16 11:17             ` Wei Liu
2014-05-16 11:21               ` Wei Liu
2014-05-16 11:23                 ` Ian Campbell
2014-05-16 11:28                   ` Wei Liu
2014-05-16 11:31                     ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 05/32] xl: remove parsing of "vncviewer" option in xl domain config file Wei Liu
2014-05-20 12:44   ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 06/32] libxl: fix memory leak in libxl_cpuid_dispose Wei Liu
2014-05-13 21:53 ` [PATCH V5 07/32] libxl.h: document the paradigm of using libxl types Wei Liu
2014-05-20 12:49   ` Ian Campbell
2014-05-20 14:54     ` Ian Jackson
2014-05-20 15:02       ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 08/32] libxl.h: document libxl_<type>_to_json Wei Liu
2014-05-20 12:50   ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 09/32] libxl_internal.h: move / add some libxl defbool #define here Wei Liu
2014-05-20 12:51   ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 10/32] libxl: fix JSON generator for uint64_t Wei Liu
2014-05-20 12:55   ` Ian Campbell
2014-05-20 13:15     ` Wei Liu
2014-05-13 21:53 ` [PATCH V5 11/32] libxl IDL: rename json_fn to json_gen_fn Wei Liu
2014-05-13 21:53 ` [PATCH V5 12/32] libxl_json: introduce libxl__object_from_json Wei Liu
2014-05-13 21:53 ` [PATCH V5 13/32] libxl_internal: make JSON_* types a bit-field Wei Liu
2014-05-13 21:53 ` [PATCH V5 14/32] libxl_internal.h: introduce libxl__json_object_is_{null, number, double} Wei Liu
2014-05-13 21:53 ` [PATCH V5 15/32] libxl_internal.h: introduce libxl__json_object_get_number Wei Liu
2014-05-20 12:56   ` Ian Campbell
2014-05-20 15:11     ` Ian Campbell
2014-05-13 21:53 ` [PATCH V5 16/32] libxl_json: introduce parser functions for builtin types Wei Liu
2014-05-13 21:53 ` [PATCH V5 17/32] libxl_json: allow basic JSON type objects generation Wei Liu
2014-05-13 21:54 ` [PATCH V5 18/32] libxl/gentypes.py: special-case KeyedUnion map handle generation Wei Liu
2014-05-20 13:26   ` Ian Campbell
2014-05-13 21:54 ` [PATCH V5 19/32] libxl/gentypes.py: don't generate default values Wei Liu
2014-05-20 13:29   ` Ian Campbell
2014-05-20 17:17     ` Wei Liu
2014-05-21  8:31       ` Ian Campbell
2014-05-13 21:54 ` [PATCH V5 20/32] libxl IDL: generate code to parse libxl__json_object to libxl_FOO struct Wei Liu
2014-05-20 13:35   ` Ian Campbell
2014-06-01 17:43     ` Wei Liu
2014-05-13 21:54 ` [PATCH V5 21/32] libxl/gentest.py: test JSON parser Wei Liu
2014-05-13 21:54 ` [PATCH V5 22/32] libxl: introduce libxl_key_value_list_length Wei Liu
2014-05-20 13:36   ` Ian Campbell
2014-05-13 21:54 ` [PATCH V5 23/32] libxl: introduce libxl_cpuid_policy_list_length Wei Liu
2014-05-20 13:36   ` Ian Campbell
2014-05-13 21:54 ` [PATCH V5 24/32] libxl: copy function for builtin types Wei Liu
2014-05-20 13:39   ` Ian Campbell
2014-05-13 21:54 ` [PATCH V5 25/32] libxl IDL: generate deep copy functions Wei Liu
2014-05-20 13:42   ` Ian Campbell
2014-05-13 21:54 ` [PATCH V5 26/32] libxl/gentest.py: test " Wei Liu
2014-05-13 21:54 ` [PATCH V5 27/32] libxl: libxl-json format and load/store configuration functions Wei Liu
2014-05-20 14:03   ` Ian Campbell
2014-06-01 18:41     ` Wei Liu
2014-06-02 16:19       ` Ian Campbell
2014-06-02 19:56         ` Wei Liu
2014-05-20 15:01   ` Ian Jackson
2014-06-01 18:46     ` Wei Liu
2014-05-13 21:54 ` [PATCH V5 28/32] libxl: store up-to-date domain configuration as we create domain Wei Liu
2014-05-20 14:12   ` Ian Campbell
2014-06-01 19:02     ` Wei Liu
2014-06-02 16:21       ` Ian Campbell
2014-05-20 15:04   ` Ian Jackson
2014-05-13 21:54 ` [PATCH V5 29/32] xl: use "libxl-json" format Wei Liu
2014-05-20 14:23   ` Ian Campbell
2014-05-20 15:13     ` Ian Jackson
2014-05-20 15:31       ` Ian Campbell
2014-06-01 19:37     ` Wei Liu
2014-06-02 16:30       ` Ian Campbell
2014-06-03 10:02         ` Wei Liu
2014-06-03 10:34           ` Ian Campbell
2014-05-20 15:11   ` Ian Jackson
2014-05-20 15:15     ` Ian Campbell
2014-05-20 15:39       ` Ian Jackson
2014-06-01 19:18         ` Wei Liu
2014-06-01 19:07     ` Wei Liu
2014-06-02 16:23       ` Ian Campbell
2014-05-13 21:54 ` [PATCH V5 30/32] libxl: consider force removal of device successful Wei Liu
2014-05-20 14:26   ` Ian Campbell
2014-06-01 19:44     ` Wei Liu
2014-05-20 15:15   ` Ian Jackson
2014-06-01 19:46     ` Wei Liu
2014-05-13 21:54 ` [PATCH V5 31/32] libxl: update domain configuration when updating memory targets Wei Liu
2014-05-20 14:32   ` Ian Campbell
2014-06-01 20:00     ` Wei Liu
2014-05-20 15:21   ` Ian Jackson
2014-05-20 15:35     ` Ian Campbell
2014-05-20 15:44       ` Ian Jackson
2014-05-20 15:55         ` Ian Campbell
2014-05-20 16:03           ` Ian Jackson
2014-05-21  8:38             ` Ian Campbell
2014-06-01 20:51             ` Wei Liu
2014-06-01 20:22     ` Wei Liu
2014-06-02 16:32       ` Ian Campbell
2014-05-13 21:54 ` Wei Liu [this message]
2014-05-20 14:35   ` [PATCH V5 32/32] libxl: synchronize configuration when we plug / unplug device Ian Campbell
2014-05-20 15:33   ` Ian Jackson
2014-06-01 20:57     ` Wei Liu
2014-06-02 16:33       ` Ian Campbell
2014-05-21 10:18 ` [PATCH V5 00/32] JSON infrastructure, new "xl-json" format and domain configuration synchronization Ian Campbell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1400018054-26038-33-git-send-email-wei.liu2@citrix.com \
    --to=wei.liu2@citrix.com \
    --cc=ian.campbell@citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).