[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] [RFC] sysfs support for xen linux
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@xxxxxxxxxx # HG changeset patch # User mdday@xxxxxxxxxxxxxxxxxxxxx # Node ID cec2fc0a07c611023e096cf3496d948aa39c1342 # Parent c08884b412da24dd4c05d36fdff408f4433bd865 # Parent da7873110bbb8b55d9adb9111d100e209fc49ee6 signed-off-by Mike Day <ncmike@xxxxxxxxxx> 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@xxxxxxxxxx> + + 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@xxxxxxxxxx> + + 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@xxxxxxxxxx> + + 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@xxxxxxxxxxxxxxxxxxxxx # 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@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |