[Devel] [PATCH 03/22] switch ckpt_generate_err to use ctx fields

serue at us.ibm.com serue at us.ibm.com
Fri Oct 30 16:00:25 PDT 2009


From: Serge E. Hallyn <serue at us.ibm.com>

ckpt_generate_fmt() now places the format in ctx->fmt_buf.
ckpt_fill_err_string() calls ckpt_generate_fmt() under
ctx->fmt_buf_lock, and writes its own error (under
ctx->err_string_lock) to ctx->err_string.

Signed-off-by: Serge E. Hallyn <serue at us.ibm.com>
---
 checkpoint/checkpoint.c    |   76 ++++++++++++++++++++++++++++++--------------
 checkpoint/sys.c           |   16 ++-------
 include/linux/checkpoint.h |    3 +-
 3 files changed, 58 insertions(+), 37 deletions(-)

diff --git a/checkpoint/checkpoint.c b/checkpoint/checkpoint.c
index d0ffd0d..49f6e9d 100644
--- a/checkpoint/checkpoint.c
+++ b/checkpoint/checkpoint.c
@@ -96,36 +96,52 @@ int ckpt_write_string(struct ckpt_ctx *ctx, char *str, int len)
 	return ckpt_write_obj_type(ctx, str, len, CKPT_HDR_STRING);
 }
 
-/* see _ckpt_generate_fmt for information on @fmt0 */
-static void __ckpt_generate_err(struct ckpt_ctx *ctx, char *fmt0,
+static void ckpt_fill_err_string(struct ckpt_ctx *ctx, char *fmt0,
 				char *fmt, va_list ap)
 {
 	va_list aq;
-	char *format;
-	char *str;
 	int len;
+	unsigned long flags;
 
-	format = ckpt_generate_fmt(ctx, fmt0, fmt);
+	spin_lock_irqsave(&ctx->err_string_lock, flags);
+	spin_lock(&ctx->fmt_buf_lock);
+	ckpt_generate_fmt(ctx, fmt0, fmt);
 	va_copy(aq, ap);
 
+	if (ctx->err_string_len == CKPT_MSG_BUFSZ)
+		goto out_unlock;
+
 	/*
 	 * prefix the error string with a '\0' to facilitate easy
 	 * backtrace to the beginning of the error message without
 	 * needing to parse the entire checkpoint image.
 	 */
-	ctx->err_string[0] = '\0';
-	str = &ctx->err_string[1];
-	len = vsnprintf(str, 255, format ? : fmt, ap) + 2;
+	if (ctx->err_string_len == 0) {
+		ctx->err_string[0] = '\0';
+		ctx->err_string_len = 1;
+	}
 
-	if (len > 256) {
+	len = vsnprintf(ctx->err_string + ctx->err_string_len,
+			CKPT_MSG_BUFSZ - ctx->err_string_len,
+			ctx->fmt_buf, ap);
+
+	if (len >= CKPT_MSG_BUFSZ - ctx->err_string_len) {
 		printk(KERN_NOTICE "c/r: error string truncated: ");
 		vprintk(fmt, aq);
-	}
+		ctx->err_string[CKPT_MSG_BUFSZ-1] = '\0';
+		ctx->err_string_len = CKPT_MSG_BUFSZ;
+	} else
+		/* vscnprintf did add a \0 but didn't count
+		 * it toward the len.  We want it to count
+		 * toward the len so we keep a \0 between each
+		 * error msg */
+		ctx->err_string_len += len + 1;
 
 	va_end(aq);
-	kfree(format);
 
-	ckpt_debug("c/r: checkpoint error: %s\n", str);
+out_unlock:
+	spin_unlock(&ctx->fmt_buf_lock);
+	spin_unlock_irqrestore(&ctx->err_string_lock, flags);
 }
 
 /**
@@ -143,7 +159,7 @@ void __ckpt_write_err(struct ckpt_ctx *ctx, char *fmt0, char *fmt, ...)
 	va_list ap;
 
 	va_start(ap, fmt);
-	__ckpt_generate_err(ctx, fmt0, fmt, ap);
+	ckpt_fill_err_string(ctx, fmt, ap);
 	va_end(ap);
 }
 
@@ -160,29 +176,41 @@ void __ckpt_write_err(struct ckpt_ctx *ctx, char *fmt0, char *fmt, ...)
 int ckpt_write_err(struct ckpt_ctx *ctx, char *fmt0, char *fmt, ...)
 {
 	va_list ap;
-	char *str;
-	int len, ret = 0;
+	int i, len, ret = 0;
 
 	if (fmt) {
 		va_start(ap, fmt);
-		__ckpt_generate_err(ctx, fmt0, fmt, ap);
+		ckpt_fill_err_string(ctx,  fmt, ap);
 		va_end(ap);
 	}
 
-	str = ctx->err_string;
-	len = strlen(str + 1);
-	if (len == 0)	/* empty error string */
-		return 0;
+	mutex_lock(&ctx->msg_buf_mutex);
+	spin_lock(&ctx->err_string_lock);
+	len = ctx->err_string_len;
+	memcpy(ctx->msg_buf, ctx->err_string, len);
+	ctx->err_string_len = 0;
+	spin_unlock(&ctx->err_string_lock);
+
+	if (len == 0)
+		goto out_unlock;
 
-	len += 2; 	/* leading and trailing '\0' */
+	ctx->msg_buf_len = len;
+	/* write to the checkpoint image */
 	ret = ckpt_write_obj_type(ctx, NULL, 0, CKPT_HDR_ERROR);
 	if (!ret)
-		ret = ckpt_write_string(ctx, str, len);
+		ret = ckpt_write_string(ctx, ctx->msg_buf, ctx->msg_buf_len);
 	if (ret < 0)
 		printk(KERN_NOTICE "c/r: error string unsaved (%d): %s\n",
-		       ret, str + 1);
+		       ret, ctx->msg_buf);
+
+	/* duplicate to user log file and syslog */
+	for (i = 0; i < len-1; i++)
+		if (ctx->msg_buf[i] == '\0')
+			ctx->msg_buf[i] = '\n';
+	ckpt_do_write_msg(ctx);
 
-	str[1] = '\0';
+out_unlock:
+	mutex_unlock(&ctx->msg_buf_mutex);
 	return ret;
 }
 
diff --git a/checkpoint/sys.c b/checkpoint/sys.c
index 0a486f0..8810576 100644
--- a/checkpoint/sys.c
+++ b/checkpoint/sys.c
@@ -375,12 +375,13 @@ int walk_task_subtree(struct task_struct *root,
  *
  * Here, T is simply passed, E expects an integer (err), O expects an
  * integer (objref), and the last argument matches the format string.
+ *
+ * Must be called with ctx->fmt_buf_lock held.  The expanded format
+ * will be placed in ctx->fmt_buf.
  */
 char *ckpt_generate_fmt(struct ckpt_ctx *ctx, char *fmt0, char *fmt)
 {
-	static int warn_notask = 0;
-	static int warn_prefmt = 0;
-	char *format;
+	char *format = ctx->fmt_buf;
 	int i, j, len = 0;
 
 	static struct {
@@ -395,15 +396,6 @@ char *ckpt_generate_fmt(struct ckpt_ctx *ctx, char *fmt0, char *fmt)
 		{ 0, "??? %pS" },
 	};
 
-	/*
-	 * 17 for "pid %d" (plus space)
-	 * 21 for "tsk %s" (tsk->comm)
-	 * up to 8 per varfmt entry
-	 */
-	format = kzalloc(37 + 8 * strlen(fmt0) + strlen(fmt), GFP_KERNEL);
-	if (!format)
-		return NULL;
-
 	format[len++] = '[';
 
 	if (fmt0[0] == 'T') {
diff --git a/include/linux/checkpoint.h b/include/linux/checkpoint.h
index 541bfa8..4cfd44b 100644
--- a/include/linux/checkpoint.h
+++ b/include/linux/checkpoint.h
@@ -370,7 +370,8 @@ static inline void restore_debug_free(struct ckpt_ctx *ctx) {}
 
 #endif /* CONFIG_CHECKPOINT_DEBUG */
 
-extern char *ckpt_generate_fmt(struct ckpt_ctx *ctx, char *fmt0, char *fmt);
+extern void ckpt_generate_fmt(struct ckpt_ctx *ctx, char *fmt0, char *fmt);
+static inline void ckpt_do_write_msg(struct ckpt_ctx *ctx) { }
 
 #endif /* CONFIG_CHECKPOINT */
 #endif /* __KERNEL__ */
-- 
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