All of lore.kernel.org
 help / color / mirror / Atom feed
From: Li Zefan <lizf@cn.fujitsu.com>
To: Ben Blum <bblum@google.com>
Cc: linux-kernel@vger.kernel.org,
	containers@lists.linux-foundation.org, akpm@linux-foundation.org,
	serue@us.ibm.com, menage@google.com
Subject: Re: [PATCH 6/6] Makes procs file writable to move all threads by tgid at	once
Date: Mon, 03 Aug 2009 11:00:55 +0800	[thread overview]
Message-ID: <4A7652E7.4020206@cn.fujitsu.com> (raw)
In-Reply-To: <20090731015154.27908.9639.stgit@hastromil.mtv.corp.google.com>

Ben Blum wrote:
> Makes procs file writable to move all threads by tgid at once
> 
> This patch adds functionality that enables users to move all threads in a
> threadgroup at once to a cgroup by writing the tgid to the 'cgroup.procs'
> file. This current implementation makes use of a per-threadgroup rwsem that's
> taken for reading in the fork() path to prevent newly forking threads within
> the threadgroup from "escaping" while the move is in progress.
> 
> There is a gap between releasing the fork_mutex and calling each subsystem's
> attach function, which could possibly lead to problems if the subsystem relies
> on something that could change in the meantime as caused by forking threads.
> No particular issue seems apparent, but were some subsystem to have a problem
> here, the per-threadgroup fork mutex could be held longer until after the
> attach calls are done.
> 

This seems to work.

A few comments below..

> Signed-off-by: Ben Blum <bblum@google.com>
> 
> ---
> 
>  Documentation/cgroups/cgroups.txt |   12 +
>  include/linux/cgroup.h            |   12 +
>  include/linux/init_task.h         |    9 +
>  include/linux/sched.h             |    2 
>  kernel/cgroup.c                   |  417 +++++++++++++++++++++++++++++++++----
>  kernel/fork.c                     |    6 -
>  6 files changed, 406 insertions(+), 52 deletions(-)
> 
> diff --git a/Documentation/cgroups/cgroups.txt b/Documentation/cgroups/cgroups.txt
> index 6eb1a97..d579346 100644
> --- a/Documentation/cgroups/cgroups.txt
> +++ b/Documentation/cgroups/cgroups.txt
> @@ -228,6 +228,7 @@ Each cgroup is represented by a directory in the cgroup file system
>  containing the following files describing that cgroup:
>  
>   - tasks: list of tasks (by pid) attached to that cgroup
> + - cgroup.procs: list of unique tgids in the cgroup
>   - notify_on_release flag: run the release agent on exit?
>   - release_agent: the path to use for release notifications (this file
>     exists in the top cgroup only)
> @@ -374,7 +375,7 @@ Now you want to do something with this cgroup.
>  
>  In this directory you can find several files:
>  # ls
> -notify_on_release tasks
> +cgroup.procs notify_on_release tasks
>  (plus whatever files added by the attached subsystems)
>  
>  Now attach your shell to this cgroup:
> @@ -408,6 +409,15 @@ You can attach the current shell task by echoing 0:
>  
>  # echo 0 > tasks
>  
> +The cgroup.procs file is useful for managing all tasks in a threadgroup at
> +once. It works the same way as the tasks file, but moves all tasks in the
> +threadgroup with the specified tgid.
> +
> +Writing the pid of a task that's not the threadgroup leader (i.e., a pid
> +that isn't a tgid) is treated as invalid. Writing a '0' to cgroup.procs will
> +attach the writing task and all tasks in its threadgroup, but is invalid if
> +the writing task is not the leader of the threadgroup.
> +
>  3. Kernel API
>  =============
>  
> diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
> index 8286758..105d681 100644
> --- a/include/linux/cgroup.h
> +++ b/include/linux/cgroup.h
> @@ -30,10 +30,12 @@ extern int cgroup_init(void);
>  extern void cgroup_lock(void);
>  extern bool cgroup_lock_live_group(struct cgroup *cgrp);
>  extern void cgroup_unlock(void);
> -extern void cgroup_fork(struct task_struct *p);
> +extern void cgroup_fork(struct task_struct *p, int clone_flags);
>  extern void cgroup_fork_callbacks(struct task_struct *p);
> -extern void cgroup_post_fork(struct task_struct *p);
> +extern void cgroup_post_fork(struct task_struct *p, int clone_flags);
>  extern void cgroup_exit(struct task_struct *p, int run_callbacks);
> +extern void cgroup_fork_failed(struct task_struct *p, int run_callbacks,
> +			       int clone_flags);
>  extern int cgroupstats_build(struct cgroupstats *stats,
>  				struct dentry *dentry);
>  
> @@ -551,10 +553,12 @@ unsigned short css_depth(struct cgroup_subsys_state *css);
>  
>  static inline int cgroup_init_early(void) { return 0; }
>  static inline int cgroup_init(void) { return 0; }
> -static inline void cgroup_fork(struct task_struct *p) {}
> +static inline void cgroup_fork(struct task_struct *p, int clone_flags) {}
>  static inline void cgroup_fork_callbacks(struct task_struct *p) {}
> -static inline void cgroup_post_fork(struct task_struct *p) {}
> +static inline void cgroup_post_fork(struct task_struct *p, int clone_flags) {}
>  static inline void cgroup_exit(struct task_struct *p, int callbacks) {}
> +static inline void cgroup_fork_failed(struct task_struct *p, int callbacks,
> +				      int clone_flags) {}
>  
>  static inline void cgroup_lock(void) {}
>  static inline void cgroup_unlock(void) {}
> diff --git a/include/linux/init_task.h b/include/linux/init_task.h
> index aecd24e..26d814f 100644
> --- a/include/linux/init_task.h
> +++ b/include/linux/init_task.h
> @@ -105,6 +105,14 @@ extern struct cred init_cred;
>  # define INIT_PERF_COUNTERS(tsk)
>  #endif
>  
> +#ifdef CONFIG_CGROUPS
> +# define INIT_CGROUP_FORK_MUTEX(tsk)					\
> +	.cgroup_fork_mutex =						\
> +		__RWSEM_INITIALIZER(tsk.cgroup_fork_mutex),
> +#else
> +# define INIT_CGROUP_FORK_MUTEX(tsk)
> +#endif
> +
>  /*
>   *  INIT_TASK is used to set up the first task table, touch at
>   * your own risk!. Base=0, limit=0x1fffff (=2MB)
> @@ -174,6 +182,7 @@ extern struct cred init_cred;
>  	INIT_LOCKDEP							\
>  	INIT_FTRACE_GRAPH						\
>  	INIT_TRACE_RECURSION						\
> +	INIT_CGROUP_FORK_MUTEX(tsk)					\
>  }
>  
>  
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index 55e3e11..5d38980 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -1400,6 +1400,8 @@ struct task_struct {
>  	struct css_set *cgroups;
>  	/* cg_list protected by css_set_lock and tsk->alloc_lock */
>  	struct list_head cg_list;
> +	/* guarantees atomic threadgroup movement via the procs file */
> +	struct rw_semaphore cgroup_fork_mutex;
>  #endif
>  #ifdef CONFIG_FUTEX
>  	struct robust_list_head __user *robust_list;
> diff --git a/kernel/cgroup.c b/kernel/cgroup.c
> index ea05d6b..3ce7298 100644
> --- a/kernel/cgroup.c
> +++ b/kernel/cgroup.c
> @@ -1297,6 +1297,87 @@ static void get_first_subsys(const struct cgroup *cgrp,
>  		*subsys_id = test_ss->subsys_id;
>  }
>  
> +/*
> + * cgroup_task_migrate - move a task from one cgroup to another.
> + *
> + * 'guarantee' is set if the caller promises that a new css_set for the task
> + * will already exist. If not set, this function might sleep, and can fail
> + * with -ENOMEM. Otherwise, it can only fail with -ESRCH.
> + */
> +static int cgroup_task_migrate(struct cgroup *cgrp, struct cgroup *oldcgrp,
> +			       struct task_struct *tsk, int guarantee)
> +{
> +	struct css_set *oldcg;
> +	struct css_set *newcg;
> +
> +	/*
> +	 * get old css_set. we need to take task_lock and refcount it, because
> +	 * an exiting task can change its css_set to init_css_set and drop its
> +	 * old one without taking cgroup_mutex.
> +	 */
> +	task_lock(tsk);
> +	oldcg = tsk->cgroups;
> +	get_css_set(oldcg);
> +	task_unlock(tsk);

Better use blank lines more to improve code readability.

> +	/*
> +	 * locate or allocate a new css_set for this task. 'guarantee' tells
> +	 * us whether or not we are sure that a new css_set already exists;
> +	 * in that case, we are not allowed to fail, as we won't need malloc.
> +	 */
> +	if (guarantee) {
> +		/*
> +		 * our caller promises us that the css_set we want already
> +		 * exists, so we use find_existing_css_set directly.
> +		 */
> +		struct cgroup_subsys_state *template[CGROUP_SUBSYS_COUNT];
> +		read_lock(&css_set_lock);
> +		newcg = find_existing_css_set(oldcg, cgrp, template);
> +		BUG_ON(!newcg);
> +		get_css_set(newcg);
> +		read_unlock(&css_set_lock);
> +	} else {
> +		might_sleep();
> +		/* find_css_set will give us newcg already referenced. */
> +		newcg = find_css_set(oldcg, cgrp);
> +		if (!newcg) {
> +			put_css_set(oldcg);
> +			return -ENOMEM;
> +		}
> +	}
> +	put_css_set(oldcg);
> +
> +	/*
> +	 * we cannot move a task that's declared itself as exiting, as once
> +	 * PF_EXITING is set, the tsk->cgroups pointer is no longer safe.
> +	 */
> +	task_lock(tsk);
> +	if (tsk->flags & PF_EXITING) {
> +		task_unlock(tsk);
> +		put_css_set(newcg);
> +		return -ESRCH;
> +	}
> +	rcu_assign_pointer(tsk->cgroups, newcg);
> +	task_unlock(tsk);
> +
> +	/* Update the css_set linked lists if we're using them */
> +	write_lock(&css_set_lock);
> +	if (!list_empty(&tsk->cg_list)) {
> +		list_del(&tsk->cg_list);
> +		list_add(&tsk->cg_list, &newcg->tasks);

list_move()

> +	}
> +	write_unlock(&css_set_lock);
> +
> +	/*
> +	 * We just gained a reference on oldcg by taking it from the task. As

This comment is incorrect, the ref we just got has been dropped by
the above put_css_set(oldcg).

> +	 * trading it for newcg is protected by cgroup_mutex, we're safe to
> +	 * drop it here; it will be freed under RCU.
> +	 */
> +	put_css_set(oldcg);
> +
> +	set_bit(CGRP_RELEASABLE, &oldcgrp->flags);
> +	return 0;
> +}
> +
>  /**
>   * cgroup_attach_task - attach task 'tsk' to cgroup 'cgrp'
>   * @cgrp: the cgroup the task is attaching to
> @@ -1307,11 +1388,9 @@ static void get_first_subsys(const struct cgroup *cgrp,
>   */
>  int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
>  {
> -	int retval = 0;
> +	int retval;
>  	struct cgroup_subsys *ss;
>  	struct cgroup *oldcgrp;
> -	struct css_set *cg;
> -	struct css_set *newcg;
>  	struct cgroupfs_root *root = cgrp->root;
>  	int subsys_id;
>  
> @@ -1330,75 +1409,293 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
>  		}
>  	}
>  
> -	task_lock(tsk);
> -	cg = tsk->cgroups;
> -	get_css_set(cg);
> -	task_unlock(tsk);
> +	retval = cgroup_task_migrate(cgrp, oldcgrp, tsk, 0);
> +	if (retval)
> +		return retval;
> +
> +	for_each_subsys(root, ss) {
> +		if (ss->attach)
> +			ss->attach(ss, cgrp, oldcgrp, tsk, false);
> +	}
> +
> +	synchronize_rcu();
> +
>  	/*
> -	 * Locate or allocate a new css_set for this task,
> -	 * based on its final set of cgroups
> +	 * wake up rmdir() waiter. the rmdir should fail since the cgroup
> +	 * is no longer empty.
>  	 */
> +	cgroup_wakeup_rmdir_waiters(cgrp);
> +	return 0;
> +}
> +
> +/*
> + * cgroup_attach_proc works in two stages, the first of which prefetches all
> + * new css_sets needed (to make sure we have enough memory before committing
> + * to the move) and stores them in a list, of entries of the following type.
> + * TODO: possible optimization: use css_set->rcu_head for chaining instead
> + */
> +struct cg_list_entry {
> +	struct css_set *cg;
> +	struct list_head links;
> +};
> +
> +static int css_set_check_fetched(struct cgroup *cgrp, struct task_struct *tsk,
> +				 struct css_set *cg,
> +				 struct list_head *newcg_list)
> +{
> +	struct css_set *newcg;
> +	struct cg_list_entry *cg_entry;
> +	struct cgroup_subsys_state *template[CGROUP_SUBSYS_COUNT];
> +	read_lock(&css_set_lock);
> +	newcg = find_existing_css_set(cg, cgrp, template);
> +	if (newcg)
> +		get_css_set(newcg);
> +	read_unlock(&css_set_lock);
> +	/* doesn't exist at all? */
> +	if (!newcg)
> +		return 1;

I think it's more intuitive to return 1 if found and 0 if not found.

> +	/* see if it's already in the list */
> +	list_for_each_entry(cg_entry, newcg_list, links) {
> +		if (cg_entry->cg == newcg) {
> +			put_css_set(newcg);
> +			return 0;
> +		}
> +	}
> +	/* not found */
> +	put_css_set(newcg);
> +	return 1;

Those lines are squeezed too tight. ;)

> +}
> +


  parent reply	other threads:[~2009-08-03  3:02 UTC|newest]

Thread overview: 100+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-31  1:51 [PATCH v2 0/6] CGroups: cgroup memberlist enhancement+fix Ben Blum
2009-07-31  1:51 ` [PATCH 1/6] Adds a read-only "procs" file similar to "tasks" that shows only unique tgids Ben Blum
     [not found] ` <20090731012908.27908.62208.stgit-/yCBOHwbXCxd3OlUiQof+WCaruZE5nAUZeezCHUQhQ4@public.gmane.org>
2009-07-31  1:51   ` Ben Blum
2009-07-31  1:51   ` [PATCH 2/6] Ensures correct concurrent opening/reading of pidlists across pid namespaces Ben Blum
2009-07-31  1:51   ` [PATCH 3/6] Quick vmalloc vs kmalloc fix to the case where array size is too large Ben Blum
2009-07-31  1:51     ` Ben Blum
2009-07-31  1:51   ` [PATCH 4/6] Changes css_set freeing mechanism to be under RCU Ben Blum
2009-07-31  1:51   ` [PATCH 5/6] Lets ss->can_attach and ss->attach do whole threadgroups at a time Ben Blum
2009-07-31  1:51   ` [PATCH 6/6] Makes procs file writable to move all threads by tgid at once Ben Blum
2009-07-31  1:51 ` [PATCH 2/6] Ensures correct concurrent opening/reading of pidlists across pid namespaces Ben Blum
2009-07-31  1:51 ` [PATCH 4/6] Changes css_set freeing mechanism to be under RCU Ben Blum
2009-07-31  1:51 ` [PATCH 5/6] Lets ss->can_attach and ss->attach do whole threadgroups at a time Ben Blum
     [not found]   ` <20090731015149.27908.25403.stgit-/yCBOHwbXCxd3OlUiQof+WCaruZE5nAUZeezCHUQhQ4@public.gmane.org>
2009-08-03  2:22     ` Li Zefan
2009-08-03  2:22   ` Li Zefan
     [not found]     ` <4A7649E1.4000200-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
2009-08-04  0:35       ` Benjamin Blum
2009-08-04  0:35     ` Benjamin Blum
2009-07-31  1:51 ` [PATCH 6/6] Makes procs file writable to move all threads by tgid at once Ben Blum
     [not found]   ` <20090731015154.27908.9639.stgit-/yCBOHwbXCxd3OlUiQof+WCaruZE5nAUZeezCHUQhQ4@public.gmane.org>
2009-08-03  3:00     ` Li Zefan
2009-08-03 17:54     ` Serge E. Hallyn
2009-08-03  3:00   ` Li Zefan [this message]
2009-08-04  0:56     ` Benjamin Blum
     [not found]       ` <2f86c2480908031756j557e7aebmbf7951da6a1aadb0-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-08-04  1:05         ` Paul Menage
2009-08-04  1:09         ` Li Zefan
2009-08-04  1:09           ` Li Zefan
2009-08-04  1:19           ` Benjamin Blum
     [not found]             ` <2f86c2480908031819h2513cdb4tac3d6def3e0aa320-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-08-04  1:45               ` Li Zefan
2009-08-04  1:45             ` Li Zefan
     [not found]               ` <4A7792C4.5010504-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
2009-08-04  1:55                 ` Paul Menage
2009-08-04  1:55               ` Paul Menage
     [not found]           ` <4A778A49.6040302-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
2009-08-04  1:19             ` Benjamin Blum
2009-08-04  1:05       ` Paul Menage
     [not found]         ` <6599ad830908031805y31136eceqeff0bab455100d6c-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-08-04  1:11           ` Benjamin Blum
2009-08-04  1:11         ` Benjamin Blum
     [not found]     ` <4A7652E7.4020206-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
2009-08-04  0:56       ` Benjamin Blum
2009-08-03 17:54   ` Serge E. Hallyn
2009-08-03 18:07     ` Paul Menage
     [not found]     ` <20090803175452.GA5481-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2009-08-03 18:07       ` Paul Menage
2009-08-03 18:13       ` Benjamin Blum
2009-08-03 18:13     ` Benjamin Blum
2009-08-03 18:55       ` Serge E. Hallyn
     [not found]         ` <20090803185556.GA8469-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2009-08-03 19:45           ` Serge E. Hallyn
2009-08-03 19:45         ` Serge E. Hallyn
2009-08-03 19:55           ` Paul Menage
     [not found]             ` <6599ad830908031255j68ce047x7165bfefa62ed53c-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-08-04 14:01               ` Serge E. Hallyn
2009-08-04 21:40               ` Matt Helsley
2009-08-04 14:01             ` Serge E. Hallyn
2009-08-04 21:40             ` Matt Helsley
2009-08-04 21:40             ` Matt Helsley
     [not found]           ` <20090803194555.GA10158-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2009-08-03 19:55             ` Paul Menage
2009-08-04 18:48             ` Paul Menage
2009-08-04 18:48               ` Paul Menage
     [not found]               ` <6599ad830908041148h6d3f3e9bxfef9f3eedec0ab6d-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-08-04 19:01                 ` Serge E. Hallyn
2009-08-04 19:01                   ` Serge E. Hallyn
2009-08-04 19:14                 ` Benjamin Blum
2009-08-04 19:14                   ` Benjamin Blum
     [not found]                   ` <2f86c2480908041214r1f23c1b7q9a25b04e26c92a1a-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-08-04 19:28                     ` Paul Menage
2009-08-04 19:28                       ` Paul Menage
     [not found]                       ` <6599ad830908041228w67bc6f7fh57e28f244e1923b3-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-08-05 10:20                         ` Louis Rilling
2009-08-05 10:20                       ` Louis Rilling
     [not found]                         ` <20090805102057.GT29252-Hu8+6S1rdjywhHL9vcZdMVaTQe2KTcn/@public.gmane.org>
2009-08-05 16:11                           ` Paul Menage
2009-08-05 16:11                             ` Paul Menage
2009-08-05 16:42                             ` Louis Rilling
2009-08-05 16:53                               ` Peter Zijlstra
2009-08-06  0:01                               ` Benjamin Blum
2009-08-06  9:58                                 ` Louis Rilling
2009-08-06 10:04                                   ` Louis Rilling
     [not found]                                   ` <20090806095854.GD26446-Hu8+6S1rdjywhHL9vcZdMVaTQe2KTcn/@public.gmane.org>
2009-08-06 10:04                                     ` Louis Rilling
2009-08-06 10:28                                     ` Paul Menage
2009-08-06 10:28                                       ` Paul Menage
     [not found]                                       ` <6599ad830908060328y21a008c1pc5ed5c27e0ec905d-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-08-06 10:34                                         ` Peter Zijlstra
2009-08-06 10:34                                           ` Peter Zijlstra
2009-08-06 10:42                                           ` Paul Menage
2009-08-06 11:02                                             ` Peter Zijlstra
2009-08-06 11:24                                               ` Paul Menage
2009-08-06 11:24                                                 ` Paul Menage
2009-08-06 11:39                                                 ` Peter Zijlstra
2009-08-06 15:19                                                   ` Paul E. McKenney
2009-08-06 15:19                                                     ` Paul E. McKenney
     [not found]                                                     ` <20090806151922.GB6747-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2009-08-06 15:24                                                       ` Peter Zijlstra
2009-08-06 15:24                                                     ` Peter Zijlstra
2009-08-06 15:37                                                       ` Paul E. McKenney
2009-08-06 15:37                                                       ` Paul E. McKenney
     [not found]                                                 ` <6599ad830908060424r72e1aa12g2b246785e7bc039c-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-08-06 11:39                                                   ` Peter Zijlstra
     [not found]                                             ` <6599ad830908060342m1fc8cdd2me25af248a8e0e183-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-08-06 11:02                                               ` Peter Zijlstra
2009-08-06 10:42                                           ` Paul Menage
2009-08-06 11:24                                         ` Louis Rilling
2009-08-06 11:24                                           ` Louis Rilling
2009-08-06 11:40                                           ` Paul Menage
2009-08-06 14:54                                             ` Louis Rilling
     [not found]                                             ` <6599ad830908060440g2f6cbed6xdc54c7096cd3745e-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-08-06 14:54                                               ` Louis Rilling
2009-08-08  1:41                                               ` Benjamin Blum
2009-08-08  1:41                                             ` Benjamin Blum
2009-08-08  1:51                                               ` Benjamin Blum
     [not found]                                               ` <2f86c2480908071841h13009856hd8fcae167b1fadbf-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-08-08  1:51                                                 ` Benjamin Blum
     [not found]                                           ` <20090806112450.GF26446-Hu8+6S1rdjywhHL9vcZdMVaTQe2KTcn/@public.gmane.org>
2009-08-06 11:40                                             ` Paul Menage
     [not found]                                 ` <2f86c2480908051701s57120404q475edbedb58cdca1-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-08-06  9:58                                   ` Louis Rilling
     [not found]                               ` <20090805164218.GB26446-Hu8+6S1rdjywhHL9vcZdMVaTQe2KTcn/@public.gmane.org>
2009-08-05 16:53                                 ` Peter Zijlstra
2009-08-06  0:01                                 ` Benjamin Blum
     [not found]                             ` <6599ad830908050911t6f23f810i65fe8fe17f3ee698-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-08-05 16:42                               ` Louis Rilling
     [not found]       ` <2f86c2480908031113y525b6cbdhe418b8a0364c7760-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-08-03 18:55         ` Serge E. Hallyn

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=4A7652E7.4020206@cn.fujitsu.com \
    --to=lizf@cn.fujitsu.com \
    --cc=akpm@linux-foundation.org \
    --cc=bblum@google.com \
    --cc=containers@lists.linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=menage@google.com \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.