public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Dave Hansen <haveblue@us.ibm.com>
To: linux-kernel@vger.kernel.org
Cc: serue@us.ibm.com, frankeh@watson.ibm.com, clg@fr.ibm.com,
	Herbert Poetzl <herbert@13thfloor.at>,
	Sam Vilain <sam@vilain.net>, Dave Hansen <haveblue@us.ibm.com>
Subject: [RFC][PATCH 1/6] prepare sysctls for containers
Date: Mon, 06 Mar 2006 15:52:49 -0800	[thread overview]
Message-ID: <20060306235249.880CB28A@localhost.localdomain> (raw)
In-Reply-To: <20060306235248.20842700@localhost.localdomain>


Right now, sysctls can only deal with global variables.  This
patch makes them a _little_ more flexible by allowing there to
be an accessor function to get at the variable being changed,
instead of it being global.

This allows the sysctls to be backed by variables that are,
for instance, dynamically allocated and not available at
compile-time.

This also provides a very simple mechanism to take things that
are currently global and containerize them.

Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
---

 work-dave/include/linux/sysctl.h |    8 ++++
 work-dave/kernel/sysctl.c        |   65 ++++++++++++++++++++++++++-------------
 2 files changed, 52 insertions(+), 21 deletions(-)

diff -puN include/linux/sysctl.h~sysctls-for-containers include/linux/sysctl.h
--- work/include/linux/sysctl.h~sysctls-for-containers	2006-03-06 15:41:55.000000000 -0800
+++ work-dave/include/linux/sysctl.h	2006-03-06 15:41:55.000000000 -0800
@@ -872,6 +872,7 @@ extern void sysctl_init(void);
 
 typedef struct ctl_table ctl_table;
 
+typedef void *ctl_data_access (void);
 typedef int ctl_handler (ctl_table *table, int __user *name, int nlen,
 			 void __user *oldval, size_t __user *oldlenp,
 			 void __user *newval, size_t newlen, 
@@ -957,6 +958,13 @@ struct ctl_table 
 	int ctl_name;			/* Binary ID */
 	const char *procname;		/* Text ID for /proc/sys, or zero */
 	void *data;
+	ctl_data_access *data_access;	/* set this to a function if you
+					 * don't have a static place to point
+					 * ->data at compile-time.  This
+					 * function will be called to dynamically
+					 * figure out a ->data pointer.  Do not
+					 * set this and ->data at once.
+					 */
 	int maxlen;
 	mode_t mode;
 	ctl_table *child;
diff -puN kernel/sysctl.c~sysctls-for-containers kernel/sysctl.c
--- work/kernel/sysctl.c~sysctls-for-containers	2006-03-06 15:41:55.000000000 -0800
+++ work-dave/kernel/sysctl.c	2006-03-06 15:41:55.000000000 -0800
@@ -1197,6 +1197,24 @@ repeat:
 	return -ENOTDIR;
 }
 
+void *sysctl_table_data(ctl_table *table)
+{
+	void *data;
+
+	if (table->data && table->data_access) {
+		printk(KERN_WARNING
+			"sysctl: data and accessor function set for: '%s'\n",
+			table->procname);
+		table->data = NULL;
+	}
+
+	data = table->data;
+	if (!data && table->data_access)
+		data = table->data_access();
+
+	return data;
+}
+
 /* Perform the actual read/write of a sysctl table entry. */
 int do_sysctl_strategy (ctl_table *table, 
 			int __user *name, int nlen,
@@ -1205,6 +1223,7 @@ int do_sysctl_strategy (ctl_table *table
 {
 	int op = 0, rc;
 	size_t len;
+	void *data;
 
 	if (oldval)
 		op |= 004;
@@ -1224,14 +1243,15 @@ int do_sysctl_strategy (ctl_table *table
 
 	/* If there is no strategy routine, or if the strategy returns
 	 * zero, proceed with automatic r/w */
-	if (table->data && table->maxlen) {
+	data = sysctl_table_data(table);
+	if (data && table->maxlen) {
 		if (oldval && oldlenp) {
 			if (get_user(len, oldlenp))
 				return -EFAULT;
 			if (len) {
 				if (len > table->maxlen)
 					len = table->maxlen;
-				if(copy_to_user(oldval, table->data, len))
+				if(copy_to_user(oldval, data, len))
 					return -EFAULT;
 				if(put_user(len, oldlenp))
 					return -EFAULT;
@@ -1241,7 +1261,7 @@ int do_sysctl_strategy (ctl_table *table
 			len = newlen;
 			if (len > table->maxlen)
 				len = table->maxlen;
-			if(copy_from_user(table->data, newval, len))
+			if(copy_from_user(data, newval, len))
 				return -EFAULT;
 		}
 	}
@@ -1539,7 +1559,7 @@ int proc_dostring(ctl_table *table, int 
 	char __user *p;
 	char c;
 	
-	if (!table->data || !table->maxlen || !*lenp ||
+	if (!sysctl_table_data(table) || !table->maxlen || !*lenp ||
 	    (*ppos && !write)) {
 		*lenp = 0;
 		return 0;
@@ -1557,18 +1577,18 @@ int proc_dostring(ctl_table *table, int 
 		}
 		if (len >= table->maxlen)
 			len = table->maxlen-1;
-		if(copy_from_user(table->data, buffer, len))
+		if(copy_from_user(sysctl_table_data(table), buffer, len))
 			return -EFAULT;
-		((char *) table->data)[len] = 0;
+		((char *) sysctl_table_data(table))[len] = 0;
 		*ppos += *lenp;
 	} else {
-		len = strlen(table->data);
+		len = strlen(sysctl_table_data(table));
 		if (len > table->maxlen)
 			len = table->maxlen;
 		if (len > *lenp)
 			len = *lenp;
 		if (len)
-			if(copy_to_user(buffer, table->data, len))
+			if(copy_to_user(buffer, sysctl_table_data(table), len))
 				return -EFAULT;
 		if (len < *lenp) {
 			if(put_user('\n', ((char __user *) buffer) + len))
@@ -1636,13 +1656,13 @@ static int do_proc_dointvec(ctl_table *t
 	char buf[TMPBUFLEN], *p;
 	char __user *s = buffer;
 	
-	if (!table->data || !table->maxlen || !*lenp ||
+	if (!sysctl_table_data(table) || !table->maxlen || !*lenp ||
 	    (*ppos && !write)) {
 		*lenp = 0;
 		return 0;
 	}
 	
-	i = (int *) table->data;
+	i = (int *) sysctl_table_data(table);
 	vleft = table->maxlen / sizeof(*i);
 	left = *lenp;
 
@@ -1878,13 +1898,13 @@ static int do_proc_doulongvec_minmax(ctl
 	char buf[TMPBUFLEN], *p;
 	char __user *s = buffer;
 	
-	if (!table->data || !table->maxlen || !*lenp ||
+	if (!sysctl_table_data(table) || !table->maxlen || !*lenp ||
 	    (*ppos && !write)) {
 		*lenp = 0;
 		return 0;
 	}
 	
-	i = (unsigned long *) table->data;
+	i = (unsigned long *) sysctl_table_data(table);
 	min = (unsigned long *) table->extra1;
 	max = (unsigned long *) table->extra2;
 	vleft = table->maxlen / sizeof(unsigned long);
@@ -2230,7 +2250,9 @@ int sysctl_string(ctl_table *table, int 
 		  void __user *oldval, size_t __user *oldlenp,
 		  void __user *newval, size_t newlen, void **context)
 {
-	if (!table->data || !table->maxlen) 
+	char *data = sysctl_table_data(table);
+
+	if (!data || !table->maxlen)
 		return -ENOTDIR;
 	
 	if (oldval && oldlenp) {
@@ -2238,7 +2260,7 @@ int sysctl_string(ctl_table *table, int 
 		if (get_user(bufsize, oldlenp))
 			return -EFAULT;
 		if (bufsize) {
-			size_t len = strlen(table->data), copied;
+			size_t len = strlen(data), copied;
 
 			/* This shouldn't trigger for a well-formed sysctl */
 			if (len > table->maxlen)
@@ -2247,7 +2269,7 @@ int sysctl_string(ctl_table *table, int 
 			/* Copy up to a max of bufsize-1 bytes of the string */
 			copied = (len >= bufsize) ? bufsize - 1 : len;
 
-			if (copy_to_user(oldval, table->data, copied) ||
+			if (copy_to_user(oldval, data, copied) ||
 			    put_user(0, (char __user *)(oldval + copied)))
 				return -EFAULT;
 			if (put_user(len, oldlenp))
@@ -2258,11 +2280,11 @@ int sysctl_string(ctl_table *table, int 
 		size_t len = newlen;
 		if (len > table->maxlen)
 			len = table->maxlen;
-		if(copy_from_user(table->data, newval, len))
+		if(copy_from_user(data, newval, len))
 			return -EFAULT;
 		if (len == table->maxlen)
 			len--;
-		((char *) table->data)[len] = 0;
+		data[len] = 0;
 	}
 	return 1;
 }
@@ -2320,7 +2342,7 @@ int sysctl_jiffies(ctl_table *table, int
 			if (olen!=sizeof(int))
 				return -EINVAL; 
 		}
-		if (put_user(*(int *)(table->data)/HZ, (int __user *)oldval) ||
+		if (put_user(*(int *)(sysctl_table_data(table))/HZ, (int __user *)oldval) ||
 		    (oldlenp && put_user(sizeof(int),oldlenp)))
 			return -EFAULT;
 	}
@@ -2330,7 +2352,7 @@ int sysctl_jiffies(ctl_table *table, int
 			return -EINVAL; 
 		if (get_user(new, (int __user *)newval))
 			return -EFAULT;
-		*(int *)(table->data) = new*HZ; 
+		*(int *)(sysctl_table_data(table)) = new*HZ;
 	}
 	return 1;
 }
@@ -2340,6 +2362,7 @@ int sysctl_ms_jiffies(ctl_table *table, 
 		void __user *oldval, size_t __user *oldlenp,
 		void __user *newval, size_t newlen, void **context)
 {
+	int *jiffies_ptr = sysctl_table_data(table);
 	if (oldval) {
 		size_t olen;
 		if (oldlenp) { 
@@ -2348,7 +2371,7 @@ int sysctl_ms_jiffies(ctl_table *table, 
 			if (olen!=sizeof(int))
 				return -EINVAL; 
 		}
-		if (put_user(jiffies_to_msecs(*(int *)(table->data)), (int __user *)oldval) ||
+		if (put_user(jiffies_to_msecs(*jiffies_ptr), (int __user *)oldval) ||
 		    (oldlenp && put_user(sizeof(int),oldlenp)))
 			return -EFAULT;
 	}
@@ -2358,7 +2381,7 @@ int sysctl_ms_jiffies(ctl_table *table, 
 			return -EINVAL; 
 		if (get_user(new, (int __user *)newval))
 			return -EFAULT;
-		*(int *)(table->data) = msecs_to_jiffies(new);
+		*jiffies_ptr = msecs_to_jiffies(new);
 	}
 	return 1;
 }
_

  reply	other threads:[~2006-03-06 23:52 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-03-06 23:52 [RFC][PATCH 0/6] support separate namespaces for sysv Dave Hansen
2006-03-06 23:52 ` Dave Hansen [this message]
2006-03-07  0:50   ` [RFC][PATCH 1/6] prepare sysctls for containers Herbert Poetzl
2006-03-07  2:00     ` Dave Hansen
2006-03-07  2:45       ` Herbert Poetzl
2006-03-19 15:54         ` Eric W. Biederman
2006-03-07  1:01   ` Chris Wright
2006-03-07  2:04     ` Dave Hansen
2006-03-07  2:18       ` Chris Wright
2006-03-07  3:02       ` Sam Vilain
2006-03-07  1:24   ` Al Viro
2006-03-07  1:55     ` Dave Hansen
2006-03-07  1:57       ` Al Viro
2006-03-19 14:50         ` Eric W. Biederman
2006-03-19 15:29   ` Eric W. Biederman
2006-03-06 23:52 ` [RFC][PATCH 2/6] sysvmsg: containerize Dave Hansen
2006-03-07  1:57   ` Chris Wright
2006-03-07  2:08     ` Dave Hansen
2006-03-07  2:34       ` Chris Wright
2006-03-19 15:36         ` Eric W. Biederman
2006-03-20 19:34           ` Chris Wright
2006-03-20 21:29             ` Eric W. Biederman
2006-03-20 21:50               ` Chris Wright
2006-03-06 23:52 ` [RFC][PATCH 3/6] sysvmsg: containerize sysctls Dave Hansen
2006-03-06 23:52 ` [RFC][PATCH 4/6] sysvsem: containerize Dave Hansen
2006-03-07  2:44   ` Chris Wright
2006-03-07  5:08     ` Dave Hansen
2006-03-06 23:52 ` [RFC][PATCH 5/6] sysvshm: containerize Dave Hansen
2006-03-06 23:52 ` [RFC][PATCH 6/6] sysvshm: containerize sysctls Dave Hansen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20060306235249.880CB28A@localhost.localdomain \
    --to=haveblue@us.ibm.com \
    --cc=clg@fr.ibm.com \
    --cc=frankeh@watson.ibm.com \
    --cc=herbert@13thfloor.at \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sam@vilain.net \
    --cc=serue@us.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox