[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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.