[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT PATCH v2 08/10] plat/xen: Add Xenstore watch support
Reviewed-by: Yuri Volchkov <yuri.volchkov@xxxxxxxxx> Costin Lupu <costin.lupu@xxxxxxxxx> writes: > 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 > -- Yuri Volchkov Software Specialist NEC Europe Ltd Kurfürsten-Anlage 36 D-69115 Heidelberg _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |