|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT PATCH v4 5/7] 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/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
>
--
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 |