[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 |