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

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


  • To: minios-devel@xxxxxxxxxxxxx
  • From: Costin Lupu <costin.lupu@xxxxxxxxx>
  • Date: Mon, 10 Sep 2018 12:06:00 +0300
  • Cc: simon.kuenzer@xxxxxxxxx, yuri.volchkov@xxxxxxxxx
  • Delivery-date: Mon, 10 Sep 2018 09:06:22 +0000
  • Ironport-phdr: 9a23:F3lzMBYskRidPeedgHYqTBb/LSx+4OfEezUN459isYplN5qZr8qybnLW6fgltlLVR4KTs6sC17KJ9fi4EUU7or+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+jEqqkDtxwPDGJLLhCI3XLnffiLfhYap960lExQoozNBf4pVUCrcbLPLwR0/+qtrYDx4nPAyu2OvnDsty2Z8aWW2VGaCVKr3dsUKQ7OI1P+aMfJMVuCr6K/U95//ukGU5mV4Hcam32psXbGy3HvRlI0Wef3rhmdEBHnkWsQo6VuPlk0eOXiBOZyX6Y6Vp4zA9CYW9SIvOWI2pqLiAxzugWI1bYCZBEF/fP23vctCvXOwQaSTaBtJ5j3RQXr+6V44nkxWzrBLSwKEhNvfevDcf48GwnONp7vHewElhvQd/CN6QhjmA
  • 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/exportsyms.uk |   2 +
 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 ++++++++++++++++++++++++++++
 7 files changed, 302 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 be121bb..76a3264 100644
--- a/plat/xen/Makefile.uk
+++ b/plat/xen/Makefile.uk
@@ -82,5 +82,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 afa1ce2..e887bc4 100644
--- a/plat/xen/include/xenbus/xs.h
+++ b/plat/xen/include/xenbus/xs.h
@@ -209,6 +209,25 @@ int xs_del_perm(xenbus_transaction_t xbt, const char *path,
        domid_t domid);
 
 /*
+ * 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/exportsyms.uk b/plat/xen/xenbus/exportsyms.uk
index 2352a82..695a01a 100644
--- a/plat/xen/xenbus/exportsyms.uk
+++ b/plat/xen/xenbus/exportsyms.uk
@@ -12,6 +12,8 @@ xs_set_acl
 xs_get_perm
 xs_set_perm
 xs_del_perm
+xs_watch_path
+xs_unwatch
 xs_transaction_start
 xs_transaction_end
 xs_debug_msg
diff --git a/plat/xen/xenbus/xs.c b/plat/xen/xenbus/xs.c
index b1774d8..5a822b3 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"
 
 
@@ -517,6 +518,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_NULL(xsw->xs.path);
+       req[1] = XS_IOVEC_STR_NULL(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_NULL(xsw->xs.path);
+       req[1] = XS_IOVEC_STR_NULL(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 61a38b7..971f694 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"
 
 
 /*
@@ -457,7 +459,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..e2631a3
--- /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®.