[Devel] [RFC v14][PATCH 54/54] Report failures during checkpoint as an object in the output stream
Oren Laadan
orenl at cs.columbia.edu
Tue Apr 28 16:24:24 PDT 2009
One way to provide some meaningful information about the reason for
which a checkpoint failed, is to write the information as a regular
record to the output stream.
Specifically, if an error is detected, then we write a special 'struct
ckpt_hdr_error' record to the output file, followed by a string that
describes the details of why the checkpoint failed.
Signed-off-by: Oren Laadan <orenl at cs.columbia.edu>
---
checkpoint/checkpoint.c | 55 ++++++++++++++++++++++++++++++++++++++-
include/linux/checkpoint_hdr.h | 10 ++++++-
2 files changed, 62 insertions(+), 3 deletions(-)
diff --git a/checkpoint/checkpoint.c b/checkpoint/checkpoint.c
index 32a0a8e..7f5c18c 100644
--- a/checkpoint/checkpoint.c
+++ b/checkpoint/checkpoint.c
@@ -95,6 +95,50 @@ int ckpt_write_string(struct ckpt_ctx *ctx, char *str, int len)
return ckpt_write_obj_type(ctx, str, len, CKPT_HDR_STRING);
}
+/**
+ * ckpt_write_err - write an object describing an error
+ * @ctx: checkpoint context
+ * @fmt: error string format
+ * @...: error string arguments
+ */
+int ckpt_write_err(struct ckpt_ctx *ctx, char *fmt, ...)
+{
+ va_list args;
+ char str[128];
+ char *ptr = NULL;
+ int len, ret;
+
+ ret = ckpt_write_obj_type(ctx, NULL, sizeof(struct ckpt_hdr),
+ CKPT_HDR_ERROR);
+ if (ret < 0)
+ return ret;
+
+ va_start(args, fmt);
+ len = vsnprintf(str, 128, fmt, args) + 1;
+ va_end(args);
+
+ if (len > 128) {
+ /* doesn't fit on stack, allocate memory */
+ ptr = kmalloc(len + 1, GFP_KERNEL);
+ /* if malloc failed, fallback to truncated string */
+ if (ptr) {
+ va_start(args, fmt);
+ len = vsnprintf(ptr, len, fmt, args) + 1;
+ va_end(args);
+ } else {
+ len = 128;
+ printk(KERN_NOTICE "c/r: error message truncated\n");
+ }
+ }
+
+ ckpt_debug("c/r: checkpoint error: %s\n", ptr ? : str);
+ ret = ckpt_write_string(ctx, ptr ? : str, len);
+
+ kfree(ptr);
+ return ret;
+}
+
+
/***********************************************************************
* Checkpoint
*/
@@ -198,8 +242,11 @@ static int may_checkpoint_task(struct task_struct *t, struct ckpt_ctx *ctx)
return -EPERM;
/* verify that the task is frozen (unless self) */
- if (t != current && !frozen(t))
+ if (t != current && !frozen(t)) {
+ ckpt_write_err(ctx, "task %d(%s) not frozen\n",
+ task_pid_vnr(t), t->comm);
return -EBUSY;
+ }
/* FIX: add support for ptraced tasks */
if (task_ptrace(t))
@@ -436,8 +483,11 @@ static int get_container(struct ckpt_ctx *ctx, pid_t pid)
ctx->root_init = is_container_init(task);
/* FIX: does this error code makes sense here ? */
- if (!(ctx->flags & CHECKPOINT_SUBTREE) && !ctx->root_init)
+ if (!(ctx->flags & CHECKPOINT_SUBTREE) && !ctx->root_init) {
+ ckpt_write_err(ctx, "task %d(%s) not container init\n",
+ task_pid_vnr(task), task->comm);
return -EBUSY;
+ }
return 0;
@@ -501,6 +551,7 @@ int do_checkpoint(struct ckpt_ctx *ctx, pid_t pid)
if (!(ctx->flags & CHECKPOINT_SUBTREE)) {
/* verify that all objects are contained (no leaks) */
if (!ckpt_obj_contained(ctx)) {
+ ckpt_write_err(ctx, "container is not isolated\n");
ret = -EBUSY;
goto out;
}
diff --git a/include/linux/checkpoint_hdr.h b/include/linux/checkpoint_hdr.h
index 0e15f3f..058412c 100644
--- a/include/linux/checkpoint_hdr.h
+++ b/include/linux/checkpoint_hdr.h
@@ -73,9 +73,17 @@ enum {
CKPT_HDR_IPC_MSG_MSG,
CKPT_HDR_IPC_SEM,
- CKPT_HDR_TAIL = 5001
+ CKPT_HDR_TAIL = 5001,
+
+ CKPT_HDR_ERROR = 9999
};
+/* error report */
+struct ckpt_hdr_error {
+ struct ckpt_hdr h;
+ /* followed by the error string */
+} __attribute__((aligned(8)));
+
/* shared objrects (objref) */
struct ckpt_hdr_objref {
struct ckpt_hdr h;
--
1.5.4.3
_______________________________________________
Containers mailing list
Containers at lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers
More information about the Devel
mailing list