[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Minios-devel] [UNIKRAFT PATCH v2 08/10] plat/xen: Add Xenstore watch support


  • To: minios-devel@xxxxxxxxxxxxx
  • From: Costin Lupu <costin.lupu@xxxxxxxxx>
  • Date: Thu, 23 Aug 2018 13:59:36 +0300
  • Cc: simon.kuenzer@xxxxxxxxx, yuri.volchkov@xxxxxxxxx, sharan.santhanam@xxxxxxxxx
  • Delivery-date: Thu, 23 Aug 2018 10:59:53 +0000
  • Ironport-phdr: 9a23:bio9vhZfyO5sl+tF0Msq00n/LSx+4OfEezUN459isYplN5qZrs+8bnLW6fgltlLVR4KTs6sC17KJ9fi4EUU7or+5+EgYd5JNUxJXwe43pCcHRPC/NEvgMfTxZDY7FskRHHVs/nW8LFQHUJ2mPw6arXK99yMdFQviPgRpOOv1BpTSj8Oq3Oyu5pHfeQpFiCa/bL9oMBm6sRjau9ULj4dlNqs/0AbCrGFSe+RRy2NoJFaTkAj568yt4pNt8Dletuw4+cJYXqr0Y6o3TbpDDDQ7KG81/9HktQPCTQSU+HQRVHgdnwdSDAjE6BH6WYrxsjf/u+Fg1iSWIdH6QLYpUjmk8qxlSgLniD0fOjA57m/Zl8J+gqFcrh2jqRxy2JLYbJ2POfZiZK7RYc8WSGxcVchRTSxBBYa8YpMRAuoGJuZYs4j9p10TphW4GAmsHP7vwSJPi3Dq2q06yPghEQDA3AA6G9IOrWzUrMjuOagOSuC51rHIzSjYYP9Mwzf975HFfxY8qv+PRbJ9adfdxEYyGw/fjVidqZbpMy2L2ukPqWSW4fJsWf+ghmI6sQ18oTiiyt0yhoTHiI8Z0E3I+CpnzIszONa2UlR0YcS+H5tVryyaMox2Td48TGxwoyY6z6EGuYa8fCgX1JQr3x7fZOKDc4iP+h/jSuORLi15hHJhYr6wmw2y/VK4yu3hTca4ykxKri1dntnNsHACyQDT59CaRvZy40utwzWC2gDJ5u1aP0w5l7DXJpA5zr41jJUTsEDDHiHsmEXxia+bblkr+u+z6+T7Y7XmoIWQN4tpigHmL6QjgdCwAf8iPggWQmiU4v6w1Kfk/UHhWrVFkuU2krXFsJDdPckbo6+5AwlU0oYk8BazFiqp38oGnXYZKFJIYxaHj4nyO1HSO/D0F/i+jEqqkDtxwPDGJLLhCI3XLnffiLfhYap960lExQoozdBQ/YhUBasHIP7pQU/+rtrYDgM5MwOuxeboEtB925gYWW2RHqCZNLndvkSS6u0xPumGfJUVtyrlK/g5+/7uimc0mUQcfams2psXbmq0Hvd7I0qHZ3rtg8kOEX0Rswo4UuPllFmCXiRIaHqoQa08+ykxCJi6AofbWoCtnLuB0T+7H51LfGBGC0qAEWnvd4WAR/gMaCGSIsh/kjEfU7iuVZMu1RW0uwDh0bZoMPfUqWUkssfm1d504PaWmRws+DhcC8WGz3rLX2xy2GQSSGwYxqd69Gd60UuC1+BcnuRFXYhY4OhVUwF8MYPE0sRxEJbqRwiHZNDfGwXuecmvHTxkFoF5+NQJeUsoQ9g=
  • List-id: Mini-os development list <minios-devel.lists.xenproject.org>

Add support for processing Xenstore watch events coming from the
Xenstore daemon.

Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx>
---
 plat/xen/Makefile.uk         |   1 +
 plat/xen/include/xenbus/xs.h |  19 +++++++
 plat/xen/xenbus/xs.c         |  63 ++++++++++++++++++++++
 plat/xen/xenbus/xs_comms.c   |  16 +++++-
 plat/xen/xenbus/xs_watch.c   | 121 +++++++++++++++++++++++++++++++++++++++++++
 plat/xen/xenbus/xs_watch.h   |  81 +++++++++++++++++++++++++++++
 6 files changed, 300 insertions(+), 1 deletion(-)
 create mode 100644 plat/xen/xenbus/xs_watch.c
 create mode 100644 plat/xen/xenbus/xs_watch.h

diff --git a/plat/xen/Makefile.uk b/plat/xen/Makefile.uk
index 1c97d8c..7aad541 100644
--- a/plat/xen/Makefile.uk
+++ b/plat/xen/Makefile.uk
@@ -81,5 +81,6 @@ LIBXENBUS_CINCLUDES-y          += $(LIBXENPLAT_CINCLUDES-y)
 LIBXENBUS_SRCS-y               += $(LIBXENPLAT_BASE)/xenbus/xenbus.c
 LIBXENBUS_SRCS-y               += $(LIBXENPLAT_BASE)/xenbus/client.c
 LIBXENBUS_SRCS-y               += $(LIBXENPLAT_BASE)/xenbus/xs_comms.c
+LIBXENBUS_SRCS-y               += $(LIBXENPLAT_BASE)/xenbus/xs_watch.c
 LIBXENBUS_SRCS-y               += $(LIBXENPLAT_BASE)/xenbus/xs.c
 endif
diff --git a/plat/xen/include/xenbus/xs.h b/plat/xen/include/xenbus/xs.h
index 6ae761d..44792ef 100644
--- a/plat/xen/include/xenbus/xs.h
+++ b/plat/xen/include/xenbus/xs.h
@@ -198,6 +198,25 @@ int xs_set_perms(xenbus_transaction_t xbt, const char 
*path,
        domid_t domid, enum xs_perm perm);
 
 /*
+ * Creates and registers a Xenbus watch
+ *
+ * @param xbt Xenbus transaction id
+ * @param path Xenstore path
+ * @return On success, returns a malloc'd Xenbus watch. On error, returns
+ * a negative error number which should be checked using PTRISERR.
+ */
+struct xenbus_watch *xs_watch_path(xenbus_transaction_t xbt, const char *path);
+
+/*
+ * Unregisters and destroys a Xenbus watch
+ *
+ * @param xbt Xenbus transaction id
+ * @param watch Xenbus watch
+ * @return 0 on success, a negative errno value on error.
+ */
+int xs_unwatch(xenbus_transaction_t xbt, struct xenbus_watch *watch);
+
+/*
  * Start a xenbus transaction. Returns the transaction in xbt on
  * success or an error number otherwise.
  *
diff --git a/plat/xen/xenbus/xs.c b/plat/xen/xenbus/xs.c
index eb5131a..d31424e 100644
--- a/plat/xen/xenbus/xs.c
+++ b/plat/xen/xenbus/xs.c
@@ -47,6 +47,7 @@
 #include <uk/errptr.h>
 #include <xen/io/xs_wire.h>
 #include <xenbus/xs.h>
+#include "xs_watch.h"
 #include "xs_comms.h"
 
 
@@ -483,6 +484,68 @@ out:
 }
 
 /*
+ * Watches
+ */
+
+struct xenbus_watch *xs_watch_path(xenbus_transaction_t xbt, const char *path)
+{
+       struct xs_watch *xsw;
+       struct xs_iovec req[2];
+       int err;
+
+       if (path == NULL)
+               return ERR2PTR(EINVAL);
+
+       xsw = xs_watch_create(path);
+       if (PTRISERR(xsw))
+               return (struct xenbus_watch *) xsw;
+
+       req[0] = XS_IOVEC_STR(xsw->xs.path);
+       req[1] = XS_IOVEC_STR(xsw->xs.token);
+
+       err = xs_msg(XS_WATCH, xbt, req, ARRAY_SIZE(req));
+       if (err) {
+               xs_watch_destroy(xsw);
+               return ERR2PTR(-err);
+       }
+
+       return &xsw->base;
+}
+
+int xs_unwatch(xenbus_transaction_t xbt, struct xenbus_watch *watch)
+{
+       struct xs_watch *xsw, *_xsw;
+       struct xs_iovec req[2];
+       int err;
+
+       if (watch == NULL) {
+               err = -EINVAL;
+               goto out;
+       }
+
+       xsw = __containerof(watch, struct xs_watch, base);
+
+       _xsw = xs_watch_find(xsw->xs.path, xsw->xs.token);
+       if (_xsw != xsw) {
+               /* this watch was not registered */
+               err = -ENOENT;
+               goto out;
+       }
+
+       req[0] = XS_IOVEC_STR(xsw->xs.path);
+       req[1] = XS_IOVEC_STR(xsw->xs.token);
+
+       err = xs_msg(XS_UNWATCH, xbt, req, ARRAY_SIZE(req));
+       if (err)
+               goto out;
+
+       err = xs_watch_destroy(xsw);
+
+out:
+       return err;
+}
+
+/*
  * Transactions
  */
 
diff --git a/plat/xen/xenbus/xs_comms.c b/plat/xen/xenbus/xs_comms.c
index df3739d..aabd8c1 100644
--- a/plat/xen/xenbus/xs_comms.c
+++ b/plat/xen/xenbus/xs_comms.c
@@ -48,7 +48,9 @@
 #include <common/events.h>
 #include <xen-x86/mm.h>
 #include <xen-x86/setup.h>
+#include <xenbus/client.h>
 #include "xs_comms.h"
+#include "xs_watch.h"
 
 
 /*
@@ -389,7 +391,19 @@ static void process_reply(struct xsd_sockmsg *hdr, char 
*payload)
 /* Process an incoming xs watch event */
 static void process_watch_event(char *watch_msg)
 {
-       /* TODO */
+       struct xs_watch *watch;
+       char *path, *token;
+
+       path  = watch_msg;
+       token = watch_msg + strlen(path) + 1;
+
+       watch = xs_watch_find(path, token);
+       free(watch_msg);
+
+       if (watch)
+               xenbus_watch_notify_event(&watch->base);
+       else
+               uk_printd(DLVL_ERR, "Invalid watch event.");
 }
 
 static void memcpy_from_ring(const char *ring, char *dest, int off, int len)
diff --git a/plat/xen/xenbus/xs_watch.c b/plat/xen/xenbus/xs_watch.c
new file mode 100644
index 0000000..6124d0b
--- /dev/null
+++ b/plat/xen/xenbus/xs_watch.c
@@ -0,0 +1,121 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Authors: Costin Lupu <costin.lupu@xxxxxxxxx>
+ *
+ * Copyright (c) 2018, NEC Europe Ltd., NEC Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
+ */
+/* Internal API for Xenstore watches */
+
+#include <stdio.h>
+#include <string.h>
+#include <uk/errptr.h>
+#include "xs_watch.h"
+
+/* Watches list */
+static struct xenbus_watch_list xs_watch_list =
+       UK_TAILQ_HEAD_INITIALIZER(xs_watch_list);
+
+static int xs_watch_info_equal(const struct xs_watch_info *xswi,
+       const char *path, const char *token)
+{
+       return (strcmp(xswi->path, path) == 0 &&
+               strcmp(xswi->token, token) == 0);
+}
+
+struct xs_watch *xs_watch_create(const char *path)
+{
+       struct xs_watch *xsw;
+       const int token_size = sizeof(xsw) * 2 + 1;
+       char *tmpstr;
+       int stringlen;
+
+       UK_ASSERT(path != NULL);
+
+       stringlen = token_size + strlen(path) + 1;
+
+       xsw = uk_xb_malloc(sizeof(*xsw) + stringlen);
+       if (!xsw)
+               return ERR2PTR(ENOMEM);
+
+       ukarch_spin_lock_init(&xsw->base.lock);
+       xsw->base.pending_events = 0;
+       uk_waitq_init(&xsw->base.wq);
+
+       /* set path */
+       tmpstr = (char *) (xsw + 1);
+       strcpy(tmpstr, path);
+       xsw->xs.path = tmpstr;
+
+       /* set token (watch address as string) */
+       tmpstr += strlen(path) + 1;
+       sprintf(tmpstr, "%p", xsw);
+       xsw->xs.token = tmpstr;
+
+       UK_TAILQ_INSERT_HEAD(&xs_watch_list, &xsw->base, watch_list);
+
+       return xsw;
+}
+
+int xs_watch_destroy(struct xs_watch *watch)
+{
+       struct xenbus_watch *xbw;
+       struct xs_watch *xsw;
+       int err = -ENOENT;
+
+       UK_ASSERT(watch != NULL);
+
+       UK_TAILQ_FOREACH(xbw, &xs_watch_list, watch_list) {
+               xsw = __containerof(xbw, struct xs_watch, base);
+
+               if (xsw == watch) {
+                       UK_TAILQ_REMOVE(&xs_watch_list, xbw, watch_list);
+                       uk_xb_free(xsw);
+                       err = 0;
+                       break;
+               }
+       }
+
+       return err;
+}
+
+struct xs_watch *xs_watch_find(const char *path, const char *token)
+{
+       struct xenbus_watch *xbw;
+       struct xs_watch *xsw;
+
+       UK_TAILQ_FOREACH(xbw, &xs_watch_list, watch_list) {
+               xsw = __containerof(xbw, struct xs_watch, base);
+
+               if (xs_watch_info_equal(&xsw->xs, path, token))
+                       return xsw;
+       }
+
+       return NULL;
+}
diff --git a/plat/xen/xenbus/xs_watch.h b/plat/xen/xenbus/xs_watch.h
new file mode 100644
index 0000000..f9a5bff
--- /dev/null
+++ b/plat/xen/xenbus/xs_watch.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Authors: Costin Lupu <costin.lupu@xxxxxxxxx>
+ *
+ * Copyright (c) 2018, NEC Europe Ltd., NEC Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
+ */
+/* Internal API for Xenstore watches */
+
+#ifndef __XS_WATCH_H__
+#define __XS_WATCH_H__
+
+#include <xenbus/xenbus.h>
+
+/* Xenstore watch info */
+struct xs_watch_info {
+       /**< Watched Xenstore path */
+       char *path;
+       /**< Watch identification token */
+       char *token;
+};
+
+/* Xenstore watch */
+struct xs_watch {
+       struct xenbus_watch base;
+       struct xs_watch_info xs;
+};
+
+/*
+ * Create a Xenstore watch associated with a path.
+ *
+ * @param path Xenstore path
+ * @return On success, returns a malloc'd Xenstore watch. On error, returns
+ * a negative error number which should be checked using PTRISERR.
+ */
+struct xs_watch *xs_watch_create(const char *path);
+
+/*
+ * Destroy a previously created Xenstore watch.
+ *
+ * @param watch Xenstore watch
+ * @return 0 on success, a negative errno value on error.
+ */
+int xs_watch_destroy(struct xs_watch *watch);
+
+/*
+ * Returns the Xenstore watch associated with path and token.
+ *
+ * @param path Watched path
+ * @param token Watch token
+ * @return On success returns the found watch. On error, returns NULL.
+ */
+struct xs_watch *xs_watch_find(const char *path, const char *token);
+
+#endif /* __XS_WATCH_H__ */
-- 
2.11.0


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.