Linux Container Development
 help / color / mirror / Atom feed
From: Pavel Emelyanov <xemul-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
To: Serge Hallyn <serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>,
	"Eric W. Biederman"
	<ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>,
	Daniel Lezcano <dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>,
	Cedric Le Goater <clg-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
Cc: Linux Containers <containers-qjLDD68F18O7TbgM5vRIOg@public.gmane.org>
Subject: [PATCH 3/3] Switch IPC namespace to use sysctl shadows
Date: Tue, 20 Nov 2007 14:47:41 +0300	[thread overview]
Message-ID: <4742C95D.1040907@openvz.org> (raw)
In-Reply-To: <4742C73C.3010904-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>

The same as with UTS - use the shadows. With this
there's no longer need in having kludged ->proc_handler
and ->strategy for ctl_tables.

Signed-off-by: Pavel Emelyanov <xemul-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>

---

diff --git a/include/linux/ipc.h b/include/linux/ipc.h
index 408696e..a9fef83 100644
--- a/include/linux/ipc.h
+++ b/include/linux/ipc.h
@@ -118,6 +118,8 @@ struct ipc_namespace {
 	size_t		shm_ctlall;
 	int		shm_ctlmni;
 	int		shm_tot;
+
+	struct ctl_table_header *ctl_head;
 };
 
 extern struct ipc_namespace init_ipc_ns;
diff --git a/ipc/ipc_sysctl.c b/ipc/ipc_sysctl.c
index 79e24e8..5affdfe 100644
--- a/ipc/ipc_sysctl.c
+++ b/ipc/ipc_sysctl.c
@@ -15,84 +15,6 @@
 #include <linux/sysctl.h>
 #include <linux/uaccess.h>
 
-static void *get_ipc(ctl_table *table)
-{
-	char *which = table->data;
-	struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
-	which = (which - (char *)&init_ipc_ns) + (char *)ipc_ns;
-	return which;
-}
-
-#ifdef CONFIG_PROC_FS
-static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp,
-	void __user *buffer, size_t *lenp, loff_t *ppos)
-{
-	struct ctl_table ipc_table;
-	memcpy(&ipc_table, table, sizeof(ipc_table));
-	ipc_table.data = get_ipc(table);
-
-	return proc_dointvec(&ipc_table, write, filp, buffer, lenp, ppos);
-}
-
-static int proc_ipc_doulongvec_minmax(ctl_table *table, int write,
-	struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos)
-{
-	struct ctl_table ipc_table;
-	memcpy(&ipc_table, table, sizeof(ipc_table));
-	ipc_table.data = get_ipc(table);
-
-	return proc_doulongvec_minmax(&ipc_table, write, filp, buffer,
-					lenp, ppos);
-}
-
-#else
-#define proc_ipc_doulongvec_minmax NULL
-#define proc_ipc_dointvec	   NULL
-#endif
-
-#ifdef CONFIG_SYSCTL_SYSCALL
-/* The generic sysctl ipc data routine. */
-static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen,
-		void __user *oldval, size_t __user *oldlenp,
-		void __user *newval, size_t newlen)
-{
-	size_t len;
-	void *data;
-
-	/* Get out of I don't have a variable */
-	if (!table->data || !table->maxlen)
-		return -ENOTDIR;
-
-	data = get_ipc(table);
-	if (!data)
-		return -ENOTDIR;
-
-	if (oldval && oldlenp) {
-		if (get_user(len, oldlenp))
-			return -EFAULT;
-		if (len) {
-			if (len > table->maxlen)
-				len = table->maxlen;
-			if (copy_to_user(oldval, data, len))
-				return -EFAULT;
-			if (put_user(len, oldlenp))
-				return -EFAULT;
-		}
-	}
-
-	if (newval && newlen) {
-		if (newlen > table->maxlen)
-			newlen = table->maxlen;
-
-		if (copy_from_user(data, newval, newlen))
-			return -EFAULT;
-	}
-	return 1;
-}
-#else
-#define sysctl_ipc_data NULL
-#endif
-
 static struct ctl_table ipc_kern_table[] = {
 	{
 		.ctl_name	= KERN_SHMMAX,
@@ -100,8 +22,8 @@ static struct ctl_table ipc_kern_table[] = {
 		.data		= &init_ipc_ns.shm_ctlmax,
 		.maxlen		= sizeof (init_ipc_ns.shm_ctlmax),
 		.mode		= 0644,
-		.proc_handler	= proc_ipc_doulongvec_minmax,
-		.strategy	= sysctl_ipc_data,
+		.proc_handler	= proc_doulongvec_minmax,
+		.strategy	= sysctl_data,
 	},
 	{
 		.ctl_name	= KERN_SHMALL,
@@ -109,8 +31,8 @@ static struct ctl_table ipc_kern_table[] = {
 		.data		= &init_ipc_ns.shm_ctlall,
 		.maxlen		= sizeof (init_ipc_ns.shm_ctlall),
 		.mode		= 0644,
-		.proc_handler	= proc_ipc_doulongvec_minmax,
-		.strategy	= sysctl_ipc_data,
+		.proc_handler	= proc_doulongvec_minmax,
+		.strategy	= sysctl_data,
 	},
 	{
 		.ctl_name	= KERN_SHMMNI,
@@ -118,8 +40,8 @@ static struct ctl_table ipc_kern_table[] = {
 		.data		= &init_ipc_ns.shm_ctlmni,
 		.maxlen		= sizeof (init_ipc_ns.shm_ctlmni),
 		.mode		= 0644,
-		.proc_handler	= proc_ipc_dointvec,
-		.strategy	= sysctl_ipc_data,
+		.proc_handler	= proc_dointvec,
+		.strategy	= sysctl_data,
 	},
 	{
 		.ctl_name	= KERN_MSGMAX,
@@ -127,8 +49,8 @@ static struct ctl_table ipc_kern_table[] = {
 		.data		= &init_ipc_ns.msg_ctlmax,
 		.maxlen		= sizeof (init_ipc_ns.msg_ctlmax),
 		.mode		= 0644,
-		.proc_handler	= proc_ipc_dointvec,
-		.strategy	= sysctl_ipc_data,
+		.proc_handler	= proc_dointvec,
+		.strategy	= sysctl_data,
 	},
 	{
 		.ctl_name	= KERN_MSGMNI,
@@ -136,8 +58,8 @@ static struct ctl_table ipc_kern_table[] = {
 		.data		= &init_ipc_ns.msg_ctlmni,
 		.maxlen		= sizeof (init_ipc_ns.msg_ctlmni),
 		.mode		= 0644,
-		.proc_handler	= proc_ipc_dointvec,
-		.strategy	= sysctl_ipc_data,
+		.proc_handler	= proc_dointvec,
+		.strategy	= sysctl_data,
 	},
 	{
 		.ctl_name	= KERN_MSGMNB,
@@ -145,8 +67,8 @@ static struct ctl_table ipc_kern_table[] = {
 		.data		= &init_ipc_ns.msg_ctlmnb,
 		.maxlen		= sizeof (init_ipc_ns.msg_ctlmnb),
 		.mode		= 0644,
-		.proc_handler	= proc_ipc_dointvec,
-		.strategy	= sysctl_ipc_data,
+		.proc_handler	= proc_dointvec,
+		.strategy	= sysctl_data,
 	},
 	{
 		.ctl_name	= KERN_SEM,
@@ -154,8 +76,8 @@ static struct ctl_table ipc_kern_table[] = {
 		.data		= &init_ipc_ns.sem_ctls,
 		.maxlen		= 4*sizeof (int),
 		.mode		= 0644,
-		.proc_handler	= proc_ipc_dointvec,
-		.strategy	= sysctl_ipc_data,
+		.proc_handler	= proc_dointvec,
+		.strategy	= sysctl_data,
 	},
 	{}
 };
@@ -170,9 +92,43 @@ static struct ctl_table ipc_root_table[] = {
 	{}
 };
 
+int ipc_clone_sysctl(struct ipc_namespace *ns)
+{
+	struct ctl_table_header *h;
+	struct ctl_table *t;
+
+	h = create_sysctl_shadow(init_ipc_ns.ctl_head);
+	if (h == NULL)
+		return -ENOMEM;
+
+	t = h->ctl_table->child;
+
+	t[0].data = &ns->shm_ctlmax;
+	t[1].data = &ns->shm_ctlall;
+	t[2].data = &ns->shm_ctlmni;
+	t[3].data = &ns->msg_ctlmax;
+	t[4].data = &ns->msg_ctlmni;
+	t[5].data = &ns->msg_ctlmnb;
+	t[6].data = &ns->sem_ctls;
+
+	ns->ctl_head = h;
+	return 0;
+}
+
+void ipc_free_sysctl(struct ipc_namespace *ns)
+{
+	free_sysctl_shadow(ns->ctl_head);
+}
+
+static struct ctl_table_header *ipc_sysctl_shadow(struct ctl_table_header *h)
+{
+	return current->nsproxy->ipc_ns->ctl_head;
+}
+
 static int __init ipc_sysctl_init(void)
 {
-	register_sysctl_table(ipc_root_table);
+	init_ipc_ns.ctl_head = register_sysctl_table_shadow(ipc_root_table,
+			ipc_sysctl_shadow);
 	return 0;
 }
 
diff --git a/ipc/util.c b/ipc/util.c
index 76c1f34..a8cb99d 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -61,6 +61,9 @@ static struct ipc_namespace *clone_ipc_ns(struct ipc_namespace *old_ns)
 	if (ns == NULL)
 		goto err_mem;
 
+	if (ipc_clone_sysctl(ns))
+		goto err_ctl;
+
 	err = sem_init_ns(ns);
 	if (err)
 		goto err_sem;
@@ -79,6 +82,8 @@ err_shm:
 err_msg:
 	sem_exit_ns(ns);
 err_sem:
+	ipc_free_sysctl(ns);
+err_ctl:
 	kfree(ns);
 err_mem:
 	return ERR_PTR(err);
@@ -108,6 +113,7 @@ void free_ipc_ns(struct kref *kref)
 	sem_exit_ns(ns);
 	msg_exit_ns(ns);
 	shm_exit_ns(ns);
+	ipc_free_sysctl(ns);
 	kfree(ns);
 }
 
diff --git a/ipc/util.h b/ipc/util.h
index 9ffea40..dfd53c6 100644
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -28,6 +28,9 @@ void sem_exit_ns(struct ipc_namespace *ns);
 void msg_exit_ns(struct ipc_namespace *ns);
 void shm_exit_ns(struct ipc_namespace *ns);
 
+int ipc_clone_sysctl(struct ipc_namespace *ns);
+void ipc_free_sysctl(struct ipc_namespace *ns);
+
 struct ipc_ids {
 	int in_use;
 	unsigned short seq;

  parent reply	other threads:[~2007-11-20 11:47 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-11-20 11:38 [PATCH 0/3] Sysctl shadow management Pavel Emelyanov
     [not found] ` <4742C73C.3010904-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2007-11-20 11:43   ` [PATCH 1/3] The sysctl shadows Pavel Emelyanov
     [not found]     ` <4742C86E.6060705-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2007-11-20 17:16       ` Dave Hansen
2007-11-21  9:20         ` Pavel Emelyanov
2007-11-20 11:45   ` [PATCH 2/3] Switch UTS namespace to use shadows Pavel Emelyanov
2007-11-20 11:47   ` Pavel Emelyanov [this message]
     [not found]     ` <4742C95D.1040907-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2007-11-20 17:24       ` [PATCH 3/3] Switch IPC namespace to use sysctl shadows Dave Hansen
2007-11-21  9:21         ` Pavel Emelyanov
2007-11-20 13:05   ` [PATCH 0/3] Sysctl shadow management Eric W. Biederman
     [not found]     ` <m1y7ctrrrd.fsf-T1Yj925okcoyDheHMi7gv2pdwda3JcWeAL8bYrjMMd8@public.gmane.org>
2007-11-20 13:21       ` Pavel Emelyanov
     [not found]         ` <4742DF51.8060402-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2007-11-20 15:21           ` Eric W. Biederman
     [not found]             ` <m1tznhrli5.fsf-T1Yj925okcoyDheHMi7gv2pdwda3JcWeAL8bYrjMMd8@public.gmane.org>
2007-11-20 15:36               ` Pavel Emelyanov
     [not found]                 ` <4742FEF6.6080609-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2007-11-20 19:47                   ` Eric W. Biederman
     [not found]                     ` <m1myt8snqp.fsf-T1Yj925okcoyDheHMi7gv2pdwda3JcWeAL8bYrjMMd8@public.gmane.org>
2007-11-21  9:52                       ` Pavel Emelyanov
2007-11-29 17:40 ` [PATCH 0/4] Sysctl namespace support Eric W. Biederman
     [not found]   ` <m1odddc5mf.fsf-T1Yj925okcoyDheHMi7gv2pdwda3JcWeAL8bYrjMMd8@public.gmane.org>
2007-11-29 17:45     ` [PATCH 1/4] sysctl: Add register_sysctl_paths function Eric W. Biederman
2007-11-29 17:46       ` [PATCH 2/4] sysctl: Remember the ctl_table we passed to register_sysctl_paths Eric W. Biederman
2007-11-29 17:51         ` [PATCH 3/4] sysctl: Infrastructure for per namespace sysctls Eric W. Biederman
2007-11-29 17:53           ` [PATCH 4/4] net: Implement the per network namespace sysctl infrastructure Eric W. Biederman
2007-11-30 16:18             ` Serge E. Hallyn
2007-11-30 16:23               ` Pavel Emelyanov
2007-11-30 21:49               ` Eric W. Biederman
2007-12-01  0:01                 ` Serge E. Hallyn
2007-11-30 12:56   ` [PATCH 0/4] Sysctl namespace support Herbert Xu
     [not found]     ` <20071130125627.GH26848-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q@public.gmane.org>
2007-11-30 13:25       ` Eric W. Biederman

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=4742C95D.1040907@openvz.org \
    --to=xemul-gefaqzzx7r8dnm+yrofe0a@public.gmane.org \
    --cc=clg-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org \
    --cc=containers-qjLDD68F18O7TbgM5vRIOg@public.gmane.org \
    --cc=dlezcano-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org \
    --cc=ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org \
    --cc=serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org \
    /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