2005-04-17 02:20:36 +04:00
/*
* kernel / ksysfs . c - sysfs attributes in / sys / kernel , which
* are not related to any other subsystem
*
* Copyright ( C ) 2004 Kay Sievers < kay . sievers @ vrfy . org >
*
* This file is release under the GPLv2
*
*/
# include <linux/kobject.h>
# include <linux/string.h>
# include <linux/sysfs.h>
# include <linux/module.h>
# include <linux/init.h>
2006-06-23 13:05:07 +04:00
# include <linux/kexec.h>
2007-10-15 19:00:14 +04:00
# include <linux/sched.h>
2005-04-17 02:20:36 +04:00
# define KERNEL_ATTR_RO(_name) \
static struct subsys_attribute _name # # _attr = __ATTR_RO ( _name )
# define KERNEL_ATTR_RW(_name) \
static struct subsys_attribute _name # # _attr = \
__ATTR ( _name , 0644 , _name # # _show , _name # # _store )
2006-03-24 14:18:44 +03:00
# if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
2005-11-11 06:58:04 +03:00
/* current uevent sequence number */
2007-04-14 00:15:19 +04:00
static ssize_t uevent_seqnum_show ( struct kset * kset , char * page )
2005-04-17 02:20:36 +04:00
{
2005-11-16 11:00:00 +03:00
return sprintf ( page , " %llu \n " , ( unsigned long long ) uevent_seqnum ) ;
2005-04-17 02:20:36 +04:00
}
2005-11-11 06:58:04 +03:00
KERNEL_ATTR_RO ( uevent_seqnum ) ;
/* uevent helper program, used during early boo */
2007-04-14 00:15:19 +04:00
static ssize_t uevent_helper_show ( struct kset * kset , char * page )
2005-11-11 06:58:04 +03:00
{
2005-11-16 11:00:00 +03:00
return sprintf ( page , " %s \n " , uevent_helper ) ;
2005-11-11 06:58:04 +03:00
}
2007-04-14 00:15:19 +04:00
static ssize_t uevent_helper_store ( struct kset * kset , const char * page , size_t count )
2005-11-11 06:58:04 +03:00
{
2005-11-16 11:00:00 +03:00
if ( count + 1 > UEVENT_HELPER_PATH_LEN )
2005-11-11 06:58:04 +03:00
return - ENOENT ;
2005-11-16 11:00:00 +03:00
memcpy ( uevent_helper , page , count ) ;
uevent_helper [ count ] = ' \0 ' ;
if ( count & & uevent_helper [ count - 1 ] = = ' \n ' )
uevent_helper [ count - 1 ] = ' \0 ' ;
2005-11-11 06:58:04 +03:00
return count ;
}
KERNEL_ATTR_RW ( uevent_helper ) ;
2005-04-17 02:20:36 +04:00
# endif
2006-06-23 13:05:07 +04:00
# ifdef CONFIG_KEXEC
2007-04-14 00:15:19 +04:00
static ssize_t kexec_loaded_show ( struct kset * kset , char * page )
2006-06-23 13:05:07 +04:00
{
return sprintf ( page , " %d \n " , ! ! kexec_image ) ;
}
KERNEL_ATTR_RO ( kexec_loaded ) ;
2007-04-14 00:15:19 +04:00
static ssize_t kexec_crash_loaded_show ( struct kset * kset , char * page )
2006-06-23 13:05:07 +04:00
{
return sprintf ( page , " %d \n " , ! ! kexec_crash_image ) ;
}
KERNEL_ATTR_RO ( kexec_crash_loaded ) ;
2007-10-17 10:27:27 +04:00
static ssize_t vmcoreinfo_show ( struct kset * kset , char * page )
{
return sprintf ( page , " %lx %x \n " ,
paddr_vmcoreinfo_note ( ) ,
2007-10-17 10:27:28 +04:00
( unsigned int ) vmcoreinfo_max_size ) ;
2007-10-17 10:27:27 +04:00
}
KERNEL_ATTR_RO ( vmcoreinfo ) ;
2006-06-23 13:05:07 +04:00
# endif /* CONFIG_KEXEC */
2007-07-19 12:48:39 +04:00
/*
* Make / sys / kernel / notes give the raw contents of our kernel . notes section .
*/
2007-07-20 20:02:04 +04:00
extern const void __start_notes __attribute__ ( ( weak ) ) ;
extern const void __stop_notes __attribute__ ( ( weak ) ) ;
2007-07-19 12:48:39 +04:00
# define notes_size (&__stop_notes - &__start_notes)
static ssize_t notes_read ( struct kobject * kobj , struct bin_attribute * bin_attr ,
char * buf , loff_t off , size_t count )
{
memcpy ( buf , & __start_notes + off , count ) ;
return count ;
}
static struct bin_attribute notes_attr = {
. attr = {
. name = " notes " ,
. mode = S_IRUGO ,
} ,
. read = & notes_read ,
} ;
2007-10-29 22:13:17 +03:00
struct kset * kernel_kset ;
EXPORT_SYMBOL_GPL ( kernel_kset ) ;
2005-04-17 02:20:36 +04:00
static struct attribute * kernel_attrs [ ] = {
2006-03-24 14:18:44 +03:00
# if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
2005-11-11 06:58:04 +03:00
& uevent_seqnum_attr . attr ,
& uevent_helper_attr . attr ,
2006-06-23 13:05:07 +04:00
# endif
# ifdef CONFIG_KEXEC
& kexec_loaded_attr . attr ,
& kexec_crash_loaded_attr . attr ,
2007-10-17 10:27:27 +04:00
& vmcoreinfo_attr . attr ,
2005-04-17 02:20:36 +04:00
# endif
NULL
} ;
static struct attribute_group kernel_attr_group = {
. attrs = kernel_attrs ,
} ;
static int __init ksysfs_init ( void )
{
2007-10-29 22:13:17 +03:00
int error ;
2005-04-17 02:20:36 +04:00
2007-10-29 22:13:17 +03:00
kernel_kset = kset_create_and_add ( " kernel " , NULL , NULL ) ;
if ( ! kernel_kset ) {
error = - ENOMEM ;
goto exit ;
}
error = sysfs_create_group ( & kernel_kset - > kobj , & kernel_attr_group ) ;
if ( error )
goto kset_exit ;
if ( notes_size > 0 ) {
2007-07-19 12:48:39 +04:00
notes_attr . size = notes_size ;
2007-10-29 22:13:17 +03:00
error = sysfs_create_bin_file ( & kernel_kset - > kobj , & notes_attr ) ;
if ( error )
goto group_exit ;
2007-07-19 12:48:39 +04:00
}
2007-10-15 19:00:14 +04:00
/*
* Create " /sys/kernel/uids " directory and corresponding root user ' s
* directory under it .
*/
2007-10-29 22:13:17 +03:00
error = uids_kobject_init ( ) ;
if ( error )
goto notes_exit ;
return 0 ;
notes_exit :
if ( notes_size > 0 )
sysfs_remove_bin_file ( & kernel_kset - > kobj , & notes_attr ) ;
group_exit :
sysfs_remove_group ( & kernel_kset - > kobj , & kernel_attr_group ) ;
kset_exit :
kset_unregister ( kernel_kset ) ;
exit :
2005-04-17 02:20:36 +04:00
return error ;
}
core_initcall ( ksysfs_init ) ;