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

Re: [Minios-devel] [UNIKRAFT PATCH v4 6/7] plat/xen: Add Xenbus device probing



Reviewed-by: Yuri Volchkov <yuri.volchkov@xxxxxxxxx>

Costin Lupu <costin.lupu@xxxxxxxxx> writes:

> Extend the Xenbus bus driver with support for probing Xenbus
> devices.
>
> Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx>
> ---
>  plat/xen/include/xenbus/client.h |  12 ++++
>  plat/xen/include/xenbus/xenbus.h |  17 ++++-
>  plat/xen/xenbus/client.c         |  12 ++++
>  plat/xen/xenbus/exportsyms.uk    |   1 +
>  plat/xen/xenbus/xenbus.c         | 131 
> ++++++++++++++++++++++++++++++++++++++-
>  5 files changed, 171 insertions(+), 2 deletions(-)
>
> diff --git a/plat/xen/include/xenbus/client.h 
> b/plat/xen/include/xenbus/client.h
> index f3540b7..8b7e8c1 100644
> --- a/plat/xen/include/xenbus/client.h
> +++ b/plat/xen/include/xenbus/client.h
> @@ -86,4 +86,16 @@ int xenbus_watch_wait_event(struct xenbus_watch *watch);
>   */
>  int xenbus_watch_notify_event(struct xenbus_watch *watch);
>  
> +/*
> + * Driver states
> + */
> +
> +/*
> + * Returns the driver state found at the given Xenstore path.
> + *
> + * @param path Xenstore path
> + * @return The Xenbus driver state
> + */
> +XenbusState xenbus_read_driver_state(const char *path);
> +
>  #endif /* __XENBUS_CLIENT_H__ */
> diff --git a/plat/xen/include/xenbus/xenbus.h 
> b/plat/xen/include/xenbus/xenbus.h
> index 230dcd4..3d3b540 100644
> --- a/plat/xen/include/xenbus/xenbus.h
> +++ b/plat/xen/include/xenbus/xenbus.h
> @@ -110,7 +110,22 @@ UK_TAILQ_HEAD(xenbus_watch_list, struct xenbus_watch);
>   */
>  
>  struct xenbus_device {
> -
> +     /**< in use by Xenbus handler */
> +     UK_TAILQ_ENTRY(struct xenbus_device) next;
> +     /**< Device state */
> +     XenbusState state;
> +     /**< Device type */
> +     enum xenbus_dev_type devtype;
> +     /**< Xenstore path of the device */
> +     char *nodename;
> +     /**< Xenstore path of the device peer (e.g. backend for frontend) */
> +     char *otherend;
> +     /**< Domain id of the other end */
> +     domid_t otherend_id;
> +     /**< Watch for monitoring changes on other end */
> +     struct xenbus_watch *otherend_watch;
> +     /**< Xenbus driver */
> +     struct xenbus_driver *drv;
>  };
>  UK_TAILQ_HEAD(xenbus_device_list, struct xenbus_device);
>  
> diff --git a/plat/xen/xenbus/client.c b/plat/xen/xenbus/client.c
> index 3dbca0f..274e6e7 100644
> --- a/plat/xen/xenbus/client.c
> +++ b/plat/xen/xenbus/client.c
> @@ -44,6 +44,7 @@
>  #include <string.h>
>  #include <uk/errptr.h>
>  #include <uk/wait.h>
> +#include <xenbus/xs.h>
>  #include <xenbus/client.h>
>  
>  
> @@ -130,3 +131,14 @@ int xenbus_watch_notify_event(struct xenbus_watch *watch)
>  
>       return 0;
>  }
> +
> +XenbusState xenbus_read_driver_state(const char *path)
> +{
> +     char state_path[strlen(path) + sizeof("/state")];
> +     XenbusState state = XenbusStateUnknown;
> +
> +     sprintf(state_path, "%s/state", path);
> +     xs_read_integer(XBT_NIL, state_path, (int *) &state);
> +
> +     return state;
> +}
> diff --git a/plat/xen/xenbus/exportsyms.uk b/plat/xen/xenbus/exportsyms.uk
> index a424fd9..d57a2a5 100644
> --- a/plat/xen/xenbus/exportsyms.uk
> +++ b/plat/xen/xenbus/exportsyms.uk
> @@ -27,3 +27,4 @@ xenbus_state_to_str
>  xenbus_devtype_to_str
>  xenbus_str_to_devtype
>  xenbus_watch_wait_event
> +xenbus_read_driver_state
> diff --git a/plat/xen/xenbus/xenbus.c b/plat/xen/xenbus/xenbus.c
> index a20546b..28f0cfd 100644
> --- a/plat/xen/xenbus/xenbus.c
> +++ b/plat/xen/xenbus/xenbus.c
> @@ -43,8 +43,12 @@
>  #include <uk/errptr.h>
>  #include <uk/assert.h>
>  #include <xenbus/xenbus.h>
> +#include <xenbus/xs.h>
> +#include <xenbus/client.h>
>  #include "xs_comms.h"
>  
> +#define XS_DEV_PATH "device"
> +
>  static struct xenbus_handler xbh;
>  
>  
> @@ -67,13 +71,138 @@ void uk_xb_free(void *ptr)
>       uk_free(xbh.a, ptr);
>  }
>  
> +
> +static struct xenbus_driver *xenbus_find_driver(xenbus_dev_type_t devtype)
> +{
> +     struct xenbus_driver *drv;
> +     const xenbus_dev_type_t *pdevtype;
> +
> +     UK_TAILQ_FOREACH(drv, &xbh.drv_list, next) {
> +             for (pdevtype = drv->device_types;
> +                             *pdevtype != xenbus_dev_none; pdevtype++) {
> +                     if (*pdevtype == devtype)
> +                             return drv;
> +             }
> +     }
> +
> +     return NULL; /* no driver found */
> +}
> +
> +static int xenbus_probe_device(struct xenbus_driver *drv,
> +             xenbus_dev_type_t type, const char *name)
> +{
> +     int err;
> +     struct xenbus_device *dev;
> +     char *nodename = NULL;
> +     XenbusState state;
> +
> +     /* device/type/name */
> +     err = asprintf(&nodename, "%s/%s/%s",
> +             XS_DEV_PATH, xenbus_devtype_to_str(type), name);
> +     if (err < 0)
> +             goto out;
> +
> +     state = xenbus_read_driver_state(nodename);
> +     if (state != XenbusStateInitialising)
> +             return 0;
> +
> +     uk_printd(DLVL_INFO, "Xenbus device: %s\n", nodename);
> +
> +     dev = uk_xb_calloc(1, sizeof(*dev) + strlen(nodename) + 1);
> +     if (!dev) {
> +             uk_printd(DLVL_ERR, "Failed to initialize: Out of memory!\n");
> +             err = -ENOMEM;
> +             goto out;
> +     }
> +
> +     dev->state = XenbusStateInitialising;
> +     dev->devtype = type;
> +     dev->nodename = (char *) (dev + 1);
> +     strcpy(dev->nodename, nodename);
> +
> +     err = drv->add_dev(dev);
> +     if (err) {
> +             uk_printd(DLVL_ERR, "Failed to add device.\n");
> +             uk_xb_free(dev);
> +     }
> +
> +out:
> +     if (nodename)
> +             free(nodename);
> +
> +     return err;
> +}
> +
> +static int xenbus_probe_device_type(const char *devtype_str)
> +{
> +     struct xenbus_driver *drv;
> +     xenbus_dev_type_t devtype;
> +     char dirname[sizeof(XS_DEV_PATH) + strlen(devtype_str)];
> +     char **devices = NULL;
> +     int err = 0;
> +
> +     devtype = xenbus_str_to_devtype(devtype_str);
> +     if (!devtype) {
> +             uk_printd(DLVL_WARN,
> +                     "Unsupported device type: %s\n", devtype_str);
> +             goto out;
> +     }
> +
> +     drv = xenbus_find_driver(devtype);
> +     if (!drv) {
> +             uk_printd(DLVL_WARN,
> +                     "No driver for device type: %s\n", devtype_str);
> +             goto out;
> +     }
> +
> +     sprintf(dirname, "%s/%s", XS_DEV_PATH, devtype_str);
> +
> +     /* Get device list */
> +     devices = xs_ls(XBT_NIL, dirname);
> +     if (PTRISERR(devices)) {
> +             err = PTR2ERR(devices);
> +             uk_printd(DLVL_ERR,
> +                     "Error reading %s devices: %d\n", devtype_str, err);
> +             goto out;
> +     }
> +
> +     for (int i = 0; devices[i] != NULL; i++) {
> +             /* Probe only if no prior error */
> +             if (err == 0)
> +                     err = xenbus_probe_device(drv, devtype, devices[i]);
> +     }
> +
> +out:
> +     if (!PTRISERR(devices))
> +             free(devices);
> +
> +     return err;
> +}
> +
>  static int xenbus_probe(void)
>  {
> +     char **devtypes;
>       int err = 0;
>  
>       uk_printd(DLVL_INFO, "Probe Xenbus\n");
>  
> -     /* TODO */
> +     /* Get device types list */
> +     devtypes = xs_ls(XBT_NIL, XS_DEV_PATH);
> +     if (PTRISERR(devtypes)) {
> +             err = PTR2ERR(devtypes);
> +             uk_printd(DLVL_ERR, "Error reading device types: %d\n", err);
> +             goto out;
> +     }
> +
> +     for (int i = 0; devtypes[i] != NULL; i++) {
> +             /* Probe only if no previous error */
> +             if (err == 0)
> +                     err = xenbus_probe_device_type(devtypes[i]);
> +     }
> +
> +out:
> +     if (!PTRISERR(devtypes))
> +             free(devtypes);
>  
>       return err;
>  }
> -- 
> 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®.