[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Minios-devel] [UNIKRAFT PATCH v3 08/10] plat/xen: Add Xenstore watch support



I will push patches up to this one in the series. This one needs small
fixing. Sorry that I overlooked this thing last time.

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 2352a82..695a01a 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 b1774d8..5a822b3 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"
>  
>  
> @@ -517,6 +518,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 61a38b7..971f694 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"
>  
>  
>  /*
> @@ -457,7 +459,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..e2631a3
> --- /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);
I overlook this last time..

This might never happen, unless we start exploring the upper address
space. But this might result in printing something like
"0xffffffffffffffff", but you allocated space only for
"ffffffffffffffff". For exactly this reason, you better use snprintf
here (as a second measure). Also you might want to replace %p to %x.

> +     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®.