# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID 2e6e1eb66c5e51759ffcb04f95cb3ffa1f1cf4f2
# Parent 62e13cae2f5861169c9102241fbfeca25681f602
Major xenbus cleanup
1) Make xenbus_* functions first-class citizens, evict xs_ prefix.
2) Add xenbus_scanf and xenbus_printf instead of multiple functions
3) Remove unused code from xenbus.c
4) Use standard debugging macros.
Signed-off-by: Rusty Russel <rusty@xxxxxxxxxxxxxxx>
Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>
diff -r 62e13cae2f58 -r 2e6e1eb66c5e
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Tue Jul 26
15:57:18 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Tue Jul 26
16:59:40 2005
@@ -26,6 +26,8 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
+#define DEBUG
+
#include <asm-xen/hypervisor.h>
#include <asm-xen/xenbus.h>
#include <linux/kernel.h>
@@ -39,148 +41,9 @@
/* Name of field containing device type. */
#define XENBUS_DEVICE_TYPE "type"
-#define DEBUG
-
-#ifdef DEBUG
-#define dprintf(_fmt, _args...) \
-printk(KERN_INFO __stringify(KBUILD_MODNAME) " [DBG] %s" _fmt,
__FUNCTION__, ##_args)
-#else
-#define dprintf(_fmt, _args...) do { } while(0)
-#endif
-
static int xs_init_done = 0;
-/* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
-int xenbus_gather(const char *dir, ...)
-{
- va_list ap;
- const char *name;
- int ret = 0;
-
- va_start(ap, dir);
- while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
- const char *fmt = va_arg(ap, char *);
- void *result = va_arg(ap, void *);
- char *p;
-
- p = xenbus_read(dir, name, NULL);
- if (IS_ERR(p)) {
- ret = PTR_ERR(p);
- break;
- }
- if (sscanf(p, fmt, result) == 0)
- ret = -EINVAL;
- kfree(p);
- }
- va_end(ap);
- return ret;
-}
-
-/* Return the path to dir with /name appended.
- * If name is null or empty returns a copy of dir.
- */
-char *xenbus_path(const char *dir, const char *name)
-{
- char *ret;
- int len;
-
- len = strlen(dir) + 1;
- if (name)
- len += strlen(name) + 1;
- ret = kmalloc(len, GFP_KERNEL);
- if (ret == NULL)
- return NULL;
- strcpy(ret, dir);
- if (name) {
- strcat(ret, "/");
- strcat(ret, name);
- }
- return ret;
-}
-
#define streq(a, b) (strcmp((a), (b)) == 0)
-
-char *xenbus_read(const char *dir, const char *name, unsigned int *data_n)
-{
- int err = 0;
- char *data = NULL;
- char *path = xenbus_path(dir, name);
- int n = 0;
-
- if (!path) {
- err = -ENOMEM;
- goto out;
- }
- data = xs_read(path, &n);
- if (IS_ERR(data)) {
- err = PTR_ERR(data);
- if (err == -EISDIR)
- err = -ENOENT;
- } else if (n == 0) {
- err = -ENOENT;
- kfree(data);
- }
- kfree(path);
- out:
- if (data_n)
- *data_n = n;
- return (err ? ERR_PTR(err) : data);
-}
-
-int xenbus_write(const char *dir, const char *name, const char *data, int
data_n)
-{
- int err = 0;
- char *path = xenbus_path(dir, name);
-
- if (!path)
- return -ENOMEM;
- err = xs_write(path, data, data_n, O_CREAT);
- kfree(path);
- return err;
-}
-
-int xenbus_read_string(const char *dir, const char *name, char **val)
-{
- int err = 0;
-
- *val = xenbus_read(dir, name, NULL);
- if (IS_ERR(*val)) {
- err = PTR_ERR(*val);
- *val = NULL;
- }
- return err;
-}
-
-int xenbus_write_string(const char *dir, const char *name, const char *val)
-{
- return xenbus_write(dir, name, val, strlen(val));
-}
-
-int xenbus_read_ulong(const char *dir, const char *name, unsigned long *val)
-{
- return xenbus_gather(dir, name, "%lu", val, NULL);
-}
-
-int xenbus_write_ulong(const char *dir, const char *name, unsigned long val)
-{
- char data[32] = {};
-
- snprintf(data, sizeof(data), "%lu", val);
- return xenbus_write(dir, name, data, strlen(data));
-}
-
-int xenbus_read_long(const char *dir, const char *name, long *val)
-{
- return xenbus_gather(dir, name, "%li", val, NULL);
-}
-
-int xenbus_write_long(const char *dir, const char *name, long val)
-{
- char data[32] = {};
-
- snprintf(data, sizeof(data), "%li", val);
- return xenbus_write(dir, name, data, strlen(data));
-}
/* If something in array of ids matches this device, return it. */
static const struct xenbus_device_id *
@@ -214,68 +77,6 @@
.match = xenbus_match,
};
-
-/* Bus type for backend drivers. */
-static struct bus_type xenback_type = {
- .name = "xenback",
- .match = xenbus_match,
-};
-
-struct xenbus_for_dev {
- int (*fn)(struct xenbus_device *, void *);
- void *data;
-};
-
-static int for_dev(struct device *_dev, void *_data)
-{
- struct xenbus_device *dev = to_xenbus_device(_dev);
- struct xenbus_for_dev *data = _data;
- dev = to_xenbus_device(_dev);
- return data->fn(dev, data->data);
-}
-
-int xenbus_for_each_dev(struct xenbus_device * start, void * data,
- int (*fn)(struct xenbus_device *, void *))
-{
- struct xenbus_for_dev for_data = {
- .fn = fn,
- .data = data,
- };
- if (!fn)
- return -EINVAL;
- printk("%s> data=%p fn=%p for_data=%p\n", __FUNCTION__,
- data, fn, &for_data);
- return bus_for_each_dev(&xenbus_type,
- (start ? &start->dev : NULL),
- &for_data, for_dev);
-}
-
-struct xenbus_for_drv {
- int (*fn)(struct xenbus_driver *, void *);
- void *data;
-};
-
-static int for_drv(struct device_driver *_drv, void *_data)
-{
- struct xenbus_driver *drv = to_xenbus_driver(_drv);
- struct xenbus_for_drv *data = _data;
- return data->fn(drv, data->data);
-}
-
-int xenbus_for_each_drv(struct xenbus_driver * start, void * data,
- int (*fn)(struct xenbus_driver *, void *))
-{
- struct xenbus_for_drv for_data = {
- .fn = fn,
- .data = data,
- };
- if (!fn)
- return -EINVAL;
- return bus_for_each_drv(&xenbus_type,
- (start ? &start->driver: NULL),
- &for_data, for_drv);
-}
-
static int xenbus_dev_probe(struct device *_dev)
{
struct xenbus_device *dev = to_xenbus_device(_dev);
@@ -309,23 +110,13 @@
int xenbus_register_driver(struct xenbus_driver *drv)
{
- int err = 0;
-
- printk("%s> frontend driver %p %s\n", __FUNCTION__,
- drv, drv->name);
drv->driver.name = drv->name;
drv->driver.bus = &xenbus_type;
drv->driver.owner = drv->owner;
drv->driver.probe = xenbus_dev_probe;
drv->driver.remove = xenbus_dev_remove;
- err = driver_register(&drv->driver);
- if (err == 0 && xs_init_done && drv->connect) {
- printk("%s> connecting driver %p %s\n", __FUNCTION__,
- drv, drv->name);
- drv->connect(drv);
- }
- return err;
+ return driver_register(&drv->driver);
}
void xenbus_unregister_driver(struct xenbus_driver *drv)
@@ -333,39 +124,36 @@
driver_unregister(&drv->driver);
}
-static int xenbus_probe_device(const char *dir, const char *name, const char
*devicetype)
+/* devices/<typename>/<name> */
+static int xenbus_probe_device(const char *typename, const char *name)
{
int err;
struct xenbus_device *xendev;
- unsigned int xendev_n;
- char *nodename;
-
- dprintf("> dir=%s name=%s\n", dir, name);
- nodename = xenbus_path(dir, name);
- if (!nodename)
+ unsigned int stringlen;
+
+ pr_debug("> dir=%s name=%s\n", typename, name);
+
+ /* FIXME: This could be a rescan. Don't re-register existing devices. */
+
+ /* Nodename: /device/<typename>/<name>/ */
+ stringlen = strlen("device") + strlen(typename) + strlen(name) + 3;
+ /* Typename */
+ stringlen += strlen(typename) + 1;
+
+ xendev = kmalloc(sizeof(*xendev) + stringlen, GFP_KERNEL);
+ if (!xendev)
return -ENOMEM;
- /* FIXME: This could be a rescan. Don't re-register existing devices. */
-
- /* Add space for the strings. */
- xendev_n = sizeof(*xendev) + strlen(nodename) + strlen(devicetype) + 2;
- xendev = kmalloc(xendev_n, GFP_KERNEL);
- if (!xendev) {
- err = -ENOMEM;
- goto free_nodename;
- }
- memset(xendev, 0, xendev_n);
-
- snprintf(xendev->dev.bus_id, BUS_ID_SIZE, "%s-%s", devicetype, name);
- xendev->dev.bus = &xenbus_type;
-
- xendev->id = simple_strtol(name, NULL, 0);
-
+ memset(xendev, 0, sizeof(*xendev));
/* Copy the strings into the extra space. */
xendev->nodename = (char *)(xendev + 1);
- strcpy(xendev->nodename, nodename);
+ sprintf(xendev->nodename, "%s/%s/%s", "device", typename, name);
xendev->devicetype = xendev->nodename + strlen(xendev->nodename) + 1;
- strcpy(xendev->devicetype, devicetype);
+ strcpy(xendev->devicetype, typename);
+
+ /* FIXME: look for "subtype" field. */
+ snprintf(xendev->dev.bus_id, BUS_ID_SIZE, "%s-%s", typename, name);
+ xendev->dev.bus = &xenbus_type;
/* Register with generic device framework. */
printk("XENBUS: Registering device %s\n", xendev->dev.bus_id);
@@ -376,203 +164,61 @@
kfree(xendev);
}
-free_nodename:
- kfree(nodename);
- dprintf("< err=%i\n", err);
- return err;
-}
-
-static int xenbus_probe_device_type(const char *dirpath, const char *typename)
+ pr_debug("< err=%i\n", err);
+ return err;
+}
+
+/* /device/<typename> */
+static int xenbus_probe_device_type(const char *typename)
{
int err = 0;
char **dir;
- char *path;
unsigned int dir_n = 0;
int i;
- dprintf("> dirpath=%s typename=%s\n", dirpath, typename);
- path = xenbus_path(dirpath, typename);
- if (!path)
- return -ENOMEM;
-
- dir = xs_directory(path, &dir_n);
+ dir = xenbus_directory("device", typename, &dir_n);
+ printk("dir %s has %u entries\n", typename, dir_n);
if (IS_ERR(dir)) {
- err = PTR_ERR(dir);
- goto out;
+ printk("dir %s returned %li\n", typename, PTR_ERR(dir));
+ return PTR_ERR(dir);
}
for (i = 0; i < dir_n; i++) {
- err = xenbus_probe_device(path, dir[i], typename);
+ printk("Probing %s/%s\n", dir[i], typename);
+ err = xenbus_probe_device(dir[i], typename);
if (err)
break;
}
kfree(dir);
-out:
- kfree(path);
- dprintf("< err=%i\n", err);
- return err;
-}
-
-static int xenbus_probe_devices(const char *path)
+ pr_debug("< err=%i\n", err);
+ return err;
+}
+
+static int xenbus_probe_devices(void)
{
int err = 0;
char **dir;
unsigned int i, dir_n;
- dprintf("> path=%s\n", path);
- down(&xs_lock);
- dir = xs_directory(path, &dir_n);
+ down(&xenbus_lock);
+ dir = xenbus_directory("device", "", &dir_n);
if (IS_ERR(dir)) {
err = PTR_ERR(dir);
goto unlock;
}
for (i = 0; i < dir_n; i++) {
- err = xenbus_probe_device_type(path, dir[i]);
- if (err)
+ err = xenbus_probe_device_type(dir[i]);
+ if (err) {
+ printk("xenbus: error %i probing device %s\n",
+ -err, dir[i]);
break;
+ }
}
kfree(dir);
unlock:
- up(&xs_lock);
- dprintf("< err=%i\n", err);
- return err;
-}
-
-
-static int xenbus_probe_backend(const char *dir, const char *name)
-{
- int err = 0;
- struct xenbus_device *xendev = NULL;
- unsigned int xendev_n = 0;
- char *nodename = NULL, *devicetype = NULL;
- unsigned int devicetype_n = 0;
-
- dprintf("> dir=%s name=%s\n", dir, name);
- nodename = xenbus_path(dir, name);
- if (!nodename)
- return -ENOMEM;
-
- devicetype = xenbus_read(nodename, XENBUS_DEVICE_TYPE, &devicetype_n);
- if (IS_ERR(devicetype)) {
- err = PTR_ERR(devicetype);
- goto free_nodename;
- }
-
- dprintf("> devicetype='%s'\n", devicetype);
- /* FIXME: This could be a rescan. Don't re-register existing devices. */
-
- /* Add space for the strings. */
- xendev_n = sizeof(*xendev) + strlen(nodename) + strlen(devicetype) + 2;
- xendev = kmalloc(xendev_n, GFP_KERNEL);
- if (!xendev) {
- err = -ENOMEM;
- goto free_devicetype;
- }
- memset(xendev, 0, xendev_n);
-
- snprintf(xendev->dev.bus_id, BUS_ID_SIZE, "%s", devicetype);
- xendev->dev.bus = &xenback_type;
-
- /* Copy the strings into the extra space. */
- xendev->nodename = (char *)(xendev + 1);
- strcpy(xendev->nodename, nodename);
- xendev->devicetype = xendev->nodename + strlen(xendev->nodename) + 1;
- strcpy(xendev->devicetype, devicetype);
-
- /* Register with generic device framework. */
- printk("XENBUS: Registering backend %s\n", xendev->dev.bus_id);
- err = device_register(&xendev->dev);
- if (err) {
- printk("XENBUS: Registering device %s: error %i\n",
- xendev->dev.bus_id, err);
- kfree(xendev);
- }
-
-free_devicetype:
- kfree(devicetype);
-free_nodename:
- kfree(nodename);
- dprintf("< err=%i\n", err);
- return err;
-}
-
-static int xenbus_probe_backends(const char *path)
-{
- int err = 0;
- char **dir;
- unsigned int i, dir_n;
-
- dprintf("> path=%s\n", path);
- down(&xs_lock);
- dir = xs_directory(path, &dir_n);
- if (IS_ERR(dir)) {
- err = PTR_ERR(dir);
- goto unlock;
- }
- for (i = 0; i < dir_n; i++) {
- err = xenbus_probe_backend(path, dir[i]);
- if (err)
- break;
- }
- kfree(dir);
-unlock:
- up(&xs_lock);
- dprintf("< err=%i\n", err);
- return err;
-}
-
-int xenbus_register_backend(struct xenbus_driver *drv)
-{
- int err = 0;
-
- printk("%s> backend driver %p %s\n", __FUNCTION__,
- drv, drv->name);
- drv->driver.name = drv->name;
- drv->driver.bus = &xenback_type;
- drv->driver.owner = drv->owner;
- drv->driver.probe = xenbus_dev_probe;
- drv->driver.remove = xenbus_dev_remove;
-
- err = driver_register(&drv->driver);
- if (err == 0 && xs_init_done && drv->connect) {
- printk("%s> connecting driver %p %s\n", __FUNCTION__,
- drv, drv->name);
- drv->connect(drv);
- }
- return err;
-}
-
-void xenbus_unregister_backend(struct xenbus_driver *drv)
-{
- driver_unregister(&drv->driver);
-}
-
-int xenbus_for_each_backend(struct xenbus_driver * start, void * data,
- int (*fn)(struct xenbus_driver *, void *))
-{
- struct xenbus_for_drv for_data = {
- .fn = fn,
- .data = data,
- };
- if (!fn)
- return -EINVAL;
- return bus_for_each_drv(&xenback_type,
- (start ? &start->driver: NULL),
- &for_data, for_drv);
-}
-
-static int xenbus_driver_connect(struct xenbus_driver *drv, void *data)
-{
- printk("%s> driver %p %s\n", __FUNCTION__, drv, drv->name);
- if (drv->connect) {
- printk("%s> connecting driver %p %s\n", __FUNCTION__,
- drv, drv->name);
- drv->connect(drv);
- }
- printk("%s< driver %p %s\n", __FUNCTION__, drv, drv->name);
- return 0;
-}
-
+ up(&xenbus_lock);
+ return err;
+}
/* called from a thread in privcmd/privcmd.c */
int do_xenbus_probe(void *unused)
@@ -592,15 +238,8 @@
}
xs_init_done = 1;
- /* Notify drivers that xenstore has connected. */
- printk("%s> connect drivers...\n", __FUNCTION__);
- xenbus_for_each_drv(NULL, NULL, xenbus_driver_connect);
- printk("%s> connect backends...\n", __FUNCTION__);
- xenbus_for_each_backend(NULL, NULL, xenbus_driver_connect);
-
- /* Enumerate devices and backends in xenstore. */
- xenbus_probe_devices("device");
- xenbus_probe_backends("backend");
+ /* Enumerate devices in xenstore. */
+ xenbus_probe_devices();
exit:
printk("%s< err=%d\n", __FUNCTION__, err);
@@ -610,7 +249,6 @@
static int __init xenbus_probe_init(void)
{
bus_register(&xenbus_type);
- bus_register(&xenback_type);
if (!xen_start_info.store_evtchn)
return 0;
diff -r 62e13cae2f58 -r 2e6e1eb66c5e
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Tue Jul 26
15:57:18 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Tue Jul 26
16:59:40 2005
@@ -2,7 +2,7 @@
* xenbus_xs.c
*
* This is the kernel equivalent of the "xs" library. We don't need everything
- * and we use xenbus_comms to communication.
+ * and we use xenbus_comms for communication.
*
* Copyright (C) 2005 Rusty Russell, IBM Corporation
*
@@ -45,7 +45,7 @@
static void *xs_in, *xs_out;
static LIST_HEAD(watches);
-DECLARE_MUTEX(xs_lock);
+DECLARE_MUTEX(xenbus_lock);
static int get_error(const char *errorstring)
{
@@ -90,7 +90,7 @@
}
/* Emergency write. */
-void xs_debug_write(const char *str, unsigned int count)
+void xenbus_debug_write(const char *str, unsigned int count)
{
struct xsd_sockmsg msg;
void *out = (void *)xen_start_info.store_page;
@@ -115,7 +115,7 @@
unsigned int i;
int err;
- WARN_ON(down_trylock(&xs_lock) == 0);
+ WARN_ON(down_trylock(&xenbus_lock) == 0);
msg.type = type;
msg.len = 0;
@@ -182,12 +182,28 @@
return num;
}
-char **xs_directory(const char *path, unsigned int *num)
+/* Return the path to dir with /name appended. */
+static char *join(const char *dir, const char *name)
+{
+ static char buffer[4096];
+
+ BUG_ON(down_trylock(&xenbus_lock) == 0);
+ BUG_ON(strlen(dir) + strlen("/") + strlen(name) + 1 > sizeof(buffer));
+
+ strcpy(buffer, dir);
+ if (!streq(name, "")) {
+ strcat(buffer, "/");
+ strcat(buffer, name);
+ }
+ return buffer;
+}
+
+char **xenbus_directory(const char *dir, const char *node, unsigned int *num)
{
char *strings, *p, **ret;
unsigned int len;
- strings = xs_single(XS_DIRECTORY, path, &len);
+ strings = xs_single(XS_DIRECTORY, join(dir, node), &len);
if (IS_ERR(strings))
return (char **)strings;
@@ -210,67 +226,37 @@
}
/* Check if a path exists. Return 1 if it does. */
-int xs_exists(const char *path)
-{
- char **dir;
+int xenbus_exists(const char *dir, const char *node)
+{
+ char **d;
int dir_n;
- dir = xs_directory(path, &dir_n);
- if (IS_ERR(dir))
+ d = xenbus_directory(path, node, &dir_n);
+ if (IS_ERR(d))
return 0;
- kfree(dir);
+ kfree(d);
return 1;
}
-
-/* Make a directory, creating dirs on the path to it if necessary.
- * Return 0 on success, error code otherwise.
- */
-int xs_mkdirs(const char *path)
-{
- int err = 0;
- char s[strlen(path) + 1], *p = s;
-
- if (xs_exists(path))
- goto out;
- strcpy(p, path);
- if (*p == '/')
- p++;
- for (;;) {
- p = strchr(p, '/');
- if (p)
- *p = '\0';
- if (!xs_exists(s)) {
- err = xs_mkdir(s);
- if (err)
- goto out;
- }
- if (!p)
- break;
- *p++ = '/';
- }
- out:
- return err;
-}
-
/* Get the value of a single file.
* Returns a kmalloced value: call free() on it after use.
* len indicates length in bytes.
*/
-void *xs_read(const char *path, unsigned int *len)
-{
- return xs_single(XS_READ, path, len);
+void *xenbus_read(const char *dir, const char *node, unsigned int *len)
+{
+ return xs_single(XS_READ, join(dir, node), len);
}
/* Write the value of a single file.
* Returns -err on failure. createflags can be 0, O_CREAT, or O_CREAT|O_EXCL.
*/
-int xs_write(const char *path,
- const void *data, unsigned int len, int createflags)
-{
- const char *flags;
+int xenbus_write(const char *dir, const char *node,
+ const char *string, int createflags)
+{
+ const char *flags, *path;
struct kvec iovec[3];
+ path = join(dir, node);
/* Format: Flags (as string), path, data. */
if (createflags == 0)
flags = XS_WRITE_NONE;
@@ -285,22 +271,22 @@
iovec[0].iov_len = strlen(path) + 1;
iovec[1].iov_base = (void *)flags;
iovec[1].iov_len = strlen(flags) + 1;
- iovec[2].iov_base = (void *)data;
- iovec[2].iov_len = len;
+ iovec[2].iov_base = (void *)string;
+ iovec[2].iov_len = strlen(string);
return xs_error(xs_talkv(XS_WRITE, iovec, ARRAY_SIZE(iovec), NULL));
}
/* Create a new directory. */
-int xs_mkdir(const char *path)
-{
- return xs_error(xs_single(XS_MKDIR, path, NULL));
+int xenbus_mkdir(const char *dir, const char *node)
+{
+ return xs_error(xs_single(XS_MKDIR, join(dir, node), NULL));
}
/* Destroy a file or directory (directories must be empty). */
-int xs_rm(const char *path)
-{
- return xs_error(xs_single(XS_RM, path, NULL));
+int xenbus_rm(const char *dir, const char *node)
+{
+ return xs_error(xs_single(XS_RM, join(dir, node), NULL));
}
/* Start a transaction: changes by others will not be seen during this
@@ -308,7 +294,7 @@
* Transaction only applies to the given subtree.
* You can only have one transaction at any time.
*/
-int xs_transaction_start(const char *subtree)
+int xenbus_transaction_start(const char *subtree)
{
return xs_error(xs_single(XS_TRANSACTION_START, subtree, NULL));
}
@@ -316,7 +302,7 @@
/* End a transaction.
* If abandon is true, transaction is discarded instead of committed.
*/
-int xs_transaction_end(int abort)
+int xenbus_transaction_end(int abort)
{
char abortstr[2];
@@ -327,12 +313,68 @@
return xs_error(xs_single(XS_TRANSACTION_END, abortstr, NULL));
}
-char *xs_get_domain_path(domid_t domid)
-{
- char domid_str[32];
-
- sprintf(domid_str, "%u", domid);
- return xs_single(XS_GETDOMAINPATH, domid_str, NULL);
+/* Single read and scanf: returns -errno or num scanned. */
+int xenbus_scanf(const char *dir, const char *node, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+ char *val;
+
+ val = xenbus_read(dir, node, NULL);
+ if (IS_ERR(val))
+ return PTR_ERR(val);
+
+ va_start(ap, fmt);
+ ret = vsscanf(val, fmt, ap);
+ va_end(ap);
+ kfree(val);
+ /* Distinctive errno. */
+ if (ret == 0)
+ return -ERANGE;
+ return ret;
+}
+
+/* Single printf and write: returns -errno or 0. */
+int xenbus_printf(const char *dir, const char *node, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+ static char buffer[4096];
+
+ BUG_ON(down_trylock(&xenbus_lock) == 0);
+ va_start(ap, fmt);
+ ret = vsnprintf(buffer, sizeof(buffer), fmt, ap);
+ va_end(ap);
+
+ BUG_ON(ret > sizeof(buffer)-1);
+
+ return xenbus_write(dir, node, buffer, ret+1);
+}
+
+/* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
+int xenbus_gather(const char *dir, ...)
+{
+ va_list ap;
+ const char *name;
+ int ret = 0;
+
+ va_start(ap, dir);
+ while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
+ const char *fmt = va_arg(ap, char *);
+ void *result = va_arg(ap, void *);
+ char *p;
+
+ p = xenbus_read(dir, name, NULL);
+ if (IS_ERR(p)) {
+ ret = PTR_ERR(p);
+ break;
+ }
+ if (sscanf(p, fmt, result) == 0)
+ ret = -EINVAL;
+ kfree(p);
+ }
+ va_end(ap);
+ return ret;
}
static int xs_watch(const char *path, const char *token, unsigned int priority)
@@ -429,7 +471,6 @@
static int watch_thread(void *unused)
{
-
for (;;) {
char *token;
char *node = NULL;
@@ -440,7 +481,7 @@
* doing an op, they'll hold the lock and the buffer
* will be empty by the time we get there.
*/
- down(&xs_lock);
+ down(&xenbus_lock);
if (xs_input_avail(xs_in))
node = xs_read_watch(&token);
@@ -461,7 +502,7 @@
} else
printk(KERN_WARNING "XENBUS xs_read_watch: %li\n",
PTR_ERR(node));
- up(&xs_lock);
+ up(&xenbus_lock);
}
}
diff -r 62e13cae2f58 -r 2e6e1eb66c5e
linux-2.6-xen-sparse/include/asm-xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h Tue Jul 26 15:57:18 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h Tue Jul 26 16:59:40 2005
@@ -36,7 +36,6 @@
char *devicetype;
char *subtype;
char *nodename;
- int id;
struct device dev;
void *data;
};
@@ -58,21 +57,11 @@
char *name;
struct module *owner;
const struct xenbus_device_id *ids;
- /* Called when xenstore is connected. */
- int (*connect) (struct xenbus_driver * drv);
-
- int (*probe) (struct xenbus_device * dev, const struct
xenbus_device_id * id);
+ int (*probe) (struct xenbus_device * dev,
+ const struct xenbus_device_id * id);
int (*remove) (struct xenbus_device * dev);
- int (*configure)(struct xenbus_device * dev);
struct device_driver driver;
-};
-
-struct xenbus_evtchn {
- unsigned long dom1;
- unsigned long port1;
- unsigned long dom2;
- unsigned long port2;
};
static inline struct xenbus_driver *to_xenbus_driver(struct device_driver *drv)
@@ -83,36 +72,31 @@
int xenbus_register_driver(struct xenbus_driver *drv);
void xenbus_unregister_driver(struct xenbus_driver *drv);
-int xenbus_register_backend(struct xenbus_driver *drv);
-void xenbus_unregister_backend(struct xenbus_driver *drv);
-
-/* Iterator over xenbus devices (frontend). */
-int xenbus_for_each_dev(struct xenbus_device * start, void * data,
- int (*fn)(struct xenbus_device *, void *));
-
-/* Iterator over xenbus drivers (frontend). */
-int xenbus_for_each_drv(struct xenbus_driver * start, void * data,
- int (*fn)(struct xenbus_driver *, void *));
-
-/* Iterator over xenbus drivers (backend). */
-int xenbus_for_each_backend(struct xenbus_driver * start, void * data,
- int (*fn)(struct xenbus_driver *, void *));
-
/* Caller must hold this lock to call these functions: it's also held
* across watch callbacks. */
-extern struct semaphore xs_lock;
+extern struct semaphore xenbus_lock;
-char **xs_directory(const char *path, unsigned int *num);
-void *xs_read(const char *path, unsigned int *len);
-int xs_write(const char *path,
- const void *data, unsigned int len, int createflags);
-int xs_mkdir(const char *path);
-int xs_exists(const char *path);
-int xs_mkdirs(const char *path);
-int xs_rm(const char *path);
-int xs_transaction_start(const char *subtree);
-int xs_transaction_end(int abort);
-char *xs_get_domain_path(domid_t domid);
+char **xenbus_directory(const char *dir, const char *node, unsigned int *num);
+void *xenbus_read(const char *dir, const char *node, unsigned int *len);
+int xenbus_write(const char *dir, const char *node,
+ const char *string, int createflags);
+int xenbus_mkdir(const char *dir, const char *node);
+int xenbus_exists(const char *dir, const char *node);
+int xenbus_rm(const char *dir, const char *node);
+int xenbus_transaction_start(const char *subtree);
+int xenbus_transaction_end(int abort);
+
+/* Single read and scanf: returns -errno or num scanned if > 0. */
+int xenbus_scanf(const char *dir, const char *node, const char *fmt, ...)
+ __attribute__((format(scanf, 3, 4)));
+
+/* Single printf and write: returns -errno or 0. */
+int xenbus_printf(const char *dir, const char *node, const char *fmt, ...)
+ __attribute__((format(printf, 3, 4)));
+
+/* Generic read function: NULL-terminated triples of name,
+ * sprintf-style type string, and pointer. Returns 0 or errno.*/
+int xenbus_gather(const char *dir, ...);
/* Register callback to watch this node. */
struct xenbus_watch
@@ -126,20 +110,4 @@
int register_xenbus_watch(struct xenbus_watch *watch);
void unregister_xenbus_watch(struct xenbus_watch *watch);
-/* Generic read function: NULL-terminated triples of name,
- * sprintf-style type string, and pointer. */
-int xenbus_gather(const char *dir, ...);
-
-char *xenbus_path(const char *dir, const char *name);
-char *xenbus_read(const char *dir, const char *name, unsigned int *data_n);
-int xenbus_write(const char *dir, const char *name,
- const char *data, int data_n);
-
-int xenbus_read_string(const char *dir, const char *name, char **val);
-int xenbus_write_string(const char *dir, const char *name, const char *val);
-int xenbus_read_ulong(const char *dir, const char *name, unsigned long *val);
-int xenbus_write_ulong(const char *dir, const char *name, unsigned long val);
-int xenbus_read_long(const char *dir, const char *name, long *val);
-int xenbus_write_long(const char *dir, const char *name, long val);
-
#endif /* _ASM_XEN_XENBUS_H */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|