|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH v4 5/7] plat/xen: Add Xenstore watch support
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 6fb2e04..a424fd9 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 fad7d9d..5f50de2 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"
@@ -519,6 +520,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 40909c3..3fd6a07 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"
/*
@@ -459,7 +461,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..d77a285
--- /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, "%lx", (long) 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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |