[Devel] [PATCH] [RFC] Checkpoint/restart eventfd
Matt Helsley
matthltc at us.ibm.com
Sat Oct 24 22:13:10 PDT 2009
Save/restore eventfd files. These are anon_inodes just like epoll
but instead of a set of files to poll they are a 64-bit counter
and a flag value. Used for AIO.
Signed-off-by: Matt Helsley <matthltc at us.ibm.com>
NOTE: Marked [RFC] because it strangely does not pass my adapted LTP
test cases unless it's running from a checkpointed image.
Seems to be a mistake in the test case adaptation.
---
checkpoint/files.c | 7 +++++
fs/eventfd.c | 51 ++++++++++++++++++++++++++++++++++++++++
include/linux/checkpoint_hdr.h | 8 ++++++
include/linux/eventfd.h | 10 ++++++++
4 files changed, 76 insertions(+), 0 deletions(-)
diff --git a/checkpoint/files.c b/checkpoint/files.c
index f6de07e..43b95cc 100644
--- a/checkpoint/files.c
+++ b/checkpoint/files.c
@@ -23,6 +23,7 @@
#include <linux/checkpoint.h>
#include <linux/checkpoint_hdr.h>
#include <net/sock.h>
+#include <linux/eventfd.h>
/**************************************************************************
@@ -607,6 +608,12 @@ static struct restore_file_ops restore_file_ops[] = {
.file_type = CKPT_FILE_TTY,
.restore = tty_file_restore,
},
+ /* eventfd */
+ {
+ .file_name = "EVENTFD",
+ .file_type = CKPT_FILE_EVENTFD,
+ .restore = eventfd_restore,
+ },
};
static struct file *do_restore_file(struct ckpt_ctx *ctx)
diff --git a/fs/eventfd.c b/fs/eventfd.c
index 31d12de..5d30cd5 100644
--- a/fs/eventfd.c
+++ b/fs/eventfd.c
@@ -18,6 +18,8 @@
#include <linux/module.h>
#include <linux/kref.h>
#include <linux/eventfd.h>
+#include <linux/checkpoint.h>
+#include <linux/checkpoint_hdr.h>
struct eventfd_ctx {
struct kref kref;
@@ -223,11 +225,34 @@ static ssize_t eventfd_write(struct file *file, const char __user *buf, size_t c
return res;
}
+static int eventfd_checkpoint(struct ckpt_ctx *ckpt_ctx, struct file *file)
+{
+ struct eventfd_ctx *ctx;
+ struct ckpt_hdr_file_eventfd *h;
+ int ret = -ENOMEM;
+
+ h = ckpt_hdr_get_type(ckpt_ctx, sizeof(*h), CKPT_HDR_FILE);
+ if (!h)
+ return -ENOMEM;
+ h->common.f_type = CKPT_FILE_EVENTFD;
+ ret = checkpoint_file_common(ckpt_ctx, file, &h->common);
+ if (ret < 0)
+ goto out;
+ ctx = file->private_data;
+ h->count = ctx->count;
+ h->flags = ctx->flags;
+ ret = ckpt_write_obj(ckpt_ctx, &h->common.h);
+out:
+ ckpt_hdr_put(ckpt_ctx, h);
+ return ret;
+}
+
static const struct file_operations eventfd_fops = {
.release = eventfd_release,
.poll = eventfd_poll,
.read = eventfd_read,
.write = eventfd_write,
+ .checkpoint = eventfd_checkpoint,
};
/**
@@ -335,3 +360,29 @@ SYSCALL_DEFINE1(eventfd, unsigned int, count)
return sys_eventfd2(count, 0);
}
+struct file *eventfd_restore(struct ckpt_ctx *ckpt_ctx,
+ struct ckpt_hdr_file *ptr)
+{
+ struct ckpt_hdr_file_eventfd *h = (struct ckpt_hdr_file_eventfd *)ptr;
+ struct file *evfile;
+ int evfd, ret;
+
+ /* Already know type == CKPT_HDR_FILE and f_type == CKPT_FILE_EVENTFD */
+ if (h->common.h.len != sizeof(*h))
+ return ERR_PTR(-EINVAL);
+
+ evfd = sys_eventfd2(h->count, h->flags);
+ if (evfd < 0)
+ return ERR_PTR(evfd);
+ evfile = fget(evfd);
+ sys_close(evfd);
+ if (!evfile)
+ return ERR_PTR(-EBUSY);
+
+ ret = restore_file_common(ckpt_ctx, evfile, &h->common);
+ if (ret < 0) {
+ fput(evfile);
+ return ERR_PTR(ret);
+ }
+ return evfile;
+}
diff --git a/include/linux/checkpoint_hdr.h b/include/linux/checkpoint_hdr.h
index ff2e4aa..dc22244 100644
--- a/include/linux/checkpoint_hdr.h
+++ b/include/linux/checkpoint_hdr.h
@@ -476,6 +476,8 @@ enum file_type {
#define CKPT_FILE_SOCKET CKPT_FILE_SOCKET
CKPT_FILE_TTY,
#define CKPT_FILE_TTY CKPT_FILE_TTY
+ CKPT_FILE_EVENTFD,
+#define CKPT_FILE_EVENTFD CKPT_FILE_EVENTFD
CKPT_FILE_MAX
#define CKPT_FILE_MAX CKPT_FILE_MAX
};
@@ -500,6 +502,12 @@ struct ckpt_hdr_file_pipe {
__s32 pipe_objref;
} __attribute__((aligned(8)));
+struct ckpt_hdr_file_eventfd {
+ struct ckpt_hdr_file common;
+ __u64 count;
+ __u32 flags;
+} __attribute__((aligned(8)));
+
/* socket */
struct ckpt_hdr_socket {
struct ckpt_hdr h;
diff --git a/include/linux/eventfd.h b/include/linux/eventfd.h
index 3b85ba6..a904633 100644
--- a/include/linux/eventfd.h
+++ b/include/linux/eventfd.h
@@ -34,6 +34,15 @@ struct eventfd_ctx *eventfd_ctx_fdget(int fd);
struct eventfd_ctx *eventfd_ctx_fileget(struct file *file);
int eventfd_signal(struct eventfd_ctx *ctx, int n);
+#ifdef CONFIG_CHECKPOINT
+struct ckpt_ctx;
+struct ckpt_hdr_file;
+
+struct file *eventfd_restore(struct ckpt_ctx *ckpt_ctx,
+ struct ckpt_hdr_file *ptr);
+#else
+#define eventfd_restore NULL
+#endif
#else /* CONFIG_EVENTFD */
/*
@@ -55,6 +64,7 @@ static inline void eventfd_ctx_put(struct eventfd_ctx *ctx)
}
+#define eventfd_restore NULL
#endif
#endif /* _LINUX_EVENTFD_H */
--
1.5.6.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