2007-02-14 11:33:58 +03:00
/*
* Copyright ( C ) 2007
*
* Author : Eric Biederman < ebiederm @ xmision . 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 , version 2 of the
* License .
*/
2011-05-23 22:51:41 +04:00
# include <linux/export.h>
2007-02-14 11:33:58 +03:00
# include <linux/uts.h>
# include <linux/utsname.h>
# include <linux/sysctl.h>
2011-11-03 00:39:22 +04:00
# include <linux/wait.h>
2007-02-14 11:33:58 +03:00
2013-02-28 05:05:22 +04:00
# ifdef CONFIG_PROC_SYSCTL
2007-02-14 11:33:58 +03:00
static void * get_uts ( ctl_table * table , int write )
{
char * which = table - > data ;
2007-11-29 03:21:38 +03:00
struct uts_namespace * uts_ns ;
uts_ns = current - > nsproxy - > uts_ns ;
which = ( which - ( char * ) & init_uts_ns ) + ( char * ) uts_ns ;
2007-07-16 10:40:58 +04:00
2007-02-14 11:33:58 +03:00
if ( ! write )
down_read ( & uts_sem ) ;
else
down_write ( & uts_sem ) ;
return which ;
}
static void put_uts ( ctl_table * table , int write , void * which )
{
if ( ! write )
up_read ( & uts_sem ) ;
else
up_write ( & uts_sem ) ;
}
/*
* Special case of dostring for the UTS structure . This has locks
* to observe . Should this be in kernel / sys . c ? ? ? ?
*/
2009-09-24 02:57:19 +04:00
static int proc_do_uts_string ( ctl_table * table , int write ,
2007-02-14 11:33:58 +03:00
void __user * buffer , size_t * lenp , loff_t * ppos )
{
struct ctl_table uts_table ;
int r ;
memcpy ( & uts_table , table , sizeof ( uts_table ) ) ;
uts_table . data = get_uts ( table , write ) ;
2009-09-24 02:57:19 +04:00
r = proc_dostring ( & uts_table , write , buffer , lenp , ppos ) ;
2007-02-14 11:33:58 +03:00
put_uts ( table , write , uts_table . data ) ;
2011-11-03 00:39:22 +04:00
if ( write )
proc_sys_poll_notify ( table - > poll ) ;
2007-02-14 11:33:58 +03:00
return r ;
}
# else
# define proc_do_uts_string NULL
# endif
2011-11-03 00:39:22 +04:00
static DEFINE_CTL_TABLE_POLL ( hostname_poll ) ;
static DEFINE_CTL_TABLE_POLL ( domainname_poll ) ;
2007-02-14 11:33:58 +03:00
static struct ctl_table uts_kern_table [ ] = {
{
. procname = " ostype " ,
. data = init_uts_ns . name . sysname ,
. maxlen = sizeof ( init_uts_ns . name . sysname ) ,
. mode = 0444 ,
. proc_handler = proc_do_uts_string ,
} ,
{
. procname = " osrelease " ,
. data = init_uts_ns . name . release ,
. maxlen = sizeof ( init_uts_ns . name . release ) ,
. mode = 0444 ,
. proc_handler = proc_do_uts_string ,
} ,
{
. procname = " version " ,
. data = init_uts_ns . name . version ,
. maxlen = sizeof ( init_uts_ns . name . version ) ,
. mode = 0444 ,
. proc_handler = proc_do_uts_string ,
} ,
{
. procname = " hostname " ,
. data = init_uts_ns . name . nodename ,
. maxlen = sizeof ( init_uts_ns . name . nodename ) ,
. mode = 0644 ,
. proc_handler = proc_do_uts_string ,
2011-11-03 00:39:22 +04:00
. poll = & hostname_poll ,
2007-02-14 11:33:58 +03:00
} ,
{
. procname = " domainname " ,
. data = init_uts_ns . name . domainname ,
. maxlen = sizeof ( init_uts_ns . name . domainname ) ,
. mode = 0644 ,
. proc_handler = proc_do_uts_string ,
2011-11-03 00:39:22 +04:00
. poll = & domainname_poll ,
2007-02-14 11:33:58 +03:00
} ,
{ }
} ;
static struct ctl_table uts_root_table [ ] = {
{
. procname = " kernel " ,
. mode = 0555 ,
. child = uts_kern_table ,
} ,
{ }
} ;
2011-11-03 00:39:22 +04:00
# ifdef CONFIG_PROC_SYSCTL
/*
* Notify userspace about a change in a certain entry of uts_kern_table ,
* identified by the parameter proc .
*/
void uts_proc_notify ( enum uts_proc proc )
{
struct ctl_table * table = & uts_kern_table [ proc ] ;
proc_sys_poll_notify ( table - > poll ) ;
}
# endif
2007-02-14 11:33:58 +03:00
static int __init utsname_sysctl_init ( void )
{
2007-02-14 11:34:09 +03:00
register_sysctl_table ( uts_root_table ) ;
2007-02-14 11:33:58 +03:00
return 0 ;
}
__initcall ( utsname_sysctl_init ) ;