[Devel] [PATCH 1/7] move handling of err down into _ckpt_do_msg and _append
serue at us.ibm.com
serue at us.ibm.com
Thu Nov 5 16:00:13 PST 2009
From: Serge E. Hallyn <serue at us.ibm.com>
Since ckpt_err() will also be used at restart, and since at
restart we don't want to just set ctx->err, move handling of
the argument 'err' further down. We only set ckpt->errno if
err is not 0 and a checkpoint is going on. Then we automatically
add '[err %d] % err' if err is non-0, so that the caller has a
choice of passing in err or passing %(E) in fmt and err as a
vararg.
Changelog:
nov 4: drop %(E) and print passed-in err instead
Signed-off-by: Serge E. Hallyn <serue at us.ibm.com>
---
checkpoint/sys.c | 51 +++++++++++++++++++++++++++----------------
include/linux/checkpoint.h | 16 ++++++-------
2 files changed, 39 insertions(+), 28 deletions(-)
diff --git a/checkpoint/sys.c b/checkpoint/sys.c
index 7d14b30..c1c4e99 100644
--- a/checkpoint/sys.c
+++ b/checkpoint/sys.c
@@ -382,14 +382,13 @@ static inline int is_special_flag(char *s)
* The special flags are surrounded by %() to help them visually stand
* out. For instance, %(O) means an objref. The following special
* flags are recognized:
- * E: error
* O: objref
* P: pointer
* T: task
* S: string
* V: variable
*
- * %(E) will be expanded to "[err %d]". Likewise O, P, S, and V, will
+ * %(O) will be expanded to "[obj %d]". Likewise P, S, and V, will
* also expand to format flags requiring an argument to the subsequent
* sprintf or printk. T will be expanded to a string with no flags,
* requiring no further arguments.
@@ -401,7 +400,7 @@ static inline int is_special_flag(char *s)
* the additional variabes, in order, to match the @fmt (except for
* the T key), e.g.:
*
- * ckpt_err(ctx, "%(T)FILE flags %d %(O) %(E)\n", flags, objref, err);
+ * ckpt_err(ctx, err, "%(T)FILE flags %d %(O)\n", flags, objref);
*
* May be called under spinlock.
* Must be called with ctx->msg_mutex held. The expanded format
@@ -418,9 +417,6 @@ static void _ckpt_generate_fmt(struct ckpt_ctx *ctx, char *fmt)
continue;
}
switch (fmt[2]) {
- case 'E':
- len += snprintf(s+len, CKPT_MSG_LEN-len, "[err %%d]");
- break;
case 'O':
len += snprintf(s+len, CKPT_MSG_LEN-len, "[obj %%d]");
break;
@@ -455,24 +451,41 @@ static void _ckpt_generate_fmt(struct ckpt_ctx *ctx, char *fmt)
s[len] = '\0';
}
-static void _ckpt_msg_appendv(struct ckpt_ctx *ctx, char *fmt, va_list ap)
+static void _ckpt_msg_appendv(struct ckpt_ctx *ctx, int err, char *fmt,
+ va_list ap)
{
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)
+ goto full;
+ }
+
len += vsnprintf(&ctx->msg[len], CKPT_MSG_LEN-len, fmt, ap);
if (len > CKPT_MSG_LEN) {
+full:
len = CKPT_MSG_LEN;
ctx->msg[CKPT_MSG_LEN-1] = '\0';
}
ctx->msglen = len;
}
-void _ckpt_msg_append(struct ckpt_ctx *ctx, char *fmt, ...)
+void _ckpt_msg_append(struct ckpt_ctx *ctx, int err, char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
- _ckpt_msg_appendv(ctx, fmt, ap);
+ _ckpt_msg_appendv(ctx, err, fmt, ap);
va_end(ap);
}
@@ -507,25 +520,25 @@ void _ckpt_msg_complete(struct ckpt_ctx *ctx)
ctx->msglen = 0;
}
-#define __do_ckpt_msg(ctx, fmt) do { \
- va_list ap; \
- _ckpt_generate_fmt(ctx, fmt); \
- va_start(ap, fmt); \
- _ckpt_msg_appendv(ctx, ctx->fmt, ap); \
- va_end(ap); \
+#define __do_ckpt_msg(ctx, err, fmt) do { \
+ va_list ap; \
+ _ckpt_generate_fmt(ctx, fmt); \
+ va_start(ap, fmt); \
+ _ckpt_msg_appendv(ctx, err, ctx->fmt, ap); \
+ va_end(ap); \
} while (0)
-void _do_ckpt_msg(struct ckpt_ctx *ctx, char *fmt, ...)
+void _do_ckpt_msg(struct ckpt_ctx *ctx, int err, char *fmt, ...)
{
- __do_ckpt_msg(ctx, fmt);
+ __do_ckpt_msg(ctx, err, fmt);
}
-void do_ckpt_msg(struct ckpt_ctx *ctx, char *fmt, ...)
+void do_ckpt_msg(struct ckpt_ctx *ctx, int err, char *fmt, ...)
{
if (!ctx) return;
ckpt_msg_lock(ctx);
- __do_ckpt_msg(ctx, fmt);
+ __do_ckpt_msg(ctx, err, fmt);
_ckpt_msg_complete(ctx);
ckpt_msg_unlock(ctx);
}
diff --git a/include/linux/checkpoint.h b/include/linux/checkpoint.h
index 89e6fb3..8fd6cba 100644
--- a/include/linux/checkpoint.h
+++ b/include/linux/checkpoint.h
@@ -384,7 +384,7 @@ extern void ckpt_msg_unlock(struct ckpt_ctx *ctx);
* May be called under spinlock.
* Must be called under ckpt_msg_lock().
*/
-extern void _ckpt_msg_append(struct ckpt_ctx *ctx, char *fmt, ...);
+extern void _ckpt_msg_append(struct ckpt_ctx *ctx, int err, char *fmt, ...);
/*
* Write ctx->msg to all relevant places.
@@ -399,7 +399,7 @@ extern void _ckpt_msg_complete(struct ckpt_ctx *ctx);
* the caller will have to use _ckpt_msg_complete() to finish up.
* Must be called with ckpt_msg_lock held.
*/
-extern void _do_ckpt_msg(struct ckpt_ctx *ctx, char *fmt, ...);
+extern void _do_ckpt_msg(struct ckpt_ctx *ctx, int err, char *fmt, ...);
/*
* Append an enhanced formatted message to ctx->msg.
@@ -411,12 +411,11 @@ extern void _do_ckpt_msg(struct ckpt_ctx *ctx, char *fmt, ...);
*
* Must not be called under spinlock.
*/
-extern void do_ckpt_msg(struct ckpt_ctx *ctx, char *fmt, ...);
+extern void do_ckpt_msg(struct ckpt_ctx *ctx, int err, char *fmt, ...);
#define ckpt_err(ctx, err, fmt, args...) do { \
- ctx->errno = (err); \
- do_ckpt_msg(ctx, "[Error at %s:%d][err %d]" fmt, __func__, __LINE__, \
- (err), ##args); \
+ do_ckpt_msg(ctx, (err), "[Error at %s:%d]" fmt, __func__, __LINE__, \
+ ##args); \
} while (0)
@@ -427,9 +426,8 @@ extern void do_ckpt_msg(struct ckpt_ctx *ctx, char *fmt, ...);
* must be followed by a call to _ckpt_msg_complete()
*/
#define _ckpt_err(ctx, err, fmt, args...) do { \
- ctx->errno = (err); \
- _do_ckpt_msg(ctx, "[ error %s:%d][err %d]" fmt, __func__, __LINE__, \
- (err), ##args); \
+ _do_ckpt_msg(ctx, (err), "[Error at %s:%d]" fmt, __func__, __LINE__, \
+ ##args); \
} while (0)
#endif /* CONFIG_CHECKPOINT */
--
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