OpenVZ Forum - RDF feed
type: channel
items: [PATCH 0/6] linux-cr: make pids a proper shared object (v2)
items: [PATCH 1/6] c/r: introduce ckpt_task_vnr(), ckpt_pid_vnr()
items: [PATCH 2/6] c/r: nit to avoid rcu lockdep complaint in restore_obj_sighand()
items: [PATCH 3/6] c/r: introduce ckpt_obj_count() for the total number of objects
items: [PATCH 4/6] c/r: introduce pids objects
items: [PATCH 5/6] c/r: checkpoint and restart pids objects
items: [PATCH 6/6] c/r: use pids objects for the pgrp/old_pgdp of ttys

[PATCH 0/6] linux-cr: make pids a proper shared object (v2)
type: item
description: Hi, This patch-set changes the way pids are saved/restored to treat them as proper shared objects (tracked in objhash) rather than simple pid numbers. The patch-set applies on top of branch 'ckpt-v23-rc1'. It also requires updates to user-cr (patchset posted separately). Changelog[v2]: - Wipe out many bugs - this version now passes all tests-cr tests. - Rename 'depth' to 'vpids' as per Suka's suggestion Oren. _______________________________________________ Containers mailing list Containers@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/containe rs
creator: Oren Laadan
date: 2011-02-07T17:18:02-00:00

[PATCH 1/6] c/r: introduce ckpt_task_vnr(), ckpt_pid_vnr()
type: item
description: This helpoer is Useful to get the pid from the root task's (checkpoint or restart) point of view. Signed-off-by: Oren Laadan <orenl@cs.columbia.edu> --- include/linux/checkpoint.h | 10 +++++++++- kernel/checkpoint/checkpoint.c | 4 ++-- kernel/checkpoint/restart.c | 6 ++---- kernel/signal.c | 2 +- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/include/linux/checkpoint.h b/include/linux/checkpoint.h index 6c0ccfd..21fc23e 100644 --- a/include/linux/checkpoint.h +++ b/include/linux/checkpoint.h @@ -114,8 +114,16 @@ extern int checkpoint_dump_page(struct ckpt_ctx *ctx, struct page *page); extern int restore_read_page(struct ckpt_ctx *ctx, struct page *page); /* pids */ -extern pid_t ckpt_pid_nr(struct ckpt_ctx *ctx, struct pid *pid); extern struct pid *_ckpt_find_pgrp(struct ckpt_ctx *ctx, pid_t pgid); +static inline pid_t ckpt_task_vnr(struct ckpt_ctx *ctx, struct task_struct *task) +{ + return task_pid_nr_ns(task, ctx->root_nsproxy->pid_ns); +} +static inline pid_t ckpt_pid_vnr(struct ckpt_ctx *ctx, struct pid *pid) +{ + return pid_nr_ns(pid, ctx->root_nsproxy->pid_ns); +} +extern int ckpt_lookup_pid(struct ckpt_ctx *ctx, struct pid *pid); /* defined in objhash.c and also used in security/security.c */ extern void lsm_string_free(struct kref *kref); diff --git a/kernel/checkpoint/checkpoint.c b/kernel/checkpoint/checkpoint.c index 0f46acf..01653d7 100644 --- a/kernel/checkpoint/checkpoint.c +++ b/kernel/checkpoint/checkpoint.c @@ -243,10 +243,10 @@ static int may_checkpoint_task(struct ckpt_ctx *ctx, struct task_struct *t) { struct task_struct *root = ctx->root_task; struct nsproxy *nsproxy; - int ret = 0; struct pid_namespace *pidns; + int ret = 0; - ckpt_debug("check %d\n", task_pid_nr_ns(t, ctx->root_nsproxy->pid_ns)); + ckpt_debug("check %d\n", ckpt_task_vnr(ctx, t)); if (t->exit_state == EXIT_DEAD) { _ckpt_err(ctx, -EBUSY, "%(T)Task state EXIT_DEAD\n"); diff --git a/kernel/checkpoint/restart.c b/kernel/checkpoint/restart.c index 01da67f..66b6625 1…
creator: Oren Laadan
date: 2011-02-07T17:18:03-00:00

[PATCH 2/6] c/r: nit to avoid rcu lockdep complaint in restore_obj_sighand()
type: item
description: Signed-off-by: Oren Laadan <orenl@cs.columbia.edu> --- kernel/signal.c | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/kernel/signal.c b/kernel/signal.c index dca40be..3842f5d 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2871,7 +2871,7 @@ static void *restore_sighand(struct ckpt_ctx *ctx) int restore_obj_sighand(struct ckpt_ctx *ctx, int sighand_objref) { struct sighand_struct *sighand; - struct sighand_struct *old_sighand; + struct sighand_struct *old_sighand = NULL; sighand = ckpt_obj_fetch(ctx, sighand_objref, CKPT_OBJ_SIGHAND); if (IS_ERR(sighand)) @@ -2884,11 +2884,14 @@ int restore_obj_sighand(struct ckpt_ctx *ctx, int sighand_objref) /* manipulate tsk->sighand with tasklist lock write-held */ write_lock_irq(&tasklist_lock); - old_sighand = rcu_dereference(current->sighand); + old_sighand = rcu_dereference_check(current->sighand, + rcu_read_lock_held() || + lockdep_is_held(&tasklist_lock)); spin_lock(&old_sighand->siglock); rcu_assign_pointer(current->sighand, sighand); spin_unlock(&old_sighand->siglock); write_unlock_irq(&tasklist_lock); + __cleanup_sighand(old_sighand); return 0; -- 1.7.1 _______________________________________________ Containers mailing list Containers@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/containe rs
creator: Oren Laadan
date: 2011-02-07T17:18:04-00:00

[PATCH 3/6] c/r: introduce ckpt_obj_count() for the total number of objects
type: item
description: This will be needed for pids-objects in container checkpoints. In userspace we will rely on the pids objects inserted to the objash sequentially. For subtree checkpoint, the pids objects are the first to enter the objhash, therefore their tags will counting from 1. In container checkpoint, other objects are inserted first, so we will need to know how many objects were inserted earlier - so we will alos save the count at that time. Signed-off-by: Oren Laadan <orenl@cs.columbia.edu> --- include/linux/checkpoint.h | 2 ++ kernel/checkpoint/objhash.c | 5 +++++ 2 files changed, 7 insertions(+), 0 deletions(-) diff --git a/include/linux/checkpoint.h b/include/linux/checkpoint.h index 21fc23e..65b6477 100644 --- a/include/linux/checkpoint.h +++ b/include/linux/checkpoint.h @@ -211,6 +211,8 @@ extern int ckpt_obj_insert(struct ckpt_ctx *ctx, void *ptr, int objref, extern int ckpt_obj_reserve(struct ckpt_ctx *ctx); extern int ckpt_obj_delete(struct ckpt_ctx *ctx, int objref, enum obj_type type); +extern int ckpt_obj_count(struct ckpt_ctx *ctx); + extern struct ckpt_ctx *ckpt_ctx_get(struct ckpt_ctx *ctx); extern void ckpt_ctx_put(struct ckpt_ctx *ctx); diff --git a/kernel/checkpoint/objhash.c b/kernel/checkpoint/objhash.c index 40c2e9b..cbace7a 100644 --- a/kernel/checkpoint/objhash.c +++ b/kernel/checkpoint/objhash.c @@ -158,6 +158,11 @@ static inline int obj_alloc_objref(struct ckpt_ctx *ctx) return ctx->obj_hash->next_free_objref++; } +int ckpt_obj_count(struct ckpt_ctx *ctx) +{ + return ctx->obj_hash->next_free_objref; +} + /** * ckpt_obj_new - add an object to the obj_hash * @ctx: checkpoint context -- 1.7.1 _______________________________________________ Containers mailing list Containers@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/containe rs
creator: Oren Laadan
date: 2011-02-07T17:18:05-00:00

[PATCH 4/6] c/r: introduce pids objects
type: item
description: Add the interface to handle pids as proper c/r shared objects. This is the first step in converting the c/r code to hanlde pid as pids objects that are namespace aware. Also remote the unused field @root_pid from struct ckpt_ctx. Signed-off-by: Oren Laadan <orenl@cs.columbia.edu> --- include/linux/checkpoint_hdr.h | 6 +++++- include/linux/checkpoint_types.h | 1 - kernel/checkpoint/checkpoint.c | 2 -- kernel/checkpoint/restart.c | 1 - kernel/pid.c | 28 ++++++++++++++++++++++++++++ 5 files changed, 33 insertions(+), 5 deletions(-) diff --git a/include/linux/checkpoint_hdr.h b/include/linux/checkpoint_hdr.h index b12d586..922eff0 100644 --- a/include/linux/checkpoint_hdr.h +++ b/include/linux/checkpoint_hdr.h @@ -245,6 +245,8 @@ struct ckpt_hdr_objref { enum obj_type { CKPT_OBJ_IGNORE = 0, #define CKPT_OBJ_IGNORE CKPT_OBJ_IGNORE + CKPT_OBJ_PID, +#define CKPT_OBJ_PID CKPT_OBJ_PID CKPT_OBJ_INODE, #define CKPT_OBJ_INODE CKPT_OBJ_INODE CKPT_OBJ_FILE_TABLE, @@ -373,7 +375,9 @@ struct ckpt_pids { } __attribute__((aligned(8))); /* pids */ -#define CKPT_PID_NULL -1 +/* (negative but not valid error) */ +#define CKPT_PID_NULL (-4096) /* null pid pointer */ +#define CKPT_PID_ROOT (-4097) /* pid same as root task */ /* task data */ struct ckpt_hdr_task { diff --git a/include/linux/checkpoint_types.h b/include/linux/checkpoint_types.h index cf74d3e..87a569a 100644 --- a/include/linux/checkpoint_types.h +++ b/include/linux/checkpoint_types.h @@ -35,7 +35,6 @@ struct ckpt_ctx { ktime_t ktime_begin; /* operation start time */ int root_init; /* [container] root init ? */ - pid_t root_pid; /* [container] root pid */ struct task_struct *root_task; /* [container] root task */ struct nsproxy *root_nsproxy; /* [container] root nsproxy */ struct task_struct *root_freezer; /* [container] root task */ diff --git a/kernel/checkpoint/checkpoint.c b/kernel/checkpoint/checkpoint.c index 01653d7..a850423 100644 --- a/kernel/checkpoint/checkpoint.c +++ b/kernel/checkpoint/checkpoint.c @@ -628,8 +62…
creator: Oren Laadan
date: 2011-02-07T17:18:06-00:00

[PATCH 5/6] c/r: checkpoint and restart pids objects
type: item
description: Make use of (shared) pids objects instead of simply saving the pid_t numbers in both checkpoint and restart. The motivation for this change is twofold. First, since pid-ns came to life pid's in the kenrel _are_ shared objects and should be treated as such. This is useful e.g. for tty handling and also file-ownership (the latter waiting for this feature). Second, to properly support nested namesapces we need to report with each pid the entire list of pid numbers, not only a single pid. While current we do that for all "live" pids (those that belong to live tasks), we didn't do it for "dead" pids (to be assigned to ghost restarting tasks). Note, that ideally the list of vpids of a pid object should also include the pid-ns to which each level belongs; however, in this patch we don't yet hanlde that. So only linear pid-nesting works well and not arbitrary tree. DICLAIMER: this patch is big and intrusive! Here is a summary of the changes that it makes: CHECKPOINT: 1) Modified the data structures used to describe pids and tasks' pids: struct ckpt_pids - for the data of a pids object (depth, numbers) (pids objects are collected in the order found, and are assigned tags sequentially, starting from 1) struct ckpt_task_pids - for a task's pids, holding the _tag_ of the corresponding pids object rather than their pid numbers themselves. 2) Accordingly, two arrays are used to hold this information: ctx->pids_arr - array of 'struct ckpt_pids' collected from the tasks and the pids they reference. Entries are of variable size depending on the pid-ns nesting level. ctx->tasks_arr - array of 'struct ckpt_task_pids' collected from teh tasks. Entries are of fixed size, and hold the objref tags to the shared pids objects rather than actual pid numbers. (the old vpids_arr is no longer needed, nor written separately). 3) We now first write the pids information, then tasks' pids. 4) checkpoint_pids() builds and writes the ctx->pids_arr: checkpoint_pids_build() - iterates over the tasks an…
creator: Oren Laadan
date: 2011-02-07T17:18:07-00:00

[PATCH 6/6] c/r: use pids objects for the pgrp/old_pgdp of ttys
type: item
description: Make tty_old_pgrp and tty_pgrp use the shared pid instead of saving the actual pid number in {checkpoint,restore}_signal(). Signed-off-by: Oren Laadan <orenl@cs.columbia.edu> --- kernel/signal.c | 42 ++++++++++++++++++++++++++++++++---------- 1 files changed, 32 insertions(+), 10 deletions(-) diff --git a/kernel/signal.c b/kernel/signal.c index 718b940..5c174a9 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -3218,25 +3218,34 @@ static int checkpoint_signal(struct ckpt_ctx *ctx, struct task_struct *t) /* tty */ if (signal->leader) { - h->tty_old_pgrp = ckpt_pid_vnr(ctx, signal->tty_old_pgrp); + h->tty_old_pgrp = ckpt_lookup_pid(ctx, signal->tty_old_pgrp); tty = tty_kref_get(signal->tty); if (tty) { /* irq is already disabled */ spin_lock(&tty->ctrl_lock); - h->tty_pgrp = ckpt_pid_vnr(ctx, tty->pgrp); + h->tty_pgrp = ckpt_lookup_pid(ctx, tty->pgrp); spin_unlock(&tty->ctrl_lock); - tty_kref_put(tty); } } unlock_task_sighand(t, &flags); /* + * tty_pgrp must be in our namespace, since we are the + * session leader and could not have unshared pidns ! + */ + if (tty && h->tty_pgrp == 0) { + ckpt_err(ctx, -EBUSY, "%(T)tty_pgrp outside namespace\n"); + ret = -EBUSY; + goto out; + } + + /* * If the session is in an ancestor namespace, skip this tty * and set tty_objref = 0. It will not be explicitly restored, * but rather inherited from parent pid-ns at restart time. */ - if (tty && ckpt_pid_vnr(ctx, tty->session) > 0) { + if (tty && ckpt_lookup_pid(ctx, tty->session) > 0) { h->tty_objref = checkpoint_obj(ctx, tty, CKPT_OBJ_TTY); if (h->tty_objref < 0) ret = h->tty_objref; @@ -3255,6 +3264,7 @@ static int checkpoint_signal(struct ckpt_ctx *ctx, struct task_struct *t) list_splice(&shared_pending.list, &signal->shared_pending.list); unlock_task_sighand(t, &flags); out: + tty_kref_put(tty); ckpt_hdr_put(ctx, h); return ret; } @@ -3339,6 +3349,10 @@ static int restore_signal(struct ckpt_ctx *ctx) /* tty - session */ if (h->tty_objref) { + /* + * should only get here if we …
creator: Oren Laadan
date: 2011-02-07T17:18:08-00:00