[Devel] [PATCH 7/9] cr: checkpoint saved_auxv as u64s
serue at us.ibm.com
serue at us.ibm.com
Mon Feb 8 18:00:04 PST 2010
From: Serge E. Hallyn <serue at us.ibm.com>
unsigned longs are not a good value to checkpoint between
x86-32 and x86-64 32-bit tasks :)
Signed-off-by: Serge E. Hallyn <serue at us.ibm.com>
---
checkpoint/checkpoint.c | 5 +--
checkpoint/memory.c | 53 +++++++++++++++++++++++++++++++++++++--
checkpoint/restart.c | 6 ++--
include/linux/checkpoint_hdr.h | 2 +-
4 files changed, 56 insertions(+), 10 deletions(-)
diff --git a/checkpoint/checkpoint.c b/checkpoint/checkpoint.c
index b4e0021..b3c1c4f 100644
--- a/checkpoint/checkpoint.c
+++ b/checkpoint/checkpoint.c
@@ -103,13 +103,12 @@ int ckpt_write_string(struct ckpt_ctx *ctx, char *str, int len)
static void fill_kernel_const(struct ckpt_const *h)
{
struct task_struct *tsk;
- struct mm_struct *mm;
struct new_utsname *uts;
/* task */
h->task_comm_len = sizeof(tsk->comm);
- /* mm */
- h->mm_saved_auxv_len = sizeof(mm->saved_auxv);
+ /* mm->saved_auxv size */
+ h->at_vector_size = AT_VECTOR_SIZE;
/* signal */
h->signal_nsig = _NSIG;
/* uts */
diff --git a/checkpoint/memory.c b/checkpoint/memory.c
index d51f94b..5058ab3 100644
--- a/checkpoint/memory.c
+++ b/checkpoint/memory.c
@@ -661,6 +661,25 @@ static int checkpoint_vmas(struct ckpt_ctx *ctx, struct mm_struct *mm)
return ret < 0 ? ret : map_count;
}
+#define CKPT_AT_SZ (AT_VECTOR_SIZE * sizeof(u64))
+/*
+ * We always write saved_auxv out as an array of u64s, though it is
+ * an array of u32s on 32-bit arch.
+ */
+static int ckpt_write_auxv(struct ckpt_ctx *ctx, struct mm_struct *mm)
+{
+ int i, ret;
+ u64 *buf = kzalloc(CKPT_AT_SZ, GFP_KERNEL);
+
+ if (!buf)
+ return -ENOMEM;
+ for (i=0; i<AT_VECTOR_SIZE; i++)
+ buf[i] = mm->saved_auxv[i];
+ ret = ckpt_write_buffer(ctx, buf, CKPT_AT_SZ);
+ kfree(buf);
+ return ret;
+}
+
static int do_checkpoint_mm(struct ckpt_ctx *ctx, struct mm_struct *mm)
{
struct ckpt_hdr_mm *h;
@@ -718,7 +737,7 @@ static int do_checkpoint_mm(struct ckpt_ctx *ctx, struct mm_struct *mm)
if (ret < 0)
goto out;
- ret = ckpt_write_buffer(ctx, mm->saved_auxv, sizeof(mm->saved_auxv));
+ ret = ckpt_write_auxv(ctx, mm);
if (ret < 0)
return ret;
@@ -1205,6 +1224,32 @@ static int restore_vma(struct ckpt_ctx *ctx, struct mm_struct *mm)
return ret;
}
+static int ckpt_read_auxv(struct ckpt_ctx *ctx, struct mm_struct *mm)
+{
+ int i, ret;
+ u64 *buf = kmalloc(CKPT_AT_SZ, GFP_KERNEL);
+
+ if (!buf)
+ return -ENOMEM;
+ ret = _ckpt_read_buffer(ctx, buf, CKPT_AT_SZ);
+ if (ret < 0) {
+ kfree(buf);
+ return ret;
+ }
+
+ for (i=0; i<AT_VECTOR_SIZE; i++)
+ if (buf[i] > (u64) ULONG_MAX) {
+ kfree(buf);
+ return -E2BIG;
+ }
+
+ for (i=0; i<AT_VECTOR_SIZE; i++)
+ mm->saved_auxv[i] = buf[i];
+
+ kfree(buf);
+ return 0;
+}
+
static struct mm_struct *do_restore_mm(struct ckpt_ctx *ctx)
{
struct ckpt_hdr_mm *h;
@@ -1270,9 +1315,11 @@ static struct mm_struct *do_restore_mm(struct ckpt_ctx *ctx)
}
up_write(&mm->mmap_sem);
- ret = _ckpt_read_buffer(ctx, mm->saved_auxv, sizeof(mm->saved_auxv));
- if (ret < 0)
+ ret = ckpt_read_auxv(ctx, mm);
+ if (ret < 0) {
+ ckpt_err(ctx, ret, "Error restoring auxv\n");
goto out;
+ }
for (nr = h->map_count; nr; nr--) {
ret = restore_vma(ctx, mm);
diff --git a/checkpoint/restart.c b/checkpoint/restart.c
index 9bb17fc..a5f30f2 100644
--- a/checkpoint/restart.c
+++ b/checkpoint/restart.c
@@ -552,15 +552,15 @@ int ckpt_read_consume(struct ckpt_ctx *ctx, int len, int type)
static int check_kernel_const(struct ckpt_const *h)
{
struct task_struct *tsk;
- struct mm_struct *mm;
struct new_utsname *uts;
/* task */
if (h->task_comm_len != sizeof(tsk->comm))
return -EINVAL;
- /* mm */
- if (h->mm_saved_auxv_len != sizeof(mm->saved_auxv))
+ /* mm->saved_auxv size */
+ if (h->at_vector_size != AT_VECTOR_SIZE)
return -EINVAL;
+
/* signal */
if (h->signal_nsig != _NSIG)
return -EINVAL;
diff --git a/include/linux/checkpoint_hdr.h b/include/linux/checkpoint_hdr.h
index 5a68178..b5dd95c 100644
--- a/include/linux/checkpoint_hdr.h
+++ b/include/linux/checkpoint_hdr.h
@@ -262,7 +262,7 @@ struct ckpt_const {
/* task */
__u16 task_comm_len;
/* mm */
- __u16 mm_saved_auxv_len;
+ __u16 at_vector_size;
/* signal */
__u16 signal_nsig;
/* uts */
--
1.6.0.4
_______________________________________________
Containers mailing list
Containers at lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers
More information about the Devel
mailing list