All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] [RFC] sysfs support for xen linux
@ 2006-01-09 23:35 Mike D. Day
  2006-01-10  1:09 ` Christopher G. Stach II
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: Mike D. Day @ 2006-01-09 23:35 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: Type: text/plain, Size: 683 bytes --]


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

[-- Attachment #2: xen_sysfs.diff --]
[-- Type: text/plain, Size: 23096 bytes --]

# 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

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

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

^ permalink raw reply	[flat|nested] 15+ messages in thread
* Re: [PATCH] [RFC] sysfs support for xen linux
@ 2006-01-10 12:58 Mike D. Day
  2006-01-11 10:21 ` Keir Fraser
  0 siblings, 1 reply; 15+ messages in thread
From: Mike D. Day @ 2006-01-10 12:58 UTC (permalink / raw)
  To: Keir Fraser; +Cc: xen-devel

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

^ permalink raw reply	[flat|nested] 15+ messages in thread
* Re: [PATCH] [RFC] sysfs support for xen linux
@ 2006-01-11 16:12 Mike D. Day
  2006-01-11 16:05 ` Mark Williamson
  0 siblings, 1 reply; 15+ messages in thread
From: Mike D. Day @ 2006-01-11 16:12 UTC (permalink / raw)
  To: Keir Fraser; +Cc: xen-devel

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

^ permalink raw reply	[flat|nested] 15+ messages in thread
* Re: [PATCH] [RFC] sysfs support for xen linux
@ 2006-01-11 16:28 Mike D. Day
  2006-01-11 16:28 ` Mark Williamson
  0 siblings, 1 reply; 15+ messages in thread
From: Mike D. Day @ 2006-01-11 16:28 UTC (permalink / raw)
  To: Mark Williamson; +Cc: xen-devel

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

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2006-01-12  1:44 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-01-09 23:35 [PATCH] [RFC] sysfs support for xen linux Mike D. Day
2006-01-10  1:09 ` Christopher G. Stach II
2006-01-10 10:13 ` Keir Fraser
2006-01-10 13:23 ` Gawain Lynch
2006-01-12  1:44 ` Chris Wright
  -- strict thread matches above, loose matches on Subject: below --
2006-01-10 12:58 Mike D. Day
2006-01-11 10:21 ` Keir Fraser
2006-01-11 16:12 Mike D. Day
2006-01-11 16:05 ` Mark Williamson
2006-01-11 16:35   ` Keir Fraser
2006-01-11 16:40     ` Ronald G Minnich
2006-01-11 16:28 Mike D. Day
2006-01-11 16:28 ` Mark Williamson
2006-01-11 16:50   ` Anthony Liguori
2006-01-11 17:03     ` Daniel Stekloff

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.