[Devel] [PATCH 6/6] have ckpt_err set ctx->errno
serue at us.ibm.com
serue at us.ibm.com
Tue Nov 17 17:53:33 PST 2009
From: Serge E. Hallyn <serue at us.ibm.com>
Move setting of ctx->errno into do_ckpt_msg(). If the operation is
a restart, and errno was previously unset, then also wake all waiting
callers so they know to quit.
NOTE that the way this is set up, users of _ckpt_err().._ckpt_msg_complete()
do not cause restore_wake_all_on_error() to be called. If a restart
path has to use _ckpt_err(), then we'll have to work around that, which
seems simplest to do by again using the CKPT_CTX_WOKEN flag separate from
CKPT_CTX_ERROR.
Signed-off-by: Serge E. Hallyn <serue at us.ibm.com>
---
checkpoint/restart.c | 32 ++++----------------------------
checkpoint/sys.c | 25 +++++++++++++++++--------
include/linux/checkpoint.h | 6 ------
3 files changed, 21 insertions(+), 42 deletions(-)
diff --git a/checkpoint/restart.c b/checkpoint/restart.c
index 6cdefc9..a45263e 100644
--- a/checkpoint/restart.c
+++ b/checkpoint/restart.c
@@ -719,29 +719,6 @@ static inline int is_task_active(struct ckpt_ctx *ctx, pid_t pid)
return get_active_pid(ctx) == pid;
}
-/* should not be called under write_lock_irq(&tasklist_lock) */
-static void _restore_notify_error(struct ckpt_ctx *ctx, int errno)
-{
- /* first to fail: notify everyone (racy but harmless) */
- if (!ckpt_test_ctx_error(ctx)) {
- ckpt_debug("setting restart error %d\n", errno); \
- ckpt_set_ctx_error(ctx, errno);
- complete(&ctx->complete);
- wake_up_all(&ctx->waitq);
- wake_up_all(&ctx->ghostq);
- }
-}
-
-/*
- * Need to call ckpt_debug such that it will get the correct source
- * location. Should not be called under write_lock_irq(&tasklist_lock)
-*/
-#define restore_notify_error(ctx, errno) \
-do { \
- ckpt_debug("restart error %d, root pid %d\n", errno, ctx->root_pid); \
- _restore_notify_error(ctx, errno); \
-} while(0)
-
static inline struct ckpt_ctx *get_task_ctx(struct task_struct *task)
{
struct ckpt_ctx *ctx;
@@ -812,8 +789,7 @@ static int restore_activate_next(struct ckpt_ctx *ctx)
rcu_read_unlock();
if (!task) {
- ckpt_debug("could not find task %d\n", pid);
- restore_notify_error(ctx, -ESRCH);
+ ckpt_err(ctx, -ESRCH, "could not find task %d\n", pid);
return -ESRCH;
}
} else {
@@ -898,7 +874,7 @@ static int do_ghost_task(void)
out:
restore_debug_error(ctx, ret);
if (ret < 0)
- restore_notify_error(ctx, ret);
+ ckpt_err(ctx, ret, "Error while restarting ghost\n");
current->exit_signal = -1;
restore_debug_exit(ctx);
@@ -1009,7 +985,7 @@ static int do_restore_task(void)
out:
restore_debug_error(ctx, ret);
if (ret < 0)
- restore_notify_error(ctx, ret);
+ ckpt_err(ctx, ret, "Error while restarting task\n");
post_restore_task();
current->flags &= ~PF_RESTARTING;
@@ -1272,7 +1248,7 @@ static int do_restore_coord(struct ckpt_ctx *ctx, pid_t pid)
restore_debug_error(ctx, ret);
if (ret < 0)
- ckpt_set_ctx_error(ctx, ret);
+ ckpt_err(ctx, ret, "Error while restarting coordinator\n");
if (ckpt_test_ctx_error(ctx)) {
destroy_descendants(ctx);
diff --git a/checkpoint/sys.c b/checkpoint/sys.c
index bf66418..f22bdb7 100644
--- a/checkpoint/sys.c
+++ b/checkpoint/sys.c
@@ -376,6 +376,19 @@ static inline int is_special_flag(char *s)
}
/*
+ * If exiting a restart with error, then wake up all other tasks
+ * in the restart context.
+ */
+static void restore_wake_all_on_error(struct ckpt_ctx *ctx)
+{
+ if (!ctx->kflags & CKPT_CTX_RESTART)
+ return;
+ complete(&ctx->complete);
+ wake_up_all(&ctx->waitq);
+ wake_up_all(&ctx->ghostq);
+}
+
+/*
* _ckpt_generate_fmt - handle the special flags in the enhanced format
* strings used by checkpoint/restart error messages.
* @ctx: checkpoint context
@@ -459,14 +472,6 @@ static void _ckpt_msg_appendv(struct ckpt_ctx *ctx, int err, char *fmt,
int len = ctx->msglen;
if (err) {
- /* At restart we must use a more baroque helper to set
- * ctx->errno, which also wakes all other waiting restarting
- * tasks. But at checkpoint we just set ctx->errno so that
- * _ckpt_msg_complete() will know to write the error message
- * to the checkpoint image.
- */
- if (ctx->kflags & CKPT_CTX_CHECKPOINT && !ctx->errno)
- ctx->errno = err;
len += snprintf(&ctx->msg[len], CKPT_MSG_LEN-len, "[err %d]",
err);
if (len > CKPT_MSG_LEN)
@@ -543,6 +548,10 @@ void do_ckpt_msg(struct ckpt_ctx *ctx, int err, char *fmt, ...)
{
if (!ctx) return;
+ if (err && !ckpt_test_and_set_ctx_kflag(ctx, CKPT_CTX_ERROR)) {
+ ctx->errno = err;
+ restore_wake_all_on_error(ctx);
+ }
ckpt_msg_lock(ctx);
__do_ckpt_msg(ctx, err, fmt);
_ckpt_msg_complete(ctx);
diff --git a/include/linux/checkpoint.h b/include/linux/checkpoint.h
index 65765af..470097d 100644
--- a/include/linux/checkpoint.h
+++ b/include/linux/checkpoint.h
@@ -104,12 +104,6 @@ extern int ckpt_sock_getnames(struct ckpt_ctx *ctx,
#define ckpt_set_ctx_success(ctx) ckpt_set_ctx_kflag(ctx, CKPT_CTX_SUCCESS)
-static inline void ckpt_set_ctx_error(struct ckpt_ctx *ctx, int errno)
-{
- if (!ckpt_test_and_set_ctx_kflag(ctx, CKPT_CTX_ERROR))
- ctx->errno = errno;
-}
-
#define ckpt_test_ctx_error(ctx) \
((ctx)->kflags & CKPT_CTX_ERROR)
#define ckpt_test_ctx_complete(ctx) \
--
1.6.1
_______________________________________________
Containers mailing list
Containers at lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers
More information about the Devel
mailing list