The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: "Serge E. Hallyn" <serge@hallyn.com>
To: Chen Hanxiao <chenhanxiao@cn.fujitsu.com>
Cc: containers@lists.linux-foundation.org,
	linux-kernel@vger.kernel.org,
	Richard Weinberger <richard.weinberger@gmail.com>,
	Serge Hallyn <serge.hallyn@ubuntu.com>,
	Oleg Nesterov <oleg@redhat.com>,
	David Howells <dhowells@redhat.com>,
	"Eric W. Biederman" <ebiederm@xmission.com>,
	Al Viro <viro@zeniv.linux.org.uk>
Subject: Re: [RFC PATCH 2/3] procfs: show hierarchy of pid namespace
Date: Wed, 10 Sep 2014 18:23:15 +0200	[thread overview]
Message-ID: <20140910162315.GB7748@mail.hallyn.com> (raw)
In-Reply-To: <1409740200-26461-3-git-send-email-chenhanxiao@cn.fujitsu.com>

Quoting Chen Hanxiao (chenhanxiao@cn.fujitsu.com):
> This patch will show the hierarchy of pid namespace
> under /proc/pidns like:
> /proc/pidns
> ├── hierarchy
> │   ├── pidns4026532399
> │   │   ├── pidns -> /proc/2863/ns/pid
> │   │   └── pidns4026532515
> │   │       └── pidns -> /proc/10611/ns/pid
> │   └── pidns4026532504
> │       └── pidns -> /proc/4450/ns/pid
> └── refresh
> 
> a) hierarchy dir:
>   use to show hierarchy infomation using dir and symlinks.
>   dirs are named as pidns($inum)
>   a symlink is created under pidns($inum), and linked to
>   that pid namespace.
> 
> b) refresh
>   trigger key.
>   We need to write sth to /proc/nspid/refresh,
>   then we could get hierarchy info
>   under /proc/pidns/hierarchy.

Ouch.  There may not be a better way, but it sure would be nice if
we could simply have the list update in real-time.

If we have to 'echo 1 > /proc/pidns/refresh' to update the fs tree under
/proc/pidns/ to reflect new pidns activity, then why not just make this
a text file?  I suppose if it were a textfile you'd be encouraging ppl
to 'cat pidlist | while read line; do grep line /proc/pidns; done',
which would cause a refresh of that file for every grep?

My concern with this approach is that it is unlike any other pseudo-fs
that I know of, and people may simply expect the fs contents to be
uptodate rather than a snapshot.

> Signed-off-by: Chen Hanxiao <chenhanxiao@cn.fujitsu.com>
> ---
>  fs/proc/Kconfig           |   6 ++
>  fs/proc/Makefile          |   1 +
>  fs/proc/pidns_hierarchy.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 168 insertions(+)
>  create mode 100644 fs/proc/pidns_hierarchy.c
> 
> diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig
> index 2183fcf..e2e2292 100644
> --- a/fs/proc/Kconfig
> +++ b/fs/proc/Kconfig
> @@ -71,3 +71,9 @@ config PROC_PAGE_MONITOR
>  	  /proc/pid/smaps, /proc/pid/clear_refs, /proc/pid/pagemap,
>  	  /proc/kpagecount, and /proc/kpageflags. Disabling these
>            interfaces will reduce the size of the kernel by approximately 4kb.
> +
> +config PROC_PID_HIERARCHY
> +	bool "Enable /proc/pidns_hierarchy support" if EXPERT
> +	depends on PROC_FS
> +	help
> +	  Show pid namespace hierarchy infomation
> diff --git a/fs/proc/Makefile b/fs/proc/Makefile
> index 239493e..733599b 100644
> --- a/fs/proc/Makefile
> +++ b/fs/proc/Makefile
> @@ -29,3 +29,4 @@ proc-$(CONFIG_PROC_KCORE)	+= kcore.o
>  proc-$(CONFIG_PROC_VMCORE)	+= vmcore.o
>  proc-$(CONFIG_PRINTK)	+= kmsg.o
>  proc-$(CONFIG_PROC_PAGE_MONITOR)	+= page.o
> +proc-$(CONFIG_PROC_PID_HIERARCHY)	+= pidns_hierarchy.o
> diff --git a/fs/proc/pidns_hierarchy.c b/fs/proc/pidns_hierarchy.c
> new file mode 100644
> index 0000000..d35340f
> --- /dev/null
> +++ b/fs/proc/pidns_hierarchy.c
> @@ -0,0 +1,161 @@
> +/*
> + * proc_pidns_hierarchy.c -- handles pidns hierarchy
> + *
> + * Copyright 2014
> + */
> +
> +#include <linux/init.h>
> +#include <linux/errno.h>
> +#include <linux/proc_fs.h>
> +#include <linux/module.h>
> +#include <linux/list.h>
> +#include <linux/slab.h>
> +#include <linux/pid_namespace.h>
> +
> +/*
> + * The /proc/pidns directory
> + */
> +
> +#define BASE_DIR	"pidns"			/* Subdir in /proc */
> +#define HIERARCHY_DIR	"pidns/hierarchy"	/* hierarchy dir */
> +#define REFRESH_KEY	"pidns/refresh"		/* refresh key */
> +#define NAME		"pidns_hierarchy"	/* Module name */
> +
> +static LIST_HEAD(pidns_list);
> +static DEFINE_RWLOCK(pidns_lock);
> +static struct proc_dir_entry *proc_root;
> +
> +struct ns_pid_list {
> +	struct pid *pid;
> +	struct list_head list;
> +};
> +
> +static void free_pidns_list(struct list_head *head)
> +{
> +	struct ns_pid_list *tmp, *pos;
> +
> +	list_for_each_entry_safe(pos, tmp, head, list) {
> +		list_del(&pos->list);
> +		kfree(pos);
> +	}
> +}
> +
> +/*
> + * Only add pids with different ns
> + */
> +static int
> +ns_pid_list_really_add(struct pid *pid)
> +{
> +	struct ns_pid_list *tmp, *pos;
> +
> +	list_for_each_entry_safe(pos, tmp, &pidns_list, list)
> +		if (ns_of_pid(pid) == ns_of_pid(pos->pid))
> +			return 0;
> +
> +	return 1;
> +}
> +
> +static int
> +ns_pid_list_add(struct pid *pid)
> +{
> +	struct ns_pid_list *ent;
> +
> +	ent = kmalloc(sizeof(*ent), GFP_KERNEL);
> +	if (!ent)
> +		return -ENOMEM;
> +	ent->pid = pid;
> +	if (ns_pid_list_really_add(pid))
> +		list_add_tail(&ent->list, &pidns_list);
> +
> +	return 0;
> +}
> +
> +static void print_list(void)
> +{
> +	struct ns_pid_list *tmp, *pos;
> +	struct proc_dir_entry *parent, *parent_new;
> +	struct pid_namespace *ns, *curr_ns;
> +	struct pid *pid;
> +	char name_buf[16], pid_buf[32];
> +	int i, k;
> +
> +	curr_ns = task_active_pid_ns(current);
> +
> +	list_for_each_entry_safe(pos, tmp, &pidns_list, list) {
> +		pid = pos->pid;
> +		k = -1;
> +		ns = pid->numbers[pid->level].ns;
> +		/* Check whether pid has relationship with current ns */
> +		for (; ns != NULL; ns = ns->parent)
> +			if (ns == curr_ns)
> +				k = curr_ns->level;
> +		if (k == -1)
> +			continue;
> +		parent = proc_root;
> +		for (i = k + 1; i <= pid->level; i++) {
> +			ns = pid->numbers[i].ns;
> +			snprintf(name_buf, 16, "pidns%u",
> +				pid->numbers[i].ns->proc_inum);
> +			snprintf(pid_buf, 32, "/proc/%u/ns/pid",
> +				pid->numbers[0].nr);
> +			/* don't duplicate ns dirs */
> +			parent_new = proc_uniq_dir(parent, name_buf);
> +			if (!parent_new) {
> +				parent_new = proc_mkdir(name_buf, parent);
> +				proc_symlink("pidns", parent_new, pid_buf);
> +			}
> +		parent = parent_new;
> +		}
> +	}
> +}
> +
> +void proc_pidns_list(void)
> +{
> +	struct pid *pid;
> +	struct task_struct *task = &init_task;
> +
> +	remove_proc_subtree(HIERARCHY_DIR, NULL);
> +	proc_root = proc_mkdir(HIERARCHY_DIR, NULL);
> +	free_pidns_list(&pidns_list);
> +
> +	do {
> +		pid = task_pid(task);
> +		if (pid) {
> +			if (pid->level > 0)
> +				ns_pid_list_add(pid);
> +		}
> +	} while ((task = next_task(task)) != &init_task);
> +
> +	print_list();
> +	printk(KERN_INFO "refresh finished\n");
> +}
> +
> +ssize_t proc_pidns_refresh_switch(struct file *file, const char __user *buf,
> +		size_t size, loff_t *ppos)
> +{
> +	write_lock(&pidns_lock);
> +	proc_pidns_list();
> +	write_unlock(&pidns_lock);
> +	return 1;
> +}
> +
> +static const struct file_operations proc_pidns_refresh_fops = {
> +	.write = proc_pidns_refresh_switch,
> +};
> +
> +static int __init pidns_hierarchy_init(void)
> +{
> +
> +	if (!proc_mkdir(BASE_DIR, NULL))
> +		return -ENOMEM;
> +	proc_root = proc_mkdir(HIERARCHY_DIR, NULL);
> +	if (!proc_root)
> +		return -ENOMEM;
> +
> +	proc_create(REFRESH_KEY, S_IWUGO,
> +		NULL, &proc_pidns_refresh_fops);
> +	printk(KERN_INFO "%s: loaded successfully\n", NAME);
> +
> +	return 0;
> +}
> +fs_initcall(pidns_hierarchy_init);
> -- 
> 1.9.0
> 
> _______________________________________________
> Containers mailing list
> Containers@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/containers

  parent reply	other threads:[~2014-09-10 16:23 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-03 10:29 [RFC PATCH 0/3] ns,procfs: pid conversion between ns and showing pidns hierarchy Chen Hanxiao
2014-09-03 10:29 ` [RFC PATCH 1/3] procfs: check uniq proc_dir_entry subdir name Chen Hanxiao
2014-09-09 23:17   ` Serge E. Hallyn
2014-09-03 10:29 ` [RFC PATCH 2/3] procfs: show hierarchy of pid namespace Chen Hanxiao
2014-09-03 12:46   ` Vasiliy Kulikov
2014-09-04 10:13     ` Chen, Hanxiao
2014-09-10 16:23   ` Serge E. Hallyn [this message]
2014-09-11  9:48     ` Chen, Hanxiao
2014-09-03 10:30 ` [PATCH 3/3] /proc/pid/status: show all sets of pid according to ns Chen Hanxiao
2014-09-04 14:44 ` [RFC PATCH 0/3] ns, procfs: pid conversion between ns and showing pidns hierarchy Serge E. Hallyn
2014-09-05  5:21 ` Chen, Hanxiao
2014-09-12 22:18 ` Serge E. Hallyn
2014-09-16  9:06   ` Chen, Hanxiao

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=20140910162315.GB7748@mail.hallyn.com \
    --to=serge@hallyn.com \
    --cc=chenhanxiao@cn.fujitsu.com \
    --cc=containers@lists.linux-foundation.org \
    --cc=dhowells@redhat.com \
    --cc=ebiederm@xmission.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=oleg@redhat.com \
    --cc=richard.weinberger@gmail.com \
    --cc=serge.hallyn@ubuntu.com \
    --cc=viro@zeniv.linux.org.uk \
    /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