[CRIU] [PATCH 09/28] dump: add dump of regular files entries
Kinsbursky Stanislav
skinsbursky at openvz.org
Thu Mar 22 13:58:31 EDT 2012
From: Stanislav Kinsbursky <skinsbursky at openvz.org>
Signed-off-by: Stanislav Kinsbursky <skinsbursky at openvz.org>
---
cr-dump.c | 50 +++++++++++++++++++++++++++++++++++---------------
cr-show.c | 33 +++++++++++++++++++++++++++++++++
crtools.c | 6 ++++++
include/crtools.h | 4 ++++
include/image.h | 1 +
5 files changed, 79 insertions(+), 15 deletions(-)
-------------- next part --------------
diff --git a/cr-dump.c b/cr-dump.c
index 912bb94..5c2c84f 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -87,21 +87,22 @@ err:
return ret;
}
-static int dump_one_reg_file(const struct file_entry *p, pid_t pid,
+static int dump_one_reg_file(struct file_entry *p, pid_t pid,
int lfd, unsigned long target_fd,
const struct cr_fdset *cr_fdset,
bool do_close_lfd)
{
- struct fdinfo_entry e;
+ struct fdinfo_entry e = { };
char fd_str[128];
int len;
int ret = -1;
+ struct fd_entry *fde = &e.fde;
snprintf(fd_str, sizeof(fd_str), "/proc/self/fd/%d", lfd);
len = readlink(fd_str, big_buffer, sizeof(big_buffer) - 1);
if (len < 0) {
pr_perror("Can't readlink %s", fd_str);
- goto err;
+ return -1;
}
big_buffer[len] = '\0';
@@ -116,33 +117,46 @@ static int dump_one_reg_file(const struct file_entry *p, pid_t pid,
e.pos = p->pos;
e.addr = target_fd;
- e.fde.type = p->type;
- e.fde.fd = (u32)target_fd;
- e.fde.id = FD_ID_INVALID;
+ fde->type = p->type;
+ fde->fd = (u32)target_fd;
+ fde->id = FD_ID_INVALID;
- if (likely(!fd_is_special(&e.fde))) {
+ if (likely(!fd_is_special(fde))) {
u8 new;
long id;
id = file_collect(pid, target_fd, p, &new);
if (id < 0)
- goto err;
+ return id;
/* Now it might have completely new ID here */
- e.fde.id = id;
+ fde->id = id;
+
+ if (new) {
+ p->len = len;
+
+ pr_info("Dumping regular file: id %ld, pos %ld, "
+ "flags 0x%x, len %d",
+ p->id, p->pos, p->flags, p->len);
+ if (p->len)
+ pr_info(" --> %s", big_buffer);
+ pr_info("\n");
+
+ if (write_img(cr_fdset->fds[CR_FD_REG_FILES], p))
+ return -1;
+ if (write_img_buf(cr_fdset->fds[CR_FD_REG_FILES], big_buffer, len))
+ return -1;
+ }
}
pr_info("fdinfo: type: %2x len: %2x flags: %4x pos: %8lx addr: %16lx\n",
p->type, len, p->flags, p->pos, target_fd);
if (write_img(cr_fdset->fds[CR_FD_FDINFO], &e))
- goto err;
+ return -1;
if (write_img_buf(cr_fdset->fds[CR_FD_FDINFO], big_buffer, e.len))
- goto err;
-
- ret = 0;
-err:
- return ret;
+ return -1;
+ return 0;
}
static int dump_task_special_files(pid_t pid, const struct cr_fdset *cr_fdset)
@@ -1453,6 +1467,9 @@ static int unlink_global_image_files(void)
snprintf(path, PATH_MAX, fdset_template[CR_FD_SK_QUEUES].fmt);
if (unlinkat(image_dir_fd, path, 0) && errno != ENOENT)
goto err;
+ snprintf(path, PATH_MAX, fdset_template[CR_FD_REG_FILES].fmt);
+ if (unlinkat(image_dir_fd, path, 0) && errno != ENOENT)
+ goto err;
return 0;
err:
@@ -1505,6 +1522,9 @@ int cr_dump_tasks(pid_t pid, const struct cr_options *opts)
if (!cr_fdset)
goto err;
+ if (!cr_glob_fdset_open(CR_FD_DESC_REG_FILES, cr_fdset))
+ goto err;
+
/*
* Prepare for socket queues in advance. They are not per-task,
* but per-someother-task which makes restore tricky. Thus save
diff --git a/cr-show.c b/cr-show.c
index ae99e48..4a016dc 100644
--- a/cr-show.c
+++ b/cr-show.c
@@ -88,6 +88,36 @@ out:
pr_img_tail(CR_FD_FDINFO);
}
+static void show_reg_files(int fd_files)
+{
+ struct file_entry e;
+
+ pr_img_head(CR_FD_REG_FILES);
+
+ while (1) {
+ int ret;
+
+ ret = read_img_eof(fd_files, &e);
+ if (ret <= 0)
+ break;
+
+ pr_msg("type %02d id: %20ld pos: %16lx len: %02x flags: %4x",
+ e.type, e.id, e.pos, e.len, e.flags);
+
+ if (e.len) {
+ int ret = read(fd_files, local_buf, e.len);
+ if (ret != e.len) {
+ pr_perror("Can't read %d bytes", e.len);
+ break;
+ }
+ local_buf[e.len] = 0;
+ pr_msg(" --> %s", local_buf);
+ }
+ pr_msg("\n");
+ }
+ pr_img_tail(CR_FD_REG_FILES);
+}
+
static void show_pipes(int fd_pipes)
{
struct pipe_entry e;
@@ -505,6 +535,9 @@ static int cr_parse_file(struct cr_options *opts)
case IPCNS_SEM_MAGIC:
show_ipc_sem(fd);
break;
+ case REG_FILES_MAGIC:
+ show_reg_files(fd);
+ break;
default:
pr_err("Unknown magic %x on %s\n", magic, opts->show_dump_file);
goto err;
diff --git a/crtools.c b/crtools.c
index 6f067c0..1326d25 100644
--- a/crtools.c
+++ b/crtools.c
@@ -138,6 +138,12 @@ struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX] = {
.fmt = FMT_FNAME_IPCNS_SEM,
.magic = IPCNS_SEM_MAGIC,
},
+
+ /* Regular files */
+ [CR_FD_REG_FILES] = {
+ .fmt = FMT_FNAME_REG_FILES,
+ .magic = REG_FILES_MAGIC,
+ },
};
static struct cr_fdset *alloc_cr_fdset(void)
diff --git a/include/crtools.h b/include/crtools.h
index 9b39c91..e03fbbd 100644
--- a/include/crtools.h
+++ b/include/crtools.h
@@ -43,6 +43,8 @@ enum {
CR_FD_SK_QUEUES,
+ CR_FD_REG_FILES,
+
CR_FD_PID_MAX, /* fmt, pid */
CR_FD_SHMEM_PAGES,
@@ -92,6 +94,7 @@ extern struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX];
#define FMT_FNAME_IPCNS_MSG "ipcns-msg-%d.img"
#define FMT_FNAME_IPCNS_SEM "ipcns-sem-%d.img"
#define FMT_FNAME_SK_QUEUES "sk-queues.img"
+#define FMT_FNAME_REG_FILES "reg-files.img"
/*
* FIXME -- this is required for legacy image copy only.
@@ -119,6 +122,7 @@ struct cr_fdset {
#define CR_FD_DESC_CORE CR_FD_DESC_USE(CR_FD_CORE)
#define CR_FD_DESC_PSTREE CR_FD_DESC_USE(CR_FD_PSTREE)
#define CR_FD_DESC_SK_QUEUES CR_FD_DESC_USE(CR_FD_SK_QUEUES)
+#define CR_FD_DESC_REG_FILES CR_FD_DESC_USE(CR_FD_REG_FILES)
#define CR_FD_DESC_TASK (\
CR_FD_DESC_USE(CR_FD_FDINFO) |\
CR_FD_DESC_USE(CR_FD_PAGES) |\
diff --git a/include/image.h b/include/image.h
index 5b76a67..4b42226 100644
--- a/include/image.h
+++ b/include/image.h
@@ -26,6 +26,7 @@
#define IPCNS_SHM_MAGIC 0x46283044 /* Odessa */
#define IPCNS_MSG_MAGIC 0x55453737 /* Moscow */
#define IPCNS_SEM_MAGIC 0x59573019 /* St. Petersburg */
+#define REG_FILES_MAGIC 0x56194400 /* N. Novgorod */
#define PIPEFS_MAGIC 0x50495045
More information about the CRIU
mailing list