This patch is the first step toward instrumenting xen through sysfs, and toward migrating the /proc/xen files to /sys/xen. The major component is a set of kernel functions that hopefully make adding files to /sys/xen as easy as adding files to /proc/xen. A smaller file adds xen version information by creating a file under /sys/xen/version. I am looking for feedback on the approach and usefulness of the sysfs support functions. The next step is to add support for sysfs binary files and to experiment with implementing /proc/xen/privcmd as /sysfs/xen/privcmd Mike -- Mike D. Day STSM and Architect, Open Virtualization IBM Linux Technology Center ncmike@us.ibm.com _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Christopher G. Stach II
2006-Jan-10 01:09 UTC
Re: [Xen-devel] [PATCH] [RFC] sysfs support for xen linux
Mike D. Day wrote:> > This patch is the first step toward instrumenting xen through sysfs, and > toward migrating the /proc/xen files to /sys/xen. > > The major component is a set of kernel functions that hopefully make > adding files to /sys/xen as easy as adding files to /proc/xen. A > smaller file adds xen version information by creating a file under > /sys/xen/version. > > I am looking for feedback on the approach and usefulness of the sysfs > support functions. The next step is to add support for sysfs binary > files and to experiment with implementing /proc/xen/privcmd as > /sysfs/xen/privcmd > > Mike > > > ------------------------------------------------------------------------ > > # HG changeset patch > # User mdday@mdday.raleigh.ibm.com > # Node ID cec2fc0a07c611023e096cf3496d948aa39c1342 > # Parent c08884b412da24dd4c05d36fdff408f4433bd865 > # Parent da7873110bbb8b55d9adb9111d100e209fc49ee6 > signed-off-by Mike Day <ncmike@us.ibm.com> > > Stage support for xen to export information using sysfs. Make it just as easy to add a /sys/xen/ file as it is to add a /proc/xen file currently. Starting by exporting xen version information in /sys/xen/version. > > diff -r c08884b412da -r cec2fc0a07c6 linux-2.6-xen-sparse/arch/xen/kernel/xen_sysfs.c > --- /dev/null Mon Jan 9 21:55:13 2006 > +++ b/linux-2.6-xen-sparse/arch/xen/kernel/xen_sysfs.c Mon Jan 9 23:07:04 2006 > @@ -0,0 +1,698 @@ > +/* > + copyright (c) 2006 IBM Corporation > + Mike Day <ncmike@us.ibm.com> > + > + This program is free software; you can redistribute it and/or modify > + it under the terms of the GNU General Public License as published by > + the Free Software Foundation; either version 2 of the License, or > + (at your option) any later version. > + > + This program is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + GNU General Public License for more details. > + > + You should have received a copy of the GNU General Public License > + along with this program; if not, write to the Free Software > + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > +*/ > + > + > +#include <linux/config.h> > +#include <linux/kernel.h> > +#include <linux/init.h> > +#include <linux/kobject.h> > +#include <linux/sysfs.h> > +#include <linux/module.h> > +#include <linux/string.h> > +#include <linux/types.h> > +#include <asm/atomic.h> > +#include <asm/semaphore.h> > +#include <asm-generic/bug.h> > + > +#ifdef DEBUG > +#define DPRINTK(fmt, args...) printk(KERN_DEBUG "xen_sysfs: ", fmt, ## args) > +#else > +#define DPRINTK(fmt, args...) > +#endif > + > +#ifndef BOOL > +#define BOOL int > +#endif > + > +#ifndef FALSE > +#define FALSE 0 > +#endif > + > +#ifndef TRUE > +#define TRUE 1 > +#endif > + > +#ifndef NULL > +#define NULL 0 > +#endif > + > + > +#define __sysfs_ref__ > + > +struct xen_sysfs_object; > + > +struct xen_sysfs_attr > +{ > + struct bin_attribute attr; > + ssize_t (*show)(void *, char *) ; > + ssize_t (*store)(void *, const char *, size_t) ; > + ssize_t (*read)(void *, char *, loff_t, size_t ); > + ssize_t (*write)(void *, char *, loff_t, size_t) ; > +}; > + > + > + > +/* flags bits */ > +#define XEN_SYSFS_UNINITIALIZED 0x00 > +#define XEN_SYSFS_CHAR_TYPE 0x01 > +#define XEN_SYSFS_BIN_TYPE 0x02 > +#define XEN_SYSFS_DIR_TYPE 0x04 > +#define XEN_SYSFS_LINKED 0x08 > +#define XEN_SYSFS_UNLINKED 0x10 > +#define XEN_SYSFS_LINK_TYPE 0x11 > + > + > +struct xen_sysfs_object > +{ > + struct list_head list; > + int flags; > + struct kobject kobj; > + struct xen_sysfs_attr attr; > + char * path; > + struct list_head children; > + struct xen_sysfs_object * parent; > + atomic_t refcount; > + void * user_data; > + void (*user_data_release)(void *); > + void (*destroy)(struct xen_sysfs_object *); > +}; > + > + > +static __sysfs_ref__ struct xen_sysfs_object * > +find_object(struct xen_sysfs_object * obj, const char * path); > + > + > +static __sysfs_ref__ struct xen_sysfs_object * > +new_sysfs_object(const char * path, > + int type, > + int mode, > + ssize_t (*show)(void *, char *), > + ssize_t (*store)(void *, const char *, size_t), > + ssize_t (*read)(void *, char *, loff_t, size_t), > + ssize_t (*write)(void *, char *, loff_t, size_t), > + void * user_data, > + void (* user_data_release)(void *)) ; > + > +static void destroy_sysfs_object(struct xen_sysfs_object * obj); > +static __sysfs_ref__ struct xen_sysfs_object * __find_parent(const char * path) ; > +static __sysfs_ref__ int __add_child(struct xen_sysfs_object *parent, > + struct xen_sysfs_object *child); > +static void remove_child(struct xen_sysfs_object *child); > +static void get_object(struct xen_sysfs_object *); > +static int put_object(struct xen_sysfs_object *, > + void (*)(struct xen_sysfs_object *)); > + > + > +/* Is A == B ? */ > +#define streq(a,b) (strcmp((a),(b)) == 0) > + > +/* Does A start with B ? */ > +#define strstarts(a,b) (strncmp((a),(b),strlen(b)) == 0) > + > + > +#define __sysfs_ref__ > + > +#define XEN_SYSFS_ATTR(_name, _mode, _show, _store) \ > + struct xen_sysfs_attr xen_sysfs_attr_##_name = __ATTR(_name, _mode, _show, _store) > + > +#define __XEN_KOBJ(_parent, _dentry, _ktype) \ > + { \ > + .k_name = NULL, \ > + .parent = _parent, \ > + .dentry = _dentry, \ > + .ktype = _ktype, \ > + } > + > +static struct semaphore xen_sysfs_mut = __MUTEX_INITIALIZER(xen_sysfs_mut); > +static inline int > +sysfs_down(struct semaphore * mut) > +{ > + int err; > + do { > + err = down_interruptible(mut); > + } while ( err && err == -EINTR ); > + return err; > +} > + > +#define sysfs_up(mut) up(mut) > +#define to_xen_attr(_attr) container_of(_attr, struct xen_sysfs_attr, attr.attr) > +#define to_xen_obj(_xen_attr) container_of(_xen_attr, struct xen_sysfs_object, attr) > + > +static ssize_t > +xen_sysfs_show(struct kobject * kobj, struct attribute * attr, char * buf) > +{ > + struct xen_sysfs_attr * xen_attr = to_xen_attr(attr); > + struct xen_sysfs_object * xen_obj = to_xen_obj(xen_attr); > + if(xen_attr->show) > + return xen_attr->show(xen_obj->user_data, buf); > + return 0; > +} > + > +static ssize_t > +xen_sysfs_store(struct kobject * kobj, struct attribute * attr, > + const char *buf, size_t count) > +{ > + struct xen_sysfs_attr * xen_attr = to_xen_attr(attr); > + struct xen_sysfs_object * xen_obj = to_xen_obj(xen_attr); > + if(xen_attr->store) > + return xen_attr->store(xen_obj->user_data, buf, count) ; > + return 0; > +} > + > +#define to_xen_obj_bin(_kobj) container_of(_kobj, struct xen_sysfs_object, kobj) > + > +static ssize_t > +xen_sysfs_read(struct kobject *kobj, char * buf, loff_t offset, size_t size) > +{ > + struct xen_sysfs_object * xen_obj = to_xen_obj_bin(kobj); > + if(xen_obj->attr.read) > + return xen_obj->attr.read(xen_obj->user_data, buf, offset, size); > + return 0; > +} > + > + > +static ssize_t > +xen_sysfs_write(struct kobject *kobj, char * buf, loff_t offset, size_t size) > +{ > + struct xen_sysfs_object * xen_obj = to_xen_obj_bin(kobj); > + if (xen_obj->attr.write) > + return xen_obj->attr.write(xen_obj->user_data, buf, offset, size); > + if(size == 0 ) > + return PAGE_SIZE; > + > + return size; > +} > + > +static struct sysfs_ops xen_sysfs_ops = { > + .show = xen_sysfs_show, > + .store = xen_sysfs_store, > +}; > + > +static struct kobj_type xen_kobj_type = { > + .release = NULL, > + .sysfs_ops = &xen_sysfs_ops, > + .default_attrs = NULL, > +}; > + > + > +/* xen sysfs root entry */ > +static struct xen_sysfs_object xen_root = { > + .flags = 0, > + .kobj = { > + .k_name = NULL, > + .parent = NULL, > + .dentry = NULL, > + .ktype = &xen_kobj_type, > + }, > + .attr = { > + .attr = { > + .attr = { > + .name = NULL, > + .mode = 0775, > + }, > + > + }, > + .show = NULL, > + .store = NULL, > + .read = NULL, > + .write = NULL, > + }, > + .path = __stringify(/sys/xen), > + .list = LIST_HEAD_INIT(xen_root.list), > + .children = LIST_HEAD_INIT(xen_root.children), > + .parent = NULL, > +}; > + > +/* xen sysfs path functions */ > + > +static BOOL > +valid_chars(const char *path) > +{ > + if( ! strstarts(path, "/sys/xen") ) > + return FALSE; > + if(strstr(path, "//")) > + return FALSE; > + return (strspn(path, > + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" > + "abcdefghijklmnopqrstuvwxyz" > + "0123456789-/_@~$") == strlen(path)); > +} > + > + > +/* return value must be kfree''d */ > +static char * > +dup_path(const char *path) > +{ > + char * ret; > + int len; > + BUG_ON( ! path ); > + > + if( FALSE == valid_chars(path) ) { > + return NULL; > + } > + > + len = strlen(path) + 1; > + ret = kcalloc(len - 1, sizeof(char), GFP_KERNEL); > + memcpy(ret, path, len); > + return ret; > +} > + > + > + > +static char * > +basename(const char *name) > +{ > + return strrchr(name, ''/'') + 1; > +} > + > +static char * > +strip_trailing_slash(char * path) > +{ > + int len = strlen(path); > + > + char * term = path + len - 1; > + if( *term == ''/'') > + *term = 0; > + return path; > +} > + > +/* return value must be kfree''d */ > +static char * dirname(const char * name) > +{ > + char *ret; > + int len; > + > + len = strlen(name) - strlen(basename(name)) + 1; > + ret = kcalloc(len, sizeof(char), GFP_KERNEL); > + memcpy(ret, name, len - 1); > + ret = strip_trailing_slash(ret); > + > + return ret; > +} > + > + > +/* type must be char, bin, or dir */ > +static __sysfs_ref__ struct xen_sysfs_object * > +new_sysfs_object(const char * path, > + int type, > + int mode, > + ssize_t (*show)(void *, char *), > + ssize_t (*store)(void *, const char *, size_t), > + ssize_t (*read)(void *, char *, loff_t, size_t), > + ssize_t (*write)(void *, char *, loff_t, size_t), > + void * user_data, > + void (* user_data_release)(void *)) > +{ > + struct xen_sysfs_object * ret = > + (struct xen_sysfs_object *)kcalloc(sizeof(struct xen_sysfs_object), > + sizeof(char), > + GFP_KERNEL); > + BUG_ON(ret == NULL); > + > + ret->flags = type; > + BUG_ON( (type & XEN_SYSFS_DIR_TYPE) && (show || store) ); > + > + if( NULL == (ret->path = dup_path(path)) ) { > + kfree(ret); > + return NULL; > + } > + kobject_set_name(&ret->kobj, basename(path)); > + kobject_init(&ret->kobj); > + ret->attr.attr.attr.name = kobject_name(&ret->kobj); > + ret->attr.attr.attr.owner = THIS_MODULE; > + ret->attr.attr.attr.mode = mode; > + ret->kobj.ktype = &xen_kobj_type; > + if( type & XEN_SYSFS_CHAR_TYPE ) { > + ret->attr.show = show; > + ret->attr.store = store; > + } > + else if ( type & XEN_SYSFS_BIN_TYPE ) { > + ret->attr.attr.size = PAGE_SIZE; > + ret->attr.attr.read = xen_sysfs_read; > + ret->attr.attr.write = xen_sysfs_write; > + ret->attr.read = read; > + ret->attr.write = write; > + } > + INIT_LIST_HEAD(&ret->list); > + INIT_LIST_HEAD(&ret->children); > + atomic_set(&ret->refcount, 1); > + ret->destroy = destroy_sysfs_object; > + return ret; > +} > + > +static void > +get_object(struct xen_sysfs_object *obj) > +{ > + BUG_ON( ! atomic_read(&obj->refcount) ); > + kobject_get(&obj->kobj); > + atomic_inc(&obj->refcount); > + return; > +} > + > +static int > +put_object(struct xen_sysfs_object *obj, > + void (*release)(struct xen_sysfs_object *)) > +{ > + BUG_ON( ! release ); > + BUG_ON( release == (void (*)(struct xen_sysfs_object *))kfree); > + kobject_put(&obj->kobj); > + if(atomic_dec_and_test(&obj->refcount)) { > + release(obj); > + return 1; > + } > + return 0; > +} > + > + > +// TODO delete object > +static void > +sysfs_release(struct xen_sysfs_object * obj) > +{ > + BUG_ON( ! (obj->flags & XEN_SYSFS_UNLINKED) ); > + BUG_ON( ! list_empty(&obj->children) ); > + BUG_ON( obj->parent ) ; > + > + kobject_cleanup(&obj->kobj); > + if(obj->attr.attr.attr.name) > + kfree(obj->attr.attr.attr.name); > + if(obj->user_data && obj->user_data_release ) > + obj->user_data_release(obj->user_data); > + if( obj->path ) { > + kfree(obj->path); > + obj->path = NULL; > + } > + if (obj->destroy) > + obj->destroy(obj); > + return; > +} > + > +static void > +destroy_sysfs_object(struct xen_sysfs_object * obj) > +{ > + if(obj->path) > + kfree(obj->path); > + BUG_ON( ! list_empty(&obj->children) ) ; > + BUG_ON ( obj->parent ); > + kfree(obj); > + return; > +} > + > + > +/* refcounts object when returned */ > +static __sysfs_ref__ struct xen_sysfs_object * > +find_object(struct xen_sysfs_object * obj, const char * path) > +{ > + struct list_head * tmp = NULL; > + struct xen_sysfs_object *this_obj = NULL, * tmp_obj = NULL; > + > + if(obj->flags & XEN_SYSFS_UNLINKED) { > + return NULL; > + } > + if(! strcmp(obj->path, path) ) { > + get_object(obj); > + return obj; > + } > + // if path is longer than obj-path, search children > + if ( strstarts(path, obj->path) && > + strlen(path) > strlen(obj->path) && > + ! list_empty(&obj->children) ) { > + list_for_each(tmp, (&obj->children)) { > + tmp_obj = list_entry(tmp, struct xen_sysfs_object, list); > + if( NULL != (this_obj = find_object(tmp_obj, path)) ) { > + return this_obj; > + } > + } > + } > + return NULL; > +} > + > +/* parent is ref counted when returned */ > +static __sysfs_ref__ struct xen_sysfs_object * > +__find_parent(const char * path) > +{ > + char * dir; > + struct xen_sysfs_object * parent; > + > + BUG_ON( ! path ); > + if ( ! valid_chars(path)) > + return NULL; > + dir = dirname(path); > + BUG_ON ( sysfs_down(&xen_sysfs_mut) ); > + parent = find_object(&xen_root, dir); > + > + sysfs_up(&xen_sysfs_mut); > + kfree(dir); > + > + return parent; > +} > + > +static __sysfs_ref__ int > +__add_child(struct xen_sysfs_object *parent, > + struct xen_sysfs_object *child) > +{ > + int err = EINVAL; > + > + BUG_ON ( sysfs_down(&xen_sysfs_mut) ); > + list_add_tail(&child->list, &parent->children); > + child->kobj.parent = &parent->kobj; > + child->kobj.dentry = parent->kobj.dentry; > + if(child->flags & XEN_SYSFS_DIR_TYPE) > + err = sysfs_create_dir(&child->kobj); > + else if (child->flags & XEN_SYSFS_CHAR_TYPE) > + err = sysfs_create_file(&child->kobj, &child->attr.attr.attr); > + else if (child->flags & XEN_SYSFS_BIN_TYPE) > + err = sysfs_create_bin_file(&child->kobj, &child->attr.attr); > + child->flags |= XEN_SYSFS_LINKED; > + child->flags &= ~XEN_SYSFS_UNLINKED; > + child->parent = parent; > + sysfs_up(&xen_sysfs_mut); > + get_object(parent); > + return err; > +} > + > +static void remove_child(struct xen_sysfs_object *child) > +{ > + struct list_head *children; > + struct xen_sysfs_object *tmp_obj; > + > + children = (&child->children)->next; > + while( children != &child->children ) { > + tmp_obj = list_entry(children, struct xen_sysfs_object, list ); > + remove_child(tmp_obj); > + children = (&child->children)->next; > + } > + child->flags |= XEN_SYSFS_UNLINKED; > + child->flags &= ~XEN_SYSFS_LINKED; > + if(child->flags & XEN_SYSFS_DIR_TYPE) > + sysfs_remove_dir(&child->kobj); > + else if (child->flags & XEN_SYSFS_CHAR_TYPE) > + sysfs_remove_file(&child->kobj, &child->attr.attr.attr); > + else if (child->flags & XEN_SYSFS_BIN_TYPE) > + sysfs_remove_bin_file(&child->kobj, &child->attr.attr); > + list_del(&child->list); > + put_object(child->parent, sysfs_release); > + child->parent = NULL; > + put_object(child, sysfs_release); > + return; > +} > + > + > + > + > +int > +xen_sysfs_create_dir(const char * path, int mode) > +{ > + struct xen_sysfs_object * child, * parent; > + int err; > + > + if(path == NULL) > + return -EINVAL; > + if ( NULL == (parent = __find_parent(path)) ) > + return -EBADF; > + if( NULL == (child = new_sysfs_object(path, XEN_SYSFS_DIR_TYPE, > + mode, NULL,NULL, NULL, > + NULL, NULL,NULL))) { > + put_object(parent, sysfs_release); > + return -ENOMEM; > + } > + err = __add_child(parent, child); > + put_object(parent, sysfs_release); > + > + return -err; > +} > + > +int > +xen_sysfs_remove_dir(const char* path, BOOL recursive) > +{ > + __label__ mut; > + __label__ ref; > + int err = 0; > + struct xen_sysfs_object * dir; > + > + if(path == NULL) > + return -EINVAL; > + BUG_ON(sysfs_down(&xen_sysfs_mut)); > + if(NULL == (dir = find_object(&xen_root, path))) { > + err = -EBADF; > + goto mut; > + } > + if(FALSE == recursive && ! list_empty(&dir->children) ) { > + err = -EBUSY; > + goto ref; > + } > + remove_child(dir); > +ref: > + put_object(dir, sysfs_release); > +mut: > + sysfs_up(&xen_sysfs_mut); > + return err; > +} > + > + > + > +int > +xen_sysfs_create_file(const char * path, > + int mode, > + ssize_t (*show)(void *, char *), > + ssize_t (*store)(void *, const char *, size_t), > + void * private_data, > + void (*private_data_release)(void *)) > +{ > + > + struct xen_sysfs_object *parent, * file; > + int err; > + > + if(path == NULL || FALSE == valid_chars(path)) > + return -EINVAL; > + if(NULL == ( parent = __find_parent(path)) ) > + return -EBADF; > + > + if( NULL == ( file = new_sysfs_object(path, > + XEN_SYSFS_CHAR_TYPE, > + mode, > + show, > + store, > + NULL, > + NULL, > + private_data, > + private_data_release))) > + return -ENOMEM; > + > + err = __add_child(parent, file); > + put_object(parent, sysfs_release); > + return err; > +} > + > + > +int > +xen_sysfs_update_file(const char * path) > +{ > + __label__ mut; > + int err; > + struct xen_sysfs_object * obj; > + > + if(path == NULL || FALSE == valid_chars(path)) > + return -EINVAL; > + sysfs_down(&xen_sysfs_mut); > + > + if(NULL == (obj = find_object(&xen_root, path))) { > + err = -EBADF; > + goto mut; > + } > + > + err = sysfs_update_file(&obj->kobj, &obj->attr.attr.attr); > + put_object(obj, sysfs_release); > +mut: > + sysfs_up(&xen_sysfs_mut); > + return err; > +} > + > + > +int > +xen_sysfs_remove_file(const char* path) > +{ > + __label__ mut; > + int err = 0; > + struct xen_sysfs_object * file; > + > + if(path == NULL) > + return -EINVAL; > + BUG_ON(sysfs_down(&xen_sysfs_mut)); > + if(NULL == (file = find_object(&xen_root, path))) { > + err = -EBADF; > + goto mut; > + } > + remove_child(file); > + put_object(file, sysfs_release); > +mut: > + sysfs_up(&xen_sysfs_mut); > + return err; > +} > + > +int > +xen_sysfs_create_bin_file(const char * path, > + int mode, > + ssize_t (*read) (void *, char *, loff_t, size_t), > + ssize_t (*write) (void *, char *, loff_t, size_t), > + void * private_data, > + void (*private_data_release)(void *)) > +{ > + > + struct xen_sysfs_object *parent, * file; > + int err; > + > + if(path == NULL || FALSE == valid_chars(path)) > + return -EINVAL; > + if(NULL == ( parent = __find_parent(path)) ) > + return -EBADF; > + > + if( NULL == ( file = new_sysfs_object(path, > + XEN_SYSFS_BIN_TYPE, > + mode, > + NULL, > + NULL, > + read, > + write, > + private_data, > + private_data_release))) > + return -ENOMEM; > + > + err = __add_child(parent, file); > + put_object(parent, sysfs_release); > + return err; > +} > + > +int __init > +xen_sysfs_init(void) > +{ > + kobject_init(&xen_root.kobj); > + kobject_set_name(&xen_root.kobj, "xen"); > + atomic_set(&xen_root.refcount, 1); > + return sysfs_create_dir(&xen_root.kobj); > +} > + > +arch_initcall(xen_sysfs_init); > + > +EXPORT_SYMBOL(xen_sysfs_create_dir); > +EXPORT_SYMBOL(xen_sysfs_remove_dir); > +EXPORT_SYMBOL(xen_sysfs_create_file); > +EXPORT_SYMBOL(xen_sysfs_update_file); > +EXPORT_SYMBOL(xen_sysfs_remove_file); > + > + > diff -r c08884b412da -r cec2fc0a07c6 linux-2.6-xen-sparse/arch/xen/kernel/xen_sysfs_version.c > --- /dev/null Mon Jan 9 21:55:13 2006 > +++ b/linux-2.6-xen-sparse/arch/xen/kernel/xen_sysfs_version.c Mon Jan 9 23:07:04 2006 > @@ -0,0 +1,60 @@ > +/* > + copyright (c) 2006 IBM Corporation > + Mike Day <ncmike@us.ibm.com> > + > + This program is free software; you can redistribute it and/or modify > + it under the terms of the GNU General Public License as published by > + the Free Software Foundation; either version 2 of the License, or > + (at your option) any later version. > + > + This program is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + GNU General Public License for more details. > + > + You should have received a copy of the GNU General Public License > + along with this program; if not, write to the Free Software > + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > +*/ > + > +#include <linux/config.h> > +#include <linux/kernel.h> > +#include <linux/init.h> > +#include <linux/types.h> > +#include <asm/page.h> > +#include <asm-xen/xen-public/version.h> > +#include <asm-xen/xen-public/dom0_ops.h> > +#include <asm-xen/asm/hypercall.h> > +#include <asm-xen/xen_sysfs.h> > + > +extern int HYPERVISOR_xen_version(int, void*); > + > + > +static ssize_t xen_version_show(void *data, char *page) > +{ > + long version; > + long major, minor; > + static xen_extraversion_t extra_version; > + > + version = HYPERVISOR_xen_version(XENVER_version, NULL); > + major = version >> 16; > + minor = version & 0xff; > + > + HYPERVISOR_xen_version(XENVER_extraversion, extra_version); > + return snprintf(page, PAGE_SIZE, "xen-%ld.%ld%s\n", major, minor, extra_version); > +} > + > + > + > +int __init > +sysfs_xen_version_init(void) > +{ > + return xen_sysfs_create_file("/sys/xen/version", > + 0444, > + xen_version_show, > + NULL, > + NULL, > + NULL); > +} > + > +device_initcall(sysfs_xen_version_init); > diff -r c08884b412da -r cec2fc0a07c6 linux-2.6-xen-sparse/include/asm-xen/xen_sysfs.h > --- /dev/null Mon Jan 9 21:55:13 2006 > +++ b/linux-2.6-xen-sparse/include/asm-xen/xen_sysfs.h Mon Jan 9 23:07:04 2006 > @@ -0,0 +1,88 @@ > +/* > + copyright (c) 2006 IBM Corporation > + Mike Day <ncmike@us.ibm.com> > + > + This program is free software; you can redistribute it and/or modify > + it under the terms of the GNU General Public License as published by > + the Free Software Foundation; either version 2 of the License, or > + (at your option) any later version. > + > + This program is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + GNU General Public License for more details. > + > + You should have received a copy of the GNU General Public License > + along with this program; if not, write to the Free Software > + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > +*/ > + > + > +#include <asm/page.h> > +#include <linux/init.h> > +#include <linux/types.h> > +#include <linux/string.h> > + > + > + > +#ifndef _XEN_SYSFS_H_ > +#define _XEN_SYSFS_H_ > + > +#ifdef __KERNEL__ > + > +#ifndef BOOL > +#define BOOL int > +#endif > + > +#ifndef FALSE > +#define FALSE 0 > +#endif > + > +#ifndef TRUE > +#define TRUE 1 > +#endif > + > +#ifndef NULL > +#define NULL 0 > +#endif > + > + > +extern int > +xen_sysfs_create_dir(const char * path, int mode); > + > +extern int > +xen_sysfs_remove_dir(const char * path, BOOL recursive); > + > +extern int > +xen_sysfs_create_file(const char * path, > + int mode, > + ssize_t (*show)(void * user_data, char * buf), > + ssize_t (*store)(void * user_data, > + const char * buf, > + size_t length), > + void * private_data, > + void (*private_data_release)(void *)); > + > +extern int > +xen_sysfs_update_file(const char * path); > + > +extern int > +xen_sysfs_remove_file(const char * path); > + > + > +int xen_sysfs_create_bin_file(const char * path, > + int mode, > + ssize_t (*read)(void * user_data, > + char * buf, > + loff_t offset, > + size_t length), > + ssize_t (*write)(void * user_data, > + char *buf, > + loff_t offset, > + size_t length), > + void * private_data, > + void (*private_data_release)(void *)); > +int xen_sysfs_remove_bin_file(const char * path); > + > +#endif /* __KERNEL__ */ > +#endif /* _XEN_SYSFS_H_ */ > # HG changeset patch > # User mdday@mdday.raleigh.ibm.com > # Node ID bd2c30fbc96d3b5e264740720cbcced959ef8c46 > # Parent cec2fc0a07c611023e096cf3496d948aa39c1342 > build xen sysfs support > > diff -r cec2fc0a07c6 -r bd2c30fbc96d linux-2.6-xen-sparse/arch/xen/kernel/Makefile > --- a/linux-2.6-xen-sparse/arch/xen/kernel/Makefile Mon Jan 9 23:07:04 2006 > +++ b/linux-2.6-xen-sparse/arch/xen/kernel/Makefile Mon Jan 9 23:21:19 2006 > > XENARCH := $(subst ",,$(CONFIG_XENARCH)) > @@ -16,3 +16,4 @@ > obj-$(CONFIG_PROC_FS) += xen_proc.o > obj-$(CONFIG_NET) += skbuff.o > obj-$(CONFIG_SMP) += smpboot.o > +obj-$(CONFIG_SYSFS) += xen_sysfs.o xen_sysfs_version.o > > > ------------------------------------------------------------------------ > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/xen-develIn addition to /sys/xen/version, it would also be very helpful to init scripts if there was another file that said whether it is running in dom0 or a domU. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2006-Jan-10 10:13 UTC
Re: [Xen-devel] [PATCH] [RFC] sysfs support for xen linux
On 9 Jan 2006, at 23:35, Mike D. Day wrote:> This patch is the first step toward instrumenting xen through sysfs, > and toward migrating the /proc/xen files to /sys/xen. > > The major component is a set of kernel functions that hopefully make > adding files to /sys/xen as easy as adding files to /proc/xen. A > smaller file adds xen version information by creating a file under > /sys/xen/version. > > I am looking for feedback on the approach and usefulness of the sysfs > support functions. The next step is to add support for sysfs binary > files and to experiment with implementing /proc/xen/privcmd as > /sysfs/xen/privcmdxen_sysfs.c looks to contain a lot of code that I would expect to be part of a generic sysfs library. Does every subsystem that uses sysfs really have to implement all that stuff for itself? (I am not a sysfs expert, by the way :-). -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Mike D. Day
2006-Jan-10 12:58 UTC
Re: [Xen-devel] [PATCH] [RFC] sysfs support for xen linux
On 5:13 AM Keir Fraser wrote:> xen_sysfs.c looks to contain a lot of code that I would expect to be > part of a generic sysfs library. Does every subsystem that uses sysfs > really have to implement all that stuff for itself?No, they don''t. Drivers get sysfs attributes by using the driver core (registering a subsystem, defining attributes, etc.). However, if all you want to do is create and remove files under /sys (without using all the driver core), there is no simple way to do so (at least not that I could find). I am assuming that folks will want something that works like /proc does now. I wrote xen_sysfs.c to provide simple sysfs interfaces for non-drivers. It seems as though it would be a crime against nature to write a device driver just to create a file under /sys.> (I am not a sysfs expert, by the way :-) .Neither am I, but perhaps some such person will give feedback. :-) Mike -- Mike D. Day STSM and Architect, Open Virtualization IBM Linux Technology Center ncmike@us.ibm.com _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Gawain Lynch
2006-Jan-10 13:23 UTC
Re: [Xen-devel] [PATCH] [RFC] sysfs support for xen linux
> diff -r c08884b412da -r cec2fc0a07c6 linux-2.6-xen-sparse/arch/xen/kernel/xen_sysfs.c > --- /dev/null Mon Jan 9 21:55:13 2006 > +++ b/linux-2.6-xen-sparse/arch/xen/kernel/xen_sysfs.c Mon Jan 9 23:07:04 2006<SNIP>> +#ifndef BOOL > +#define BOOL int > +#endif > + > +#ifndef FALSE > +#define FALSE 0 > +#endif > + > +#ifndef TRUE > +#define TRUE 1 > +#endif > + > +#ifndef NULL > +#define NULL 0 > +#endifThese are already defined in kernel and a favourite nit pick on LKML.> +struct xen_sysfs_attr > +{struct xen_sysfs_attr { New line for braces are reserved for functions()> +struct xen_sysfs_object > +{struct xen_sysfs_object {> --- /dev/null Mon Jan 9 21:55:13 2006 > +++ b/linux-2.6-xen-sparse/include/asm-xen/xen_sysfs.h Mon Jan 9 23:07:04 2006<SNIP>> +#ifndef BOOL > +#define BOOL int > +#endif > + > +#ifndef FALSE > +#define FALSE 0 > +#endif > + > +#ifndef TRUE > +#define TRUE 1 > +#endif > + > +#ifndef NULL > +#define NULL 0 > +#endif >See above... _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2006-Jan-11 10:21 UTC
Re: [Xen-devel] [PATCH] [RFC] sysfs support for xen linux
On 10 Jan 2006, at 12:58, Mike D. Day wrote:> No, they don''t. Drivers get sysfs attributes by using the driver core > (registering a subsystem, defining attributes, etc.). > > However, if all you want to do is create and remove files under /sys > (without using all the driver core), there is no simple way to do so > (at least not that I could find). I am assuming that folks will want > something that works like /proc does now. > > I wrote xen_sysfs.c to provide simple sysfs interfaces for > non-drivers. It seems as though it would be a crime against nature to > write a device driver just to create a file under /sys.Well, here''s a question, and I really don''t know the answer: It of course makes sense that the kernel maintainers want drivers to install themselves under /sys, and fit in with the whole kobject and hotplug infrastructure. But, for a few odds-and-ends special files that don''t really relate to a device, is /proc also out of bounds these days? Seems to me that the kernel proc interfaces were designed to have a few random files thrown at them, in a way that the sysfs interfaces aren''t. If the argument is really that random special files are a bad idea, that would continue to hold regardless of whether we move e.g., /proc/xen/privcmd to /sys. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Mark Williamson
2006-Jan-11 16:05 UTC
Re: [Xen-devel] [PATCH] [RFC] sysfs support for xen linux
My impression is was that sysfs files are mostly meant to be very simple get/set attributes and not have magic properties like the privcmd file - do any other sysfs files even support ioctls(). Also, for things like privcmd() which are used to perform operations, isn''t it cleanest to make them a character device than a proc file? $0.02, Mark On Wednesday 11 January 2006 16:12, Mike D. Day wrote:> On 5:21 AM Keir Fraser wrote: > > Well, here''s a question, and I really don''t know the answer: It of > > course makes sense that the kernel maintainers want drivers to > > install themselves under /sys, and fit in with the whole kobject and > > hotplug infrastructure. But, for a few odds-and-ends special files > > that don''t really relate to a device, is /proc also out of bounds > > these days? Seems to me that the kernel proc interfaces were designed > > to have a few random files thrown at them, in a way that the sysfs > > interfaces aren''t. If the argument is really that random special > > files are a bad idea, that would continue to hold regardless of > > whether we move e.g., /proc/xen/privcmd to /sys. > > I think that /sys is clearly the right place to put information about > Xen, including version, domains and domain info, and perhaps info about > xenstore. This is according to feedback received when I submitted my > first (braindead) patch moving /proc/xen to /proc/sys/xen. > > Still I agree that we need input from lkml and am going to cross-post an > RFC so we can move forward. > > regards, > > Mike--> Just a question. What use is a unicyle with no seat? And no pedals!Me: To answer a question with a question: What use is a skateboard?> Skateboards have wheels.Me: My wheel has a wheel! _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Mike D. Day
2006-Jan-11 16:12 UTC
Re: [Xen-devel] [PATCH] [RFC] sysfs support for xen linux
On 5:21 AM Keir Fraser wrote:> Well, here''s a question, and I really don''t know the answer: It of > course makes sense that the kernel maintainers want drivers to > install themselves under /sys, and fit in with the whole kobject and > hotplug infrastructure. But, for a few odds-and-ends special files > that don''t really relate to a device, is /proc also out of bounds > these days? Seems to me that the kernel proc interfaces were designed > to have a few random files thrown at them, in a way that the sysfs > interfaces aren''t. If the argument is really that random special > files are a bad idea, that would continue to hold regardless of > whether we move e.g., /proc/xen/privcmd to /sys.I think that /sys is clearly the right place to put information about Xen, including version, domains and domain info, and perhaps info about xenstore. This is according to feedback received when I submitted my first (braindead) patch moving /proc/xen to /proc/sys/xen. Still I agree that we need input from lkml and am going to cross-post an RFC so we can move forward. regards, Mike -- Mike D. Day STSM and Architect, Open Virtualization IBM Linux Technology Center ncmike@us.ibm.com _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Mike D. Day
2006-Jan-11 16:28 UTC
Re: [Xen-devel] [PATCH] [RFC] sysfs support for xen linux
On 11:05 AM Mark Williamson wrote:> My impression is was that sysfs files are mostly meant to be very > simple > get/set attributes and not have magic properties like the privcmd > file - do > any other sysfs files even support ioctls().Yes, true. I think privcmd might be more appropriate for /proc, but would like to see how it works as a binary file under /sys. ioctl''s are not supported by sysfs that I can see, so privcmd would have to be a read/write interface. Regardless of privcmd there are numerous simple attributes related to Xen that are consistent with "zen" of sysfs. :-) Mike -- Mike D. Day STSM and Architect, Open Virtualization IBM Linux Technology Center ncmike@us.ibm.com _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Mark Williamson
2006-Jan-11 16:28 UTC
Re: [Xen-devel] [PATCH] [RFC] sysfs support for xen linux
> Yes, true. I think privcmd might be more appropriate for /proc, but > would like to see how it works as a binary file under /sys. ioctl''s are > not supported by sysfs that I can see, so privcmd would have to be a > read/write interface. > > Regardless of privcmd there are numerous simple attributes related to > Xen that are consistent with "zen" of sysfs. :-)Agreed. It''s an ideal place for many of the things that are in proc, and many things we''d want to add in the future. You could possibly abuse sysfs into supporting ioctl but I''m pretty sure the kernel people would find that quite distressing ;-) I had the impression binary files under sysfs were also a no-no (all meant to be cat-able - addressing one of the other problems of /proc), but I could be mistaken. Cheers, Mark --> Just a question. What use is a unicyle with no seat? And no pedals!Me: To answer a question with a question: What use is a skateboard?> Skateboards have wheels.Me: My wheel has a wheel! _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2006-Jan-11 16:35 UTC
Re: [Xen-devel] [PATCH] [RFC] sysfs support for xen linux
On 11 Jan 2006, at 16:05, Mark Williamson wrote:> My impression is was that sysfs files are mostly meant to be very > simple > get/set attributes and not have magic properties like the privcmd file > - do > any other sysfs files even support ioctls(). > > Also, for things like privcmd() which are used to perform operations, > isn''t it > cleanest to make them a character device than a proc file?Probably true, but then it''s a pain either needing to create device files in /dev, or interface with the devfs/udev du jour. I suppose we already have that issue with /dev/xen/evtchn though, and creating the device node can be hidden in libxc. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ronald G Minnich
2006-Jan-11 16:40 UTC
Re: [Xen-devel] [PATCH] [RFC] sysfs support for xen linux
Keir Fraser wrote:> > Probably true, but then it''s a pain either needing to create device > files in /dev, or interface with the devfs/udev du jour. I suppose we > already have that issue with /dev/xen/evtchn though, and creating the > device node can be hidden in libxc.we''ve observed that as well, one performance toolkit uses a /proc file to avoid the mess of "devfs/udev du jour" (what a great description ...). So maybe it oughtta be a device, who knows, but the sys file will save a lot of trouble. ron _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Anthony Liguori
2006-Jan-11 16:50 UTC
Re: [Xen-devel] [PATCH] [RFC] sysfs support for xen linux
Mark Williamson wrote:>>Yes, true. I think privcmd might be more appropriate for /proc, but >>would like to see how it works as a binary file under /sys. ioctl''s are >>not supported by sysfs that I can see, so privcmd would have to be a >>read/write interface. >> >>Regardless of privcmd there are numerous simple attributes related to >>Xen that are consistent with "zen" of sysfs. :-) >> >> > >Agreed. It''s an ideal place for many of the things that are in proc, and many >things we''d want to add in the future. > >You could possibly abuse sysfs into supporting ioctl but I''m pretty sure the >kernel people would find that quite distressing ;-) I had the impression >binary files under sysfs were also a no-no (all meant to be cat-able - >addressing one of the other problems of /proc), but I could be mistaken. > >There was a discussion a while back about this. http://permalink.gmane.org/gmane.comp.emulators.xen.devel/14273 I think the consensus was to move any ioctl interface to a char device and everything else to sysfs. You''ll probably want a proper kobject hierarchy too which means working with GKH et al to figure out where out stuff should be (/sys/hypervisor/xen??) Regards, Anthony Liguori>Cheers, >Mark > > >_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Daniel Stekloff
2006-Jan-11 17:03 UTC
Re: [Xen-devel] [PATCH] [RFC] sysfs support for xen linux
On Wed, 2006-01-11 at 10:50 -0600, Anthony Liguori wrote:> Mark Williamson wrote: > > >>Yes, true. I think privcmd might be more appropriate for /proc, but > >>would like to see how it works as a binary file under /sys. ioctl''s are > >>not supported by sysfs that I can see, so privcmd would have to be a > >>read/write interface. > >> > >>Regardless of privcmd there are numerous simple attributes related to > >>Xen that are consistent with "zen" of sysfs. :-) > >> > >> > > > >Agreed. It''s an ideal place for many of the things that are in proc, and many > >things we''d want to add in the future. > > > >You could possibly abuse sysfs into supporting ioctl but I''m pretty sure the > >kernel people would find that quite distressing ;-) I had the impression > >binary files under sysfs were also a no-no (all meant to be cat-able - > >addressing one of the other problems of /proc), but I could be mistaken. > > > > > There was a discussion a while back about this. > > http://permalink.gmane.org/gmane.comp.emulators.xen.devel/14273 > > I think the consensus was to move any ioctl interface to a char device > and everything else to sysfs. > > You''ll probably want a proper kobject hierarchy too which means working > with GKH et al to figure out where out stuff should be > (/sys/hypervisor/xen??)I think it would be a good idea if you included lkml in on your discussions. Why not get their opinions early rather than late? Thanks, Dan _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Chris Wright
2006-Jan-12 01:44 UTC
Re: [Xen-devel] [PATCH] [RFC] sysfs support for xen linux
* Mike D. Day (ncmike@us.ibm.com) wrote:> This patch is the first step toward instrumenting xen through sysfs, and > toward migrating the /proc/xen files to /sys/xen. > > The major component is a set of kernel functions that hopefully make > adding files to /sys/xen as easy as adding files to /proc/xen. A > smaller file adds xen version information by creating a file under > /sys/xen/version. > > I am looking for feedback on the approach and usefulness of the sysfs > support functions. The next step is to add support for sysfs binary > files and to experiment with implementing /proc/xen/privcmd as > /sysfs/xen/privcmdYou''re re-inventing the wheel here. The infrastructure is there so that you don''t have to create your own. I think you need to back up and consider the requirements again. E.g. exporting version should be _tiny_.> # HG changeset patch > # User mdday@mdday.raleigh.ibm.com > # Node ID cec2fc0a07c611023e096cf3496d948aa39c1342 > # Parent c08884b412da24dd4c05d36fdff408f4433bd865 > # Parent da7873110bbb8b55d9adb9111d100e209fc49ee6 > signed-off-by Mike Day <ncmike@us.ibm.com> > > Stage support for xen to export information using sysfs. Make it just as easy to add a /sys/xen/ file as it is to add a /proc/xen file currently. Starting by exporting xen version information in /sys/xen/version. > > diff -r c08884b412da -r cec2fc0a07c6 linux-2.6-xen-sparse/arch/xen/kernel/xen_sysfs.c > --- /dev/null Mon Jan 9 21:55:13 2006 > +++ b/linux-2.6-xen-sparse/arch/xen/kernel/xen_sysfs.c Mon Jan 9 23:07:04 2006 > @@ -0,0 +1,698 @@ > +/* > + copyright (c) 2006 IBM Corporation > + Mike Day <ncmike@us.ibm.com> > + > + This program is free software; you can redistribute it and/or modify > + it under the terms of the GNU General Public License as published by > + the Free Software Foundation; either version 2 of the License, or > + (at your option) any later version. > + > + This program is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + GNU General Public License for more details. > + > + You should have received a copy of the GNU General Public License > + along with this program; if not, write to the Free Software > + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > +*/ > + > + > +#include <linux/config.h> > +#include <linux/kernel.h> > +#include <linux/init.h> > +#include <linux/kobject.h> > +#include <linux/sysfs.h> > +#include <linux/module.h> > +#include <linux/string.h> > +#include <linux/types.h> > +#include <asm/atomic.h> > +#include <asm/semaphore.h> > +#include <asm-generic/bug.h> > + > +#ifdef DEBUG > +#define DPRINTK(fmt, args...) printk(KERN_DEBUG "xen_sysfs: ", fmt, ## args) > +#else > +#define DPRINTK(fmt, args...) > +#endifpr_debug> +#ifndef BOOL > +#define BOOL int > +#endif > + > +#ifndef FALSE > +#define FALSE 0 > +#endif > + > +#ifndef TRUE > +#define TRUE 1 > +#endif> +#ifndef NULL > +#define NULL 0 > +#endifunecessary, drop all this> +#define __sysfs_ref__what''s this for?> +struct xen_sysfs_object; > + > +struct xen_sysfs_attr > +{ > + struct bin_attribute attr; > + ssize_t (*show)(void *, char *) ; > + ssize_t (*store)(void *, const char *, size_t) ; > + ssize_t (*read)(void *, char *, loff_t, size_t ); > + ssize_t (*write)(void *, char *, loff_t, size_t) ; > +}; > + > + > + > +/* flags bits */ > +#define XEN_SYSFS_UNINITIALIZED 0x00 > +#define XEN_SYSFS_CHAR_TYPE 0x01 > +#define XEN_SYSFS_BIN_TYPE 0x02 > +#define XEN_SYSFS_DIR_TYPE 0x04 > +#define XEN_SYSFS_LINKED 0x08 > +#define XEN_SYSFS_UNLINKED 0x10 > +#define XEN_SYSFS_LINK_TYPE 0x11 > + > + > +struct xen_sysfs_object > +{ > + struct list_head list; > + int flags; > + struct kobject kobj; > + struct xen_sysfs_attr attr; > + char * path; > + struct list_head children; > + struct xen_sysfs_object * parent; > + atomic_t refcount;This looks like you''re creating your own tree structure. kobjects already handle this.> + void * user_data; > + void (*user_data_release)(void *); > + void (*destroy)(struct xen_sysfs_object *); > +}; > + > + > +static __sysfs_ref__ struct xen_sysfs_object * > +find_object(struct xen_sysfs_object * obj, const char * path); > + > + > +static __sysfs_ref__ struct xen_sysfs_object * > +new_sysfs_object(const char * path, > + int type, > + int mode, > + ssize_t (*show)(void *, char *), > + ssize_t (*store)(void *, const char *, size_t), > + ssize_t (*read)(void *, char *, loff_t, size_t), > + ssize_t (*write)(void *, char *, loff_t, size_t), > + void * user_data, > + void (* user_data_release)(void *)) ; > + > +static void destroy_sysfs_object(struct xen_sysfs_object * obj); > +static __sysfs_ref__ struct xen_sysfs_object * __find_parent(const char * path) ; > +static __sysfs_ref__ int __add_child(struct xen_sysfs_object *parent, > + struct xen_sysfs_object *child); > +static void remove_child(struct xen_sysfs_object *child); > +static void get_object(struct xen_sysfs_object *); > +static int put_object(struct xen_sysfs_object *, > + void (*)(struct xen_sysfs_object *)); > + > + > +/* Is A == B ? */ > +#define streq(a,b) (strcmp((a),(b)) == 0) > + > +/* Does A start with B ? */ > +#define strstarts(a,b) (strncmp((a),(b),strlen(b)) == 0)these are typically done open coded...> +#define __sysfs_ref__debugging?> +#define XEN_SYSFS_ATTR(_name, _mode, _show, _store) \ > + struct xen_sysfs_attr xen_sysfs_attr_##_name = __ATTR(_name, _mode, _show, _store) > + > +#define __XEN_KOBJ(_parent, _dentry, _ktype) \ > + { \ > + .k_name = NULL, \ > + .parent = _parent, \ > + .dentry = _dentry, \ > + .ktype = _ktype, \ > + } > + > +static struct semaphore xen_sysfs_mut = __MUTEX_INITIALIZER(xen_sysfs_mut); > +static inline int > +sysfs_down(struct semaphore * mut) > +{ > + int err; > + do { > + err = down_interruptible(mut); > + } while ( err && err == -EINTR ); > + return err; > +}What''s the point of using down_interruptible if you can''t really interrupt the call flow?> +#define sysfs_up(mut) up(mut) > +#define to_xen_attr(_attr) container_of(_attr, struct xen_sysfs_attr, attr.attr) > +#define to_xen_obj(_xen_attr) container_of(_xen_attr, struct xen_sysfs_object, attr) > + > +static ssize_t > +xen_sysfs_show(struct kobject * kobj, struct attribute * attr, char * buf) > +{ > + struct xen_sysfs_attr * xen_attr = to_xen_attr(attr); > + struct xen_sysfs_object * xen_obj = to_xen_obj(xen_attr); > + if(xen_attr->show) > + return xen_attr->show(xen_obj->user_data, buf); > + return 0; > +} > + > +static ssize_t > +xen_sysfs_store(struct kobject * kobj, struct attribute * attr, > + const char *buf, size_t count) > +{ > + struct xen_sysfs_attr * xen_attr = to_xen_attr(attr); > + struct xen_sysfs_object * xen_obj = to_xen_obj(xen_attr); > + if(xen_attr->store) > + return xen_attr->store(xen_obj->user_data, buf, count) ; > + return 0; > +} > + > +#define to_xen_obj_bin(_kobj) container_of(_kobj, struct xen_sysfs_object, kobj) > + > +static ssize_t > +xen_sysfs_read(struct kobject *kobj, char * buf, loff_t offset, size_t size) > +{ > + struct xen_sysfs_object * xen_obj = to_xen_obj_bin(kobj); > + if(xen_obj->attr.read) > + return xen_obj->attr.read(xen_obj->user_data, buf, offset, size); > + return 0; > +} > + > + > +static ssize_t > +xen_sysfs_write(struct kobject *kobj, char * buf, loff_t offset, size_t size) > +{ > + struct xen_sysfs_object * xen_obj = to_xen_obj_bin(kobj); > + if (xen_obj->attr.write) > + return xen_obj->attr.write(xen_obj->user_data, buf, offset, size); > + if(size == 0 ) > + return PAGE_SIZE; > + > + return size; > +} > + > +static struct sysfs_ops xen_sysfs_ops = { > + .show = xen_sysfs_show, > + .store = xen_sysfs_store, > +}; > + > +static struct kobj_type xen_kobj_type = { > + .release = NULL, > + .sysfs_ops = &xen_sysfs_ops, > + .default_attrs = NULL, > +}; > + > + > +/* xen sysfs root entry */ > +static struct xen_sysfs_object xen_root = { > + .flags = 0, > + .kobj = { > + .k_name = NULL, > + .parent = NULL, > + .dentry = NULL, > + .ktype = &xen_kobj_type, > + }, > + .attr = { > + .attr = { > + .attr = { > + .name = NULL, > + .mode = 0775, > + }, > + > + }, > + .show = NULL, > + .store = NULL, > + .read = NULL, > + .write = NULL, > + }, > + .path = __stringify(/sys/xen), > + .list = LIST_HEAD_INIT(xen_root.list), > + .children = LIST_HEAD_INIT(xen_root.children), > + .parent = NULL, > +}; > + > +/* xen sysfs path functions */ > + > +static BOOL > +valid_chars(const char *path) > +{ > + if( ! strstarts(path, "/sys/xen") )OK, that''s a serious problem. You should not have pathnames here at all.> + return FALSE; > + if(strstr(path, "//")) > + return FALSE; > + return (strspn(path, > + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" > + "abcdefghijklmnopqrstuvwxyz" > + "0123456789-/_@~$") == strlen(path));eek> +} > + > + > +/* return value must be kfree''d */ > +static char * > +dup_path(const char *path) > +{ > + char * ret; > + int len; > + BUG_ON( ! path ); > + > + if( FALSE == valid_chars(path) ) { > + return NULL; > + } > + > + len = strlen(path) + 1; > + ret = kcalloc(len - 1, sizeof(char), GFP_KERNEL);(despite the fact that this shouldn''t be necessary...s/kcalloc/kzalloc/) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel