[CRIU] [PATCH 2/2] fifo: Add checkpoint/restore for fifos
Cyrill Gorcunov
gorcunov at openvz.org
Fri May 25 12:09:30 EDT 2012
This patch adds ability to checkpoint/restore fifo
files. Note we don't dump/restore queued data from
fifo since the fifo file might belown to completely
different process (ie not created by us), so we rather
act as on regular files.
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
Makefile | 1 +
cr-dump.c | 9 +++-
cr-restore.c | 4 ++
cr-show.c | 33 ++++++++++++
crtools.c | 1 +
fifo.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++
include/crtools.h | 2 +
include/fifo.h | 10 ++++
include/image.h | 11 ++++
9 files changed, 214 insertions(+), 2 deletions(-)
create mode 100644 fifo.c
create mode 100644 include/fifo.h
diff --git a/Makefile b/Makefile
index f99e67b..bf2a3b2 100644
--- a/Makefile
+++ b/Makefile
@@ -45,6 +45,7 @@ OBJS += sk-unix.o
OBJS += sk-queue.o
OBJS += files.o
OBJS += pipes.o
+OBJS += fifo.o
OBJS += file-ids.o
OBJS += namespaces.o
OBJS += uts_ns.o
diff --git a/cr-dump.c b/cr-dump.c
index b9b147d..ec22895 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -35,6 +35,7 @@
#include "parasite-syscall.h"
#include "files.h"
#include "pipes.h"
+#include "fifo.h"
#include "shmem.h"
#include "sk-inet.h"
#include "eventfd.h"
@@ -496,8 +497,12 @@ static int dump_one_file(pid_t pid, int fd, int lfd, char fd_flags,
S_ISDIR(p.stat.st_mode))
return dump_reg_file(&p, lfd, cr_fdset);
- if (S_ISFIFO(p.stat.st_mode) && (statfs.f_type == PIPEFS_MAGIC))
- return dump_pipe(&p, lfd, cr_fdset);
+ if (S_ISFIFO(p.stat.st_mode)) {
+ if (statfs.f_type == PIPEFS_MAGIC)
+ return dump_pipe(&p, lfd, cr_fdset);
+ else
+ return dump_fifo(&p, lfd, cr_fdset);
+ }
return dump_unsupp_fd(&p);
}
diff --git a/cr-restore.c b/cr-restore.c
index 62e84e8..f835cdc 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -34,6 +34,7 @@
#include "lock.h"
#include "files.h"
#include "pipes.h"
+#include "fifo.h"
#include "sk-inet.h"
#include "eventfd.h"
#include "eventpoll.h"
@@ -160,6 +161,9 @@ static int prepare_shared(void)
if (collect_pipes())
return -1;
+ if (collect_fifo())
+ return -1;
+
if (collect_inet_sockets())
return -1;
diff --git a/cr-show.c b/cr-show.c
index 1c766a0..c09bef2 100644
--- a/cr-show.c
+++ b/cr-show.c
@@ -61,6 +61,7 @@ static char *fdtype2s(u8 type)
[FDINFO_REG] = "reg",
[FDINFO_INETSK] = "isk",
[FDINFO_PIPE] = "pipe",
+ [FDINFO_FIFO] = "fifo",
[FDINFO_UNIXSK] = "usk",
[FDINFO_EVENTFD] = "efd",
[FDINFO_EVENTPOLL] = "epl",
@@ -216,6 +217,38 @@ out:
pr_img_tail(CR_FD_PIPES);
}
+void show_fifo(int fd, struct cr_options *o)
+{
+ struct fifo_file_entry e;
+ int ret;
+
+ pr_img_head(CR_FD_FIFO);
+
+ while (1) {
+ ret = read_img_eof(fd, &e);
+ if (ret <= 0)
+ goto out;
+ pr_msg("id: 0x%8x id: 0x%8x flags: 0x%8x ",
+ e.id, e.id, e.flags);
+ show_fown_cont(&e.fown);
+
+ if (e.len) {
+ int ret = read(fd, local_buf, e.len);
+
+ if (ret != e.len) {
+ pr_perror("Can't read %d bytes", e.len);
+ goto out;
+ }
+ local_buf[e.len] = 0;
+ pr_msg(" --> %s", local_buf);
+ }
+ pr_msg("\n");
+ }
+
+out:
+ pr_img_tail(CR_FD_FIFO);
+}
+
void show_fs(int fd_fs, struct cr_options *o)
{
struct fs_entry fe;
diff --git a/crtools.c b/crtools.c
index fc0e010..b27181d 100644
--- a/crtools.c
+++ b/crtools.c
@@ -60,6 +60,7 @@ struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX] = {
FD_ENTRY(VMAS, "vmas-%d", show_vmas),
FD_ENTRY(PIPES, "pipes", show_pipes),
FD_ENTRY(PIPES_DATA, "pipes-data", show_pipes_data),
+ FD_ENTRY(FIFO, "fifo", show_fifo),
FD_ENTRY(PSTREE, "pstree", show_pstree),
FD_ENTRY(SIGACT, "sigacts-%d", show_sigacts),
FD_ENTRY(UNIXSK, "unixsk", show_unixsk),
diff --git a/fifo.c b/fifo.c
new file mode 100644
index 0000000..23a0797
--- /dev/null
+++ b/fifo.c
@@ -0,0 +1,145 @@
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "crtools.h"
+#include "image.h"
+#include "files.h"
+#include "fifo.h"
+#include "util-net.h"
+
+static char pathbuf[PATH_MAX];
+
+struct fifo_file_info {
+ struct fifo_file_entry ffe;
+ char *path;
+ struct file_desc d;
+};
+
+static int fifo_open(struct file_desc *d)
+{
+ struct fifo_file_info *info;
+ int tmp;
+
+ info = container_of(d, struct fifo_file_info, d);
+
+ tmp = open(info->path, info->ffe.flags);
+ if (tmp < 0) {
+ pr_perror("Can't open fifo %#08x [%s]",
+ info->ffe.id, info->path);
+ return -1;
+ }
+
+ lseek(tmp, info->ffe.pos, SEEK_SET);
+
+ if (rst_file_params(tmp, &info->ffe.fown, info->ffe.flags)) {
+ pr_perror("Can't restore params on fifo %#08x",
+ info->ffe.id);
+ goto err_close;
+ }
+
+ return tmp;
+
+err_close:
+ close(tmp);
+ return -1;
+}
+
+static struct file_desc_ops fifo_desc_ops = {
+ .type = FDINFO_FIFO,
+ .open = fifo_open,
+};
+
+int collect_fifo(void)
+{
+ struct fifo_file_info *info = NULL;
+ int fd, ret = -1;
+
+ fd = open_image_ro(CR_FD_FIFO);
+ if (fd < 0)
+ return -1;
+
+ while (1) {
+ int len;
+
+ info = xzalloc(sizeof(*info));
+ if (!info) {
+ ret = -1;
+ break;
+ }
+
+ ret = read_img_eof(fd, &info->ffe);
+ if (ret <= 0)
+ break;
+
+ len = info->ffe.len;
+ info->path = xmalloc(len + 1);
+ if (!info->path) {
+ ret = -1;
+ break;
+ }
+
+ ret = read_img_buf(fd, info->path, len);
+ if (ret < 0)
+ break;
+
+ info->path[len] = '\0';
+
+ pr_info("Collected fifo [%s] ID %#x\n", info->path, info->ffe.id);
+ file_desc_add(&info->d, info->ffe.id, &fifo_desc_ops);
+ }
+
+ if (info) {
+ xfree(info->path);
+ xfree(info);
+ }
+
+ close(fd);
+
+ return ret;
+}
+
+static int dump_one_fifo(int lfd, u32 id, const struct fd_parms *p)
+{
+ struct fifo_file_entry e;
+ char fd_str[128];
+ int len, fd;
+
+ snprintf(fd_str, sizeof(fd_str), "/proc/self/fd/%d", lfd);
+ len = readlink(fd_str, pathbuf, sizeof(pathbuf) - 1);
+ if (len < 0) {
+ pr_perror("Can't readlink %s", fd_str);
+ return len;
+ }
+
+ pathbuf[len] = '\0';
+ pr_info("Dumping path for fifo %d fd via self %d [%s]\n",
+ p->fd, lfd, pathbuf);
+ pr_info("Dumping fifo %d with id %#x\n", lfd, id);
+
+ e.id = id;
+ e.flags = p->flags;
+ e.len = len;
+ e.pos = p->pos;
+ e.fown = p->fown;
+
+ fd = fdset_fd(glob_fdset, CR_FD_FIFO);
+ if (write_img(fd, &e))
+ return -1;
+ if (write_img_buf(fd, pathbuf, len))
+ return -1;
+
+ return 0;
+}
+
+static const struct fdtype_ops fifo_ops = {
+ .type = FDINFO_FIFO,
+ .make_gen_id = make_gen_id,
+ .dump = dump_one_fifo,
+};
+
+int dump_fifo(struct fd_parms *p, int lfd, const struct cr_fdset *set)
+{
+ return do_dump_gen_file(p, lfd, &fifo_ops, set);
+}
diff --git a/include/crtools.h b/include/crtools.h
index fdfb59b..be42466 100644
--- a/include/crtools.h
+++ b/include/crtools.h
@@ -55,6 +55,7 @@ enum {
CR_FD_UNIXSK,
CR_FD_PIPES,
CR_FD_PIPES_DATA,
+ CR_FD_FIFO,
CR_FD_REMAP_FPATH,
CR_FD_EVENTFD,
CR_FD_EVENTPOLL,
@@ -113,6 +114,7 @@ void show_remap_files(int fd, struct cr_options *o);
void show_ghost_file(int fd, struct cr_options *o);
void show_fown_cont(fown_t *fown);
void show_eventfds(int fd, struct cr_options *o);
+void show_fifo(int fd, struct cr_options *o);
extern void print_data(unsigned long addr, unsigned char *data, size_t size);
extern struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX];
diff --git a/include/fifo.h b/include/fifo.h
new file mode 100644
index 0000000..7a7b328
--- /dev/null
+++ b/include/fifo.h
@@ -0,0 +1,10 @@
+#ifndef CR_FIFO_H__
+#define CR_FIFO_H__
+
+#include "files.h"
+#include "crtools.h"
+
+extern int collect_fifo(void);
+extern int dump_fifo(struct fd_parms *p, int lfd, const struct cr_fdset *set);
+
+#endif /* CR_FIFO_H__ */
diff --git a/include/image.h b/include/image.h
index 3e5f36d..7fb901e 100644
--- a/include/image.h
+++ b/include/image.h
@@ -40,11 +40,13 @@
#define INOTIFY_MAGIC 0x48424431 /* Volgograd */
#define INOTIFY_WD_MAGIC 0x54562009 /* Svetlogorsk (Rauschen) */
#define MOUNTPOINTS_MAGIC 0x55563928 /* Petushki */
+#define FIFO_MAGIC 0x59443036 /* Kolpino */
enum fd_types {
FDINFO_UND,
FDINFO_REG,
FDINFO_PIPE,
+ FDINFO_FIFO,
FDINFO_INETSK,
FDINFO_UNIXSK,
FDINFO_EVENTFD,
@@ -66,6 +68,15 @@ typedef struct {
u32 pid;
} __packed fown_t;
+struct fifo_file_entry {
+ u32 id;
+ u16 flags;
+ u16 len;
+ u64 pos;
+ fown_t fown;
+ u8 name[0];
+} __packed;
+
struct reg_file_entry {
u32 id;
u16 flags;
--
1.7.7.6
More information about the CRIU
mailing list