Linux Container Development
 help / color / mirror / Atom feed
* [PATCH 2/3] Pid ns helpers for signals
@ 2007-08-31 20:36 sukadev-r/Jw6+rmf7HQT0dZR+AlfA
       [not found] ` <20070831203634.GB3268-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: sukadev-r/Jw6+rmf7HQT0dZR+AlfA @ 2007-08-31 20:36 UTC (permalink / raw)
  To: Oleg Nesterov, Pavel Emelianov; +Cc: Containers

Define some helper functions that will be used to implement signal semantics
with multiple pid namespaces. 

	is_current_in_ancestor_pid_ns(task)

		TRUE iff active pid namespace of 'current' is an ancestor of
		active pid namespace of @task.

	is_current_in_same_or_ancestor_pid_ns(task)

		TRUE iff active pid namespace of 'current' is either same as 
		or an ancestor of active pid namespace of @task.

	pid_ns_equal(tsk)
		TRUE if active pid ns of @tsk is same as active pid ns of
		'current'.

These interfaces take into account the fact that the tasks they are operating
on may be exiting and may have already exited their namespaces (i.e their
pid namespaces may be NULL).

Changelog: [Oleg Nesterov]: Renamed helpers and grab a reference to 'struct
	   pid' and 'struct pid_namespace'.
---
 include/linux/pid.h           |   15 ++++++
 include/linux/pid_namespace.h |    4 -
 kernel/pid.c                  |   93 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 110 insertions(+), 2 deletions(-)

Index: 2.6.23-rc3-mm1/include/linux/pid.h
===================================================================
--- 2.6.23-rc3-mm1.orig/include/linux/pid.h	2007-08-31 00:45:18.000000000 -0700
+++ 2.6.23-rc3-mm1/include/linux/pid.h	2007-08-31 12:38:08.000000000 -0700
@@ -125,6 +125,21 @@ extern void FASTCALL(free_pid(struct pid
 extern void zap_pid_ns_processes(struct pid_namespace *pid_ns);
 
 /*
+ * Caller must hold a reference to @pid.
+ */
+static inline struct pid_namespace *pid_active_ns(struct pid *pid)
+{
+	if (!pid)
+		return NULL;
+
+	return pid->numbers[pid->level].ns;
+}
+
+extern int pid_ns_equal(struct task_struct *tsk);
+extern int is_current_in_ancestor_pid_ns(struct task_struct *tsk);
+extern int is_current_in_same_or_ancestor_pid_ns(struct task_struct *tsk);
+
+/*
  * the helpers to get the pid's id seen from different namespaces
  *
  * pid_nr()    : global id, i.e. the id seen from the init namespace;
Index: 2.6.23-rc3-mm1/kernel/pid.c
===================================================================
--- 2.6.23-rc3-mm1.orig/kernel/pid.c	2007-08-31 00:45:18.000000000 -0700
+++ 2.6.23-rc3-mm1/kernel/pid.c	2007-08-31 12:29:10.000000000 -0700
@@ -199,6 +199,99 @@ static int next_pidmap(struct pid_namesp
 	return -1;
 }
 
+static struct pid_namespace *get_task_pid_ns(struct task_struct *tsk)
+{
+	struct pid *pid;
+	struct pid_namespace *ns;
+
+	pid = get_task_pid(tsk, PIDTYPE_PID);
+	ns = get_pid_ns(pid_active_ns(pid));
+	put_pid(pid);
+
+	return ns;
+}
+
+/*
+ * Return TRUE if the active pid namespace of @tsk is same as active
+ * pid namespace of 'current'.
+ */
+int pid_ns_equal(struct task_struct *tsk)
+{
+	int rc;
+	struct pid_namespace *my_ns = get_task_pid_ns(current);
+	struct pid_namespace *tsk_ns = get_task_pid_ns(tsk);
+
+	rc = (my_ns == tsk_ns);
+
+	put_pid_ns(my_ns);
+	put_pid_ns(tsk_ns);
+
+	return rc;
+}
+
+/*
+ * Return TRUE if pid namespace @ns1 is an ancestor of pid namespace @ns2.
+ * Return FALSE otherwise.
+ *
+ * Note: Callers must ensure @ns1 and @ns2 are stable.
+ */
+static int ancestor_pid_ns(struct pid_namespace *ns1, struct pid_namespace *ns2)
+{
+	int i;
+	struct pid_namespace *tmp;
+
+	if (ns1 == NULL || ns2 == NULL)
+		return 0;
+
+	if (ns1->level >= ns2->level)
+		return 0;
+
+	tmp = ns2->parent;
+	for (i = tmp->level; i >= ns1->level; i--) {
+		if (tmp == ns1)
+			return 1;
+		tmp = tmp->parent;
+	}
+
+	return 0;
+}
+
+/*
+ * Return TRUE if active pid namespace of 'current' is an ancestor of
+ * pid namespace of @tsk. Return FALSE otherwise.
+ */
+int is_current_in_ancestor_pid_ns(struct task_struct *tsk)
+{
+	int rc;
+	struct pid_namespace *my_ns = get_task_pid_ns(current);
+	struct pid_namespace *tsk_ns = get_task_pid_ns(tsk);
+
+	rc = ancestor_pid_ns(my_ns, tsk_ns);
+
+	put_pid_ns(my_ns);
+	put_pid_ns(tsk_ns);
+
+	return rc;
+}
+
+/*
+ * Return TRUE if active pid namespace of 'current' is either same as
+ * or an ancestor of active pid namespace of @tsk.
+ */
+int is_current_in_same_or_ancestor_pid_ns(struct task_struct *tsk)
+{
+	int rc;
+	struct pid_namespace *my_ns = get_task_pid_ns(current);
+	struct pid_namespace *tsk_ns = get_task_pid_ns(tsk);
+
+	rc = my_ns == tsk_ns || ancestor_pid_ns(my_ns, tsk_ns);
+
+	put_pid_ns(my_ns);
+	put_pid_ns(tsk_ns);
+
+	return rc;
+}
+
 fastcall void put_pid(struct pid *pid)
 {
 	struct pid_namespace *ns;
Index: 2.6.23-rc3-mm1/include/linux/pid_namespace.h
===================================================================
--- 2.6.23-rc3-mm1.orig/include/linux/pid_namespace.h	2007-08-31 00:45:18.000000000 -0700
+++ 2.6.23-rc3-mm1/include/linux/pid_namespace.h	2007-08-31 12:15:09.000000000 -0700
@@ -31,7 +31,7 @@ extern struct pid_namespace init_pid_ns;
 
 static inline struct pid_namespace *get_pid_ns(struct pid_namespace *ns)
 {
-	if (ns != &init_pid_ns)
+	if (ns && ns != &init_pid_ns)
 		kref_get(&ns->kref);
 	return ns;
 }
@@ -41,7 +41,7 @@ extern void free_pid_ns(struct kref *kre
 
 static inline void put_pid_ns(struct pid_namespace *ns)
 {
-	if (ns != &init_pid_ns)
+	if (ns && ns != &init_pid_ns)
 		kref_put(&ns->kref, free_pid_ns);
 }

^ permalink raw reply	[flat|nested] 8+ messages in thread
* [PATCH 2/3] Pid ns helpers for signals
@ 2007-09-11  4:11 sukadev-r/Jw6+rmf7HQT0dZR+AlfA
  0 siblings, 0 replies; 8+ messages in thread
From: sukadev-r/Jw6+rmf7HQT0dZR+AlfA @ 2007-09-11  4:11 UTC (permalink / raw)
  To: Oleg Nesterov, Pavel Emelianov; +Cc: Containers



Define some helper functions that will be used to implement signal semantics
with multiple pid namespaces. 

	is_current_in_ancestor_pid_ns(task)

		TRUE iff active pid namespace of 'current' is an ancestor of
		active pid namespace of @task.

	is_current_in_same_or_ancestor_pid_ns(task)

		TRUE iff active pid namespace of 'current' is either same as 
		or an ancestor of active pid namespace of @task.

	pid_ns_equal(tsk)
		TRUE if active pid ns of @tsk is same as active pid ns of
		'current'.

Changelog: [Oleg Nesterov]: Renamed helpers. Dropped reference to pid and
			    pid-namespace since they are stable for current
			    callers.

---
 include/linux/pid.h |   12 +++++++++
 kernel/pid.c        |   63 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+)

Index: 2.6.23-rc4-mm1/include/linux/pid.h
===================================================================
--- 2.6.23-rc4-mm1.orig/include/linux/pid.h	2007-09-07 19:18:34.000000000 -0700
+++ 2.6.23-rc4-mm1/include/linux/pid.h	2007-09-07 19:18:42.000000000 -0700
@@ -124,6 +124,18 @@ extern struct pid *alloc_pid(struct pid_
 extern void FASTCALL(free_pid(struct pid *pid));
 extern void zap_pid_ns_processes(struct pid_namespace *pid_ns);
 
+static inline struct pid_namespace *pid_active_ns(struct pid *pid)
+{
+	if (!pid)
+		return NULL;
+
+	return pid->numbers[pid->level].ns;
+}
+
+extern int pid_ns_equal(struct task_struct *tsk);
+extern int is_current_in_ancestor_pid_ns(struct task_struct *tsk);
+extern int is_current_in_same_or_ancestor_pid_ns(struct task_struct *tsk);
+
 /*
  * the helpers to get the pid's id seen from different namespaces
  *
Index: 2.6.23-rc4-mm1/kernel/pid.c
===================================================================
--- 2.6.23-rc4-mm1.orig/kernel/pid.c	2007-09-07 19:18:34.000000000 -0700
+++ 2.6.23-rc4-mm1/kernel/pid.c	2007-09-10 18:35:51.000000000 -0700
@@ -199,6 +199,69 @@ static int next_pidmap(struct pid_namesp
 	return -1;
 }
 
+/*
+ * Return TRUE if the active pid namespace of @tsk is same as active
+ * pid namespace of 'current'.
+ */
+int pid_ns_equal(struct task_struct *tsk)
+{
+	struct pid_namespace *my_ns = pid_active_ns(task_pid(current));
+	struct pid_namespace *tsk_ns = pid_active_ns(task_pid(tsk));
+
+	return my_ns == tsk_ns;
+}
+
+/*
+ * Return TRUE if pid namespace @ns1 is an ancestor of pid namespace @ns2.
+ * Return FALSE otherwise.
+ *
+ * Note: Callers must ensure @ns1 and @ns2 are stable.
+ */
+static int ancestor_pid_ns(struct pid_namespace *ns1, struct pid_namespace *ns2)
+{
+	int i;
+	struct pid_namespace *tmp;
+
+	if (ns1 == NULL || ns2 == NULL)
+		return 0;
+
+	if (ns1->level >= ns2->level)
+		return 0;
+
+	tmp = ns2->parent;
+	for (i = tmp->level; i >= ns1->level; i--) {
+		if (tmp == ns1)
+			return 1;
+		tmp = tmp->parent;
+	}
+
+	return 0;
+}
+
+/*
+ * Return TRUE if active pid namespace of 'current' is an ancestor of
+ * pid namespace of @tsk. Return FALSE otherwise.
+ */
+int is_current_in_ancestor_pid_ns(struct task_struct *tsk)
+{
+	struct pid_namespace *my_ns = pid_active_ns(task_pid(current));
+	struct pid_namespace *tsk_ns = pid_active_ns(task_pid(tsk));
+
+	return ancestor_pid_ns(my_ns, tsk_ns);
+}
+
+/*
+ * Return TRUE if active pid namespace of 'current' is either same as
+ * or an ancestor of active pid namespace of @tsk.
+ */
+int is_current_in_same_or_ancestor_pid_ns(struct task_struct *tsk)
+{
+	struct pid_namespace *my_ns = pid_active_ns(task_pid(current));
+	struct pid_namespace *tsk_ns = pid_active_ns(task_pid(tsk));
+
+	return my_ns == tsk_ns || ancestor_pid_ns(my_ns, tsk_ns);
+}
+
 fastcall void put_pid(struct pid *pid)
 {
 	struct pid_namespace *ns;

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2007-09-11  4:11 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-31 20:36 [PATCH 2/3] Pid ns helpers for signals sukadev-r/Jw6+rmf7HQT0dZR+AlfA
     [not found] ` <20070831203634.GB3268-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2007-09-01 11:29   ` Oleg Nesterov
     [not found]     ` <20070901112903.GD191-6lXkIZvqkOAvJsYlp49lxw@public.gmane.org>
2007-09-01 11:56       ` Oleg Nesterov
     [not found]         ` <20070901115601.GA258-6lXkIZvqkOAvJsYlp49lxw@public.gmane.org>
2007-09-03 16:01           ` sukadev-r/Jw6+rmf7HQT0dZR+AlfA
     [not found]             ` <20070903160147.GB2793-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2007-09-03 16:24               ` Oleg Nesterov
2007-09-03 16:55       ` sukadev-r/Jw6+rmf7HQT0dZR+AlfA
     [not found]         ` <20070903165514.GC2793-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2007-09-03 17:14           ` Oleg Nesterov
  -- strict thread matches above, loose matches on Subject: below --
2007-09-11  4:11 sukadev-r/Jw6+rmf7HQT0dZR+AlfA

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox