vserver 2.0 rc7
[linux-2.6.git] / kernel / sysctl.c
index 2810362..d34b4e6 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/limits.h>
 #include <linux/dcache.h>
 #include <linux/syscalls.h>
+#include <linux/vserver/cvirt.h>
 
 #include <asm/uaccess.h>
 #include <asm/processor.h>
@@ -122,6 +123,8 @@ extern int sysctl_hz_timer;
 extern int acct_parm[];
 #endif
 
+int randomize_va_space = 1;
+
 static int parse_table(int __user *, int, void __user *, size_t __user *, void __user *, size_t,
                       ctl_table *, void **);
 static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
@@ -227,6 +230,7 @@ static ctl_table kern_table[] = {
                .maxlen         = sizeof(system_utsname.sysname),
                .mode           = 0444,
                .proc_handler   = &proc_doutsstring,
+               .virt_handler   = &vx_uts_virt_handler,
                .strategy       = &sysctl_string,
        },
        {
@@ -236,6 +240,7 @@ static ctl_table kern_table[] = {
                .maxlen         = sizeof(system_utsname.release),
                .mode           = 0444,
                .proc_handler   = &proc_doutsstring,
+               .virt_handler   = &vx_uts_virt_handler,
                .strategy       = &sysctl_string,
        },
        {
@@ -245,6 +250,7 @@ static ctl_table kern_table[] = {
                .maxlen         = sizeof(system_utsname.version),
                .mode           = 0444,
                .proc_handler   = &proc_doutsstring,
+               .virt_handler   = &vx_uts_virt_handler,
                .strategy       = &sysctl_string,
        },
        {
@@ -254,6 +260,7 @@ static ctl_table kern_table[] = {
                .maxlen         = sizeof(system_utsname.nodename),
                .mode           = 0644,
                .proc_handler   = &proc_doutsstring,
+               .virt_handler   = &vx_uts_virt_handler,
                .strategy       = &sysctl_string,
        },
        {
@@ -263,6 +270,7 @@ static ctl_table kern_table[] = {
                .maxlen         = sizeof(system_utsname.domainname),
                .mode           = 0644,
                .proc_handler   = &proc_doutsstring,
+               .virt_handler   = &vx_uts_virt_handler,
                .strategy       = &sysctl_string,
        },
        {
@@ -642,6 +650,15 @@ static ctl_table kern_table[] = {
                .proc_handler   = &proc_dointvec,
        },
 #endif
+       {
+               .ctl_name       = KERN_RANDOMIZE,
+               .procname       = "randomize_va_space",
+               .data           = &randomize_va_space,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec,
+       },
+
        { .ctl_name = 0 }
 };
 
@@ -1376,6 +1393,7 @@ static ssize_t proc_writesys(struct file * file, const char __user * buf,
  * @filp: the file structure
  * @buffer: the user buffer
  * @lenp: the size of the user buffer
+ * @ppos: file position
  *
  * Reads/writes a string from/to the user buffer. If the kernel
  * buffer provided is not large enough to hold the string, the
@@ -1389,16 +1407,20 @@ static ssize_t proc_writesys(struct file * file, const char __user * buf,
 int proc_dostring(ctl_table *table, int write, struct file *filp,
                  void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-       size_t len;
+       size_t len, maxlen;
        char __user *p;
        char c;
+       void *data;
+
+       data = table->data;
+       maxlen = table->maxlen;
+
+       if (!data || !maxlen || !*lenp || (*ppos && !write))
+               return (*lenp = 0);
        
-       if (!table->data || !table->maxlen || !*lenp ||
-           (*ppos && !write)) {
-               *lenp = 0;
-               return 0;
-       }
-       
+       if (table->virt_handler)
+               table->virt_handler(table, write, filp->f_xid, &data, &maxlen);
+
        if (write) {
                len = 0;
                p = buffer;
@@ -1409,20 +1431,20 @@ int proc_dostring(ctl_table *table, int write, struct file *filp,
                                break;
                        len++;
                }
-               if (len >= table->maxlen)
-                       len = table->maxlen-1;
-               if(copy_from_user(table->data, buffer, len))
+               if (len >= maxlen)
+                       len = maxlen-1;
+               if(copy_from_user(data, buffer, len))
                        return -EFAULT;
-               ((char *) table->data)[len] = 0;
+               ((char *) data)[len] = 0;
                *ppos += *lenp;
        } else {
-               len = strlen(table->data);
-               if (len > table->maxlen)
-                       len = table->maxlen;
+               len = strlen(data);
+               if (len > maxlen)
+                       len = maxlen;
                if (len > *lenp)
                        len = *lenp;
                if (len)
-                       if(copy_to_user(buffer, table->data, len))
+                       if(copy_to_user(buffer, data, len))
                                return -EFAULT;
                if (len < *lenp) {
                        if(put_user('\n', ((char __user *) buffer) + len))
@@ -1592,6 +1614,7 @@ static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
  * @filp: the file structure
  * @buffer: the user buffer
  * @lenp: the size of the user buffer
+ * @ppos: file position
  *
  * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
  * values from/to the user buffer, treated as an ASCII string. 
@@ -1696,6 +1719,7 @@ static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp,
  * @filp: the file structure
  * @buffer: the user buffer
  * @lenp: the size of the user buffer
+ * @ppos: file position
  *
  * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
  * values from/to the user buffer, treated as an ASCII string.
@@ -1828,6 +1852,7 @@ static int do_proc_doulongvec_minmax(ctl_table *table, int write,
  * @filp: the file structure
  * @buffer: the user buffer
  * @lenp: the size of the user buffer
+ * @ppos: file position
  *
  * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
  * values from/to the user buffer, treated as an ASCII string.
@@ -1850,6 +1875,7 @@ int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
  * @filp: the file structure
  * @buffer: the user buffer
  * @lenp: the size of the user buffer
+ * @ppos: file position
  *
  * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
  * values from/to the user buffer, treated as an ASCII string. The values
@@ -1940,6 +1966,7 @@ static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp,
  * @filp: the file structure
  * @buffer: the user buffer
  * @lenp: the size of the user buffer
+ * @ppos: file position
  *
  * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
  * values from/to the user buffer, treated as an ASCII string. 
@@ -1984,6 +2011,8 @@ int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp,
  * @filp: the file structure
  * @buffer: the user buffer
  * @lenp: the size of the user buffer
+ * @ppos: file position
+ * @ppos: the current position in the file
  *
  * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
  * values from/to the user buffer, treated as an ASCII string.