WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [LINUX] Move xenbus backend probing into

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [LINUX] Move xenbus backend probing into a separate source file and
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 25 Oct 2006 15:20:20 +0000
Delivery-date: Wed, 25 Oct 2006 08:21:15 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
# Node ID 47cc7392741ad120a0c5745f7aeaf00a1aefd538
# Parent  266aef9b0386b0742e05893e24e09375b31bf835
[LINUX] Move xenbus backend probing into a separate source file and
only build it when CONFIG_XEN_BACKEND is set.

This removes unused code from frontend only configurations and also
makes PV-on-HVM drivers on older kernels simpler by removing code
which would otherwise require extra code in the compatability shim.

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
---
 linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile               |    1 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c         |  232 --------
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.h         |   77 ++
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe_backend.c |  271 
++++++++++
 4 files changed, 368 insertions(+), 213 deletions(-)

diff -r 266aef9b0386 -r 47cc7392741a 
linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile  Wed Oct 25 13:58:30 
2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile  Wed Oct 25 13:58:30 
2006 +0100
@@ -9,4 +9,5 @@ xenbus-objs += xenbus_comms.o
 xenbus-objs += xenbus_comms.o
 xenbus-objs += xenbus_xs.o
 xenbus-objs += xenbus_probe.o
+obj-$(CONFIG_XEN_BACKEND) += xenbus_probe_backend.o
 obj-$(CONFIG_XEN_XENBUS_DEV) += xenbus_dev.o
diff -r 266aef9b0386 -r 47cc7392741a 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Wed Oct 25 
13:58:30 2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Wed Oct 25 
13:58:30 2006 +0100
@@ -56,6 +56,7 @@
 #include <xen/hvm.h>
 
 #include "xenbus_comms.h"
+#include "xenbus_probe.h"
 
 int xen_store_evtchn;
 struct xenstore_domain_interface *xen_store_interface;
@@ -68,12 +69,7 @@ static void wait_for_devices(struct xenb
 static void wait_for_devices(struct xenbus_driver *xendrv);
 
 static int xenbus_probe_frontend(const char *type, const char *name);
-static int xenbus_uevent_backend(struct device *dev, char **envp,
-                                int num_envp, char *buffer, int buffer_size);
-static int xenbus_probe_backend(const char *type, const char *domid);
-
-static int xenbus_dev_probe(struct device *_dev);
-static int xenbus_dev_remove(struct device *_dev);
+
 static void xenbus_dev_shutdown(struct device *_dev);
 
 /* If something in array of ids matches this device, return it. */
@@ -87,7 +83,7 @@ match_device(const struct xenbus_device_
        return NULL;
 }
 
-static int xenbus_match(struct device *_dev, struct device_driver *_drv)
+int xenbus_match(struct device *_dev, struct device_driver *_drv)
 {
        struct xenbus_driver *drv = to_xenbus_driver(_drv);
 
@@ -96,17 +92,6 @@ static int xenbus_match(struct device *_
 
        return match_device(drv->ids, to_xenbus_device(_dev)) != NULL;
 }
-
-struct xen_bus_type
-{
-       char *root;
-       unsigned int levels;
-       int (*get_bus_id)(char bus_id[BUS_ID_SIZE], const char *nodename);
-       int (*probe)(const char *type, const char *dir);
-       struct bus_type bus;
-       struct device dev;
-};
-
 
 /* device/<type>/<id> => <type>-<id> */
 static int frontend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
@@ -144,7 +129,7 @@ static void free_otherend_watch(struct x
 }
 
 
-static int read_otherend_details(struct xenbus_device *xendev,
+int read_otherend_details(struct xenbus_device *xendev,
                                 char *id_node, char *path_node)
 {
        int err = xenbus_gather(XBT_NIL, xendev->nodename,
@@ -174,12 +159,6 @@ static int read_backend_details(struct x
 static int read_backend_details(struct xenbus_device *xendev)
 {
        return read_otherend_details(xendev, "backend-id", "backend");
-}
-
-
-static int read_frontend_details(struct xenbus_device *xendev)
-{
-       return read_otherend_details(xendev, "frontend-id", "frontend");
 }
 
 
@@ -201,106 +180,6 @@ static struct xen_bus_type xenbus_fronte
        },
 };
 
-/* backend/<type>/<fe-uuid>/<id> => <type>-<fe-domid>-<id> */
-static int backend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
-{
-       int domid, err;
-       const char *devid, *type, *frontend;
-       unsigned int typelen;
-
-       type = strchr(nodename, '/');
-       if (!type)
-               return -EINVAL;
-       type++;
-       typelen = strcspn(type, "/");
-       if (!typelen || type[typelen] != '/')
-               return -EINVAL;
-
-       devid = strrchr(nodename, '/') + 1;
-
-       err = xenbus_gather(XBT_NIL, nodename, "frontend-id", "%i", &domid,
-                           "frontend", NULL, &frontend,
-                           NULL);
-       if (err)
-               return err;
-       if (strlen(frontend) == 0)
-               err = -ERANGE;
-       if (!err && !xenbus_exists(XBT_NIL, frontend, ""))
-               err = -ENOENT;
-
-       kfree(frontend);
-
-       if (err)
-               return err;
-
-       if (snprintf(bus_id, BUS_ID_SIZE,
-                    "%.*s-%i-%s", typelen, type, domid, devid) >= BUS_ID_SIZE)
-               return -ENOSPC;
-       return 0;
-}
-
-static struct xen_bus_type xenbus_backend = {
-       .root = "backend",
-       .levels = 3,            /* backend/type/<frontend>/<id> */
-       .get_bus_id = backend_bus_id,
-       .probe = xenbus_probe_backend,
-       .bus = {
-               .name     = "xen-backend",
-               .match    = xenbus_match,
-               .probe    = xenbus_dev_probe,
-               .remove   = xenbus_dev_remove,
-//             .shutdown = xenbus_dev_shutdown,
-               .uevent   = xenbus_uevent_backend,
-       },
-       .dev = {
-               .bus_id = "xen-backend",
-       },
-};
-
-static int xenbus_uevent_backend(struct device *dev, char **envp,
-                                int num_envp, char *buffer, int buffer_size)
-{
-       struct xenbus_device *xdev;
-       struct xenbus_driver *drv;
-       int i = 0;
-       int length = 0;
-
-       DPRINTK("");
-
-       if (dev == NULL)
-               return -ENODEV;
-
-       xdev = to_xenbus_device(dev);
-       if (xdev == NULL)
-               return -ENODEV;
-
-       /* stuff we want to pass to /sbin/hotplug */
-       add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
-                      "XENBUS_TYPE=%s", xdev->devicetype);
-
-       add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
-                      "XENBUS_PATH=%s", xdev->nodename);
-
-       add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
-                      "XENBUS_BASE_PATH=%s", xenbus_backend.root);
-
-       /* terminate, set to next free slot, shrink available space */
-       envp[i] = NULL;
-       envp = &envp[i];
-       num_envp -= i;
-       buffer = &buffer[length];
-       buffer_size -= length;
-
-       if (dev->driver) {
-               drv = to_xenbus_driver(dev->driver);
-               if (drv && drv->uevent)
-                       return drv->uevent(xdev, envp, num_envp, buffer,
-                                          buffer_size);
-       }
-
-       return 0;
-}
-
 static void otherend_changed(struct xenbus_watch *watch,
                             const char **vec, unsigned int len)
 {
@@ -360,7 +239,7 @@ static int watch_otherend(struct xenbus_
 }
 
 
-static int xenbus_dev_probe(struct device *_dev)
+int xenbus_dev_probe(struct device *_dev)
 {
        struct xenbus_device *dev = to_xenbus_device(_dev);
        struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
@@ -407,7 +286,7 @@ fail:
        return -ENODEV;
 }
 
-static int xenbus_dev_remove(struct device *_dev)
+int xenbus_dev_remove(struct device *_dev)
 {
        struct xenbus_device *dev = to_xenbus_device(_dev);
        struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
@@ -445,8 +324,8 @@ static void xenbus_dev_shutdown(struct d
        put_device(&dev->dev);
 }
 
-static int xenbus_register_driver_common(struct xenbus_driver *drv,
-                                        struct xen_bus_type *bus)
+int xenbus_register_driver_common(struct xenbus_driver *drv,
+                                 struct xen_bus_type *bus)
 {
        int ret;
 
@@ -476,14 +355,6 @@ int xenbus_register_frontend(struct xenb
        return 0;
 }
 EXPORT_SYMBOL_GPL(xenbus_register_frontend);
-
-int xenbus_register_backend(struct xenbus_driver *drv)
-{
-       drv->read_otherend_details = read_frontend_details;
-
-       return xenbus_register_driver_common(drv, &xenbus_backend);
-}
-EXPORT_SYMBOL_GPL(xenbus_register_backend);
 
 void xenbus_unregister_driver(struct xenbus_driver *drv)
 {
@@ -596,9 +467,9 @@ DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP |
 DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL);
 
 
-static int xenbus_probe_node(struct xen_bus_type *bus,
-                            const char *type,
-                            const char *nodename)
+int xenbus_probe_node(struct xen_bus_type *bus,
+                     const char *type,
+                     const char *nodename)
 {
        int err;
        struct xenbus_device *xendev;
@@ -668,55 +539,6 @@ static int xenbus_probe_frontend(const c
        return err;
 }
 
-/* backend/<typename>/<frontend-uuid>/<name> */
-static int xenbus_probe_backend_unit(const char *dir,
-                                    const char *type,
-                                    const char *name)
-{
-       char *nodename;
-       int err;
-
-       nodename = kasprintf("%s/%s", dir, name);
-       if (!nodename)
-               return -ENOMEM;
-
-       DPRINTK("%s\n", nodename);
-
-       err = xenbus_probe_node(&xenbus_backend, type, nodename);
-       kfree(nodename);
-       return err;
-}
-
-/* backend/<typename>/<frontend-domid> */
-static int xenbus_probe_backend(const char *type, const char *domid)
-{
-       char *nodename;
-       int err = 0;
-       char **dir;
-       unsigned int i, dir_n = 0;
-
-       DPRINTK("");
-
-       nodename = kasprintf("%s/%s/%s", xenbus_backend.root, type, domid);
-       if (!nodename)
-               return -ENOMEM;
-
-       dir = xenbus_directory(XBT_NIL, nodename, "", &dir_n);
-       if (IS_ERR(dir)) {
-               kfree(nodename);
-               return PTR_ERR(dir);
-       }
-
-       for (i = 0; i < dir_n; i++) {
-               err = xenbus_probe_backend_unit(nodename, type, dir[i]);
-               if (err)
-                       break;
-       }
-       kfree(dir);
-       kfree(nodename);
-       return err;
-}
-
 static int xenbus_probe_device_type(struct xen_bus_type *bus, const char *type)
 {
        int err = 0;
@@ -737,7 +559,7 @@ static int xenbus_probe_device_type(stru
        return err;
 }
 
-static int xenbus_probe_devices(struct xen_bus_type *bus)
+int xenbus_probe_devices(struct xen_bus_type *bus)
 {
        int err = 0;
        char **dir;
@@ -779,7 +601,7 @@ static int strsep_len(const char *str, c
        return (len == 0) ? i : -ERANGE;
 }
 
-static void dev_changed(const char *node, struct xen_bus_type *bus)
+void dev_changed(const char *node, struct xen_bus_type *bus)
 {
        int exists, rootlen;
        struct xenbus_device *dev;
@@ -824,23 +646,10 @@ static void frontend_changed(struct xenb
        dev_changed(vec[XS_WATCH_PATH], &xenbus_frontend);
 }
 
-static void backend_changed(struct xenbus_watch *watch,
-                           const char **vec, unsigned int len)
-{
-       DPRINTK("");
-
-       dev_changed(vec[XS_WATCH_PATH], &xenbus_backend);
-}
-
 /* We watch for devices appearing and vanishing. */
 static struct xenbus_watch fe_watch = {
        .node = "device",
        .callback = frontend_changed,
-};
-
-static struct xenbus_watch be_watch = {
-       .node = "backend",
-       .callback = backend_changed,
 };
 
 static int suspend_dev(struct device *dev, void *data)
@@ -913,7 +722,7 @@ void xenbus_suspend(void)
        DPRINTK("");
 
        bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
-       bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, suspend_dev);
+       xenbus_backend_suspend(suspend_dev);
        xs_suspend();
 }
 EXPORT_SYMBOL_GPL(xenbus_suspend);
@@ -923,7 +732,7 @@ void xenbus_resume(void)
        xb_init_comms();
        xs_resume();
        bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev);
-       bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, resume_dev);
+       xenbus_backend_resume(resume_dev);
 }
 EXPORT_SYMBOL_GPL(xenbus_resume);
 
@@ -956,13 +765,10 @@ void xenbus_probe(void *unused)
 {
        BUG_ON((xenstored_ready <= 0));
 
-       /* Enumerate devices in xenstore. */
+       /* Enumerate devices in xenstore and watch for changes. */
        xenbus_probe_devices(&xenbus_frontend);
-       xenbus_probe_devices(&xenbus_backend);
-
-       /* Watch for changes. */
        register_xenbus_watch(&fe_watch);
-       register_xenbus_watch(&be_watch);
+       xenbus_backend_probe_and_watch();
 
        /* Notify others that xenstore is up */
        notifier_call_chain(&xenstore_chain, 0, NULL);
@@ -1021,7 +827,7 @@ static int __init xenbus_probe_init(void
 
        /* Register ourselves with the kernel bus subsystem */
        bus_register(&xenbus_frontend.bus);
-       bus_register(&xenbus_backend.bus);
+       xenbus_backend_bus_register();
 
        /*
         * Domain0 doesn't have a store_evtchn or store_mfn yet.
@@ -1092,7 +898,7 @@ static int __init xenbus_probe_init(void
 
        /* Register ourselves with the kernel device subsystem */
        device_register(&xenbus_frontend.dev);
-       device_register(&xenbus_backend.dev);
+       xenbus_backend_device_register();
 
        if (!is_initial_xendomain())
                xenbus_probe(NULL);
diff -r 266aef9b0386 -r 47cc7392741a 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.h    Wed Oct 25 
13:58:30 2006 +0100
@@ -0,0 +1,77 @@
+/******************************************************************************
+ * xenbus_probe.h
+ *
+ * Talks to Xen Store to figure out what devices we have.
+ *
+ * Copyright (C) 2005 Rusty Russell, IBM Corporation
+ * Copyright (C) 2005 XenSource Ltd.
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef _XENBUS_PROBE_H
+#define _XENBUS_PROBE_H
+
+#ifdef CONFIG_XEN_BACKEND
+extern void xenbus_backend_suspend(int (*fn)(struct device *, void *));
+extern void xenbus_backend_resume(int (*fn)(struct device *, void *));
+extern void xenbus_backend_probe_and_watch(void);
+extern void xenbus_backend_bus_register(void);
+extern void xenbus_backend_device_register(void);
+#else
+static inline void xenbus_backend_suspend(int (*fn)(struct device *, void *)) 
{}
+static inline void xenbus_backend_resume(int (*fn)(struct device *, void *)) {}
+static inline void xenbus_backend_probe_and_watch(void) {}
+static inline void xenbus_backend_bus_register(void) {}
+static inline void xenbus_backend_device_register(void) {}
+#endif
+
+struct xen_bus_type
+{
+       char *root;
+       unsigned int levels;
+       int (*get_bus_id)(char bus_id[BUS_ID_SIZE], const char *nodename);
+       int (*probe)(const char *type, const char *dir);
+       struct bus_type bus;
+       struct device dev;
+};
+
+extern int xenbus_match(struct device *_dev, struct device_driver *_drv);
+extern int xenbus_dev_probe(struct device *_dev);
+extern int xenbus_dev_remove(struct device *_dev);
+extern int xenbus_register_driver_common(struct xenbus_driver *drv,
+                                        struct xen_bus_type *bus);
+extern int xenbus_probe_node(struct xen_bus_type *bus,
+                            const char *type,
+                            const char *nodename);
+extern int xenbus_probe_devices(struct xen_bus_type *bus);
+
+extern void dev_changed(const char *node, struct xen_bus_type *bus);
+
+/* Simplified asprintf. Probably belongs in lib */
+extern char *kasprintf(const char *fmt, ...);
+
+#endif
+
diff -r 266aef9b0386 -r 47cc7392741a 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe_backend.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe_backend.c    Wed Oct 
25 13:58:30 2006 +0100
@@ -0,0 +1,271 @@
+/******************************************************************************
+ * Talks to Xen Store to figure out what devices we have (backend half).
+ *
+ * Copyright (C) 2005 Rusty Russell, IBM Corporation
+ * Copyright (C) 2005 Mike Wray, Hewlett-Packard
+ * Copyright (C) 2005, 2006 XenSource Ltd
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#define DPRINTK(fmt, args...)                          \
+       pr_debug("xenbus_probe (%s:%d) " fmt ".\n",     \
+                __FUNCTION__, __LINE__, ##args)
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+#include <linux/notifier.h>
+#include <linux/kthread.h>
+
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/maddr.h>
+#include <asm/pgtable.h>
+#include <asm/hypervisor.h>
+#include <xen/xenbus.h>
+#include <xen/xen_proc.h>
+#include <xen/evtchn.h>
+#include <xen/features.h>
+#include <xen/hvm.h>
+
+#include "xenbus_comms.h"
+#include "xenbus_probe.h"
+
+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
+#include <xen/platform-compat.h>
+#endif
+
+static int xenbus_uevent_backend(struct device *dev, char **envp,
+                                int num_envp, char *buffer, int buffer_size);
+static int xenbus_probe_backend(const char *type, const char *domid);
+
+extern int read_otherend_details(struct xenbus_device *xendev,
+                                char *id_node, char *path_node);
+
+static int read_frontend_details(struct xenbus_device *xendev)
+{
+       return read_otherend_details(xendev, "frontend-id", "frontend");
+}
+
+/* backend/<type>/<fe-uuid>/<id> => <type>-<fe-domid>-<id> */
+static int backend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
+{
+       int domid, err;
+       const char *devid, *type, *frontend;
+       unsigned int typelen;
+
+       type = strchr(nodename, '/');
+       if (!type)
+               return -EINVAL;
+       type++;
+       typelen = strcspn(type, "/");
+       if (!typelen || type[typelen] != '/')
+               return -EINVAL;
+
+       devid = strrchr(nodename, '/') + 1;
+
+       err = xenbus_gather(XBT_NIL, nodename, "frontend-id", "%i", &domid,
+                           "frontend", NULL, &frontend,
+                           NULL);
+       if (err)
+               return err;
+       if (strlen(frontend) == 0)
+               err = -ERANGE;
+       if (!err && !xenbus_exists(XBT_NIL, frontend, ""))
+               err = -ENOENT;
+       kfree(frontend);
+
+       if (err)
+               return err;
+
+       if (snprintf(bus_id, BUS_ID_SIZE,
+                    "%.*s-%i-%s", typelen, type, domid, devid) >= BUS_ID_SIZE)
+               return -ENOSPC;
+       return 0;
+}
+
+static struct xen_bus_type xenbus_backend = {
+       .root = "backend",
+       .levels = 3,            /* backend/type/<frontend>/<id> */
+       .get_bus_id = backend_bus_id,
+       .probe = xenbus_probe_backend,
+       .bus = {
+               .name     = "xen-backend",
+               .match    = xenbus_match,
+               .probe    = xenbus_dev_probe,
+               .remove   = xenbus_dev_remove,
+//             .shutdown = xenbus_dev_shutdown,
+               .uevent   = xenbus_uevent_backend,
+       },
+       .dev = {
+               .bus_id = "xen-backend",
+       },
+};
+
+static int xenbus_uevent_backend(struct device *dev, char **envp,
+                                int num_envp, char *buffer, int buffer_size)
+{
+       struct xenbus_device *xdev;
+       struct xenbus_driver *drv;
+       int i = 0;
+       int length = 0;
+
+       DPRINTK("");
+
+       if (dev == NULL)
+               return -ENODEV;
+
+       xdev = to_xenbus_device(dev);
+       if (xdev == NULL)
+               return -ENODEV;
+
+       /* stuff we want to pass to /sbin/hotplug */
+       add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
+                      "XENBUS_TYPE=%s", xdev->devicetype);
+
+       add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
+                      "XENBUS_PATH=%s", xdev->nodename);
+
+       add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
+                      "XENBUS_BASE_PATH=%s", xenbus_backend.root);
+
+       /* terminate, set to next free slot, shrink available space */
+       envp[i] = NULL;
+       envp = &envp[i];
+       num_envp -= i;
+       buffer = &buffer[length];
+       buffer_size -= length;
+
+       if (dev->driver) {
+               drv = to_xenbus_driver(dev->driver);
+               if (drv && drv->uevent)
+                       return drv->uevent(xdev, envp, num_envp, buffer,
+                                          buffer_size);
+       }
+
+       return 0;
+}
+
+int xenbus_register_backend(struct xenbus_driver *drv)
+{
+       drv->read_otherend_details = read_frontend_details;
+
+       return xenbus_register_driver_common(drv, &xenbus_backend);
+}
+EXPORT_SYMBOL_GPL(xenbus_register_backend);
+
+/* backend/<typename>/<frontend-uuid>/<name> */
+static int xenbus_probe_backend_unit(const char *dir,
+                                    const char *type,
+                                    const char *name)
+{
+       char *nodename;
+       int err;
+
+       nodename = kasprintf("%s/%s", dir, name);
+       if (!nodename)
+               return -ENOMEM;
+
+       DPRINTK("%s\n", nodename);
+
+       err = xenbus_probe_node(&xenbus_backend, type, nodename);
+       kfree(nodename);
+       return err;
+}
+
+/* backend/<typename>/<frontend-domid> */
+static int xenbus_probe_backend(const char *type, const char *domid)
+{
+       char *nodename;
+       int err = 0;
+       char **dir;
+       unsigned int i, dir_n = 0;
+
+       DPRINTK("");
+
+       nodename = kasprintf("%s/%s/%s", xenbus_backend.root, type, domid);
+       if (!nodename)
+               return -ENOMEM;
+
+       dir = xenbus_directory(XBT_NIL, nodename, "", &dir_n);
+       if (IS_ERR(dir)) {
+               kfree(nodename);
+               return PTR_ERR(dir);
+       }
+
+       for (i = 0; i < dir_n; i++) {
+               err = xenbus_probe_backend_unit(nodename, type, dir[i]);
+               if (err)
+                       break;
+       }
+       kfree(dir);
+       kfree(nodename);
+       return err;
+}
+
+static void backend_changed(struct xenbus_watch *watch,
+                           const char **vec, unsigned int len)
+{
+       DPRINTK("");
+
+       dev_changed(vec[XS_WATCH_PATH], &xenbus_backend);
+}
+
+static struct xenbus_watch be_watch = {
+       .node = "backend",
+       .callback = backend_changed,
+};
+
+void xenbus_backend_suspend(int (*fn)(struct device *, void *))
+{
+       DPRINTK("");
+       bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
+}
+
+void xenbus_backend_resume(int (*fn)(struct device *, void *))
+{
+       DPRINTK("");
+       bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
+}
+
+void xenbus_backend_probe_and_watch(void)
+{
+       xenbus_probe_devices(&xenbus_backend);
+       register_xenbus_watch(&be_watch);
+}
+
+void xenbus_backend_bus_register(void)
+{
+       bus_register(&xenbus_backend.bus);
+}
+
+void xenbus_backend_device_register(void)
+{
+       device_register(&xenbus_backend.dev);
+}

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [LINUX] Move xenbus backend probing into a separate source file and, Xen patchbot-unstable <=