Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/checkpoint-restore/criu.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@virtuozzo.com>2017-03-06 11:01:30 +0300
committerPavel Emelyanov <xemul@virtuozzo.com>2017-03-07 18:14:51 +0300
commit2aa9b4f27d36f69851ad7186edc9d89cd4aaf96b (patch)
treee8fe6c8221c99051ed3b857e744e01fe94f61a7b
parentd5df3bf2acd65946149c838917e6f1cce2bd4183 (diff)
ipc: Fix huge ipcshm segments data dump/restore
The ipcns-shm images are buffered and contain raw dumps of memory contents. If the segment is huge, the bfd engine overflows and doesn't write data into image. This is not nice by itself, but huge images shouldn't use bfd to avoid double buffering. Also, in the future, this image should be fixed not to keep mem dumps in one image with object. https://github.com/xemul/criu/issues/287 Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com> Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
-rw-r--r--criu/image-desc.c2
-rw-r--r--criu/ipc_ns.c53
2 files changed, 42 insertions, 13 deletions
diff --git a/criu/image-desc.c b/criu/image-desc.c
index bac7ca276..5e5224b13 100644
--- a/criu/image-desc.c
+++ b/criu/image-desc.c
@@ -60,7 +60,7 @@ struct cr_fd_desc_tmpl imgset_template[CR_FD_MAX] = {
FD_ENTRY(CREDS, "creds-%d"),
FD_ENTRY(UTSNS, "utsns-%d"),
FD_ENTRY(IPC_VAR, "ipcns-var-%d"),
- FD_ENTRY(IPCNS_SHM, "ipcns-shm-%d"),
+ FD_ENTRY_F(IPCNS_SHM, "ipcns-shm-%d", O_NOBUF), /* writes segments of data */
FD_ENTRY(IPCNS_MSG, "ipcns-msg-%d"),
FD_ENTRY(IPCNS_SEM, "ipcns-sem-%d"),
FD_ENTRY(FS, "fs-%d"),
diff --git a/criu/ipc_ns.c b/criu/ipc_ns.c
index c9468d8ce..af1cb7c06 100644
--- a/criu/ipc_ns.c
+++ b/criu/ipc_ns.c
@@ -345,18 +345,36 @@ static int ipc_sysctl_req(IpcVarEntry *e, int op)
static int dump_ipc_shm_pages(struct cr_img *img, const IpcShmEntry *shm)
{
void *data;
- int ret;
+ int ifd;
+ ssize_t size, off;
data = shmat(shm->desc->id, NULL, SHM_RDONLY);
if (data == (void *)-1) {
pr_perror("Failed to attach IPC shared memory");
return -errno;
}
- ret = write_img_buf(img, data, round_up(shm->size, sizeof(u32)));
- if (ret < 0) {
- pr_err("Failed to write IPC shared memory data\n");
- return ret;
- }
+
+ /*
+ * FIXME -- this just write the whole memory segment into the
+ * image. In case the segment is huge this takes time. Need
+ * to adopt the holes detection code (next_data_segment) from
+ * shmem.c
+ */
+ ifd = img_raw_fd(img);
+ size = round_up(shm->size, sizeof(u32));
+ off = 0;
+ do {
+ ssize_t ret;
+
+ ret = write(ifd, data + off, size - off);
+ if (ret <= 0) {
+ pr_perror("Failed to write IPC shared memory data");
+ return (int)ret;
+ }
+
+ off += ret;
+ } while (off < size);
+
if (shmdt(data)) {
pr_perror("Failed to detach IPC shared memory");
return -errno;
@@ -761,19 +779,30 @@ err:
static int prepare_ipc_shm_pages(struct cr_img *img, const IpcShmEntry *shm)
{
- int ret;
void *data;
+ int ifd;
+ ssize_t size, off;
data = shmat(shm->desc->id, NULL, 0);
if (data == (void *)-1) {
pr_perror("Failed to attach IPC shared memory");
return -errno;
}
- ret = read_img_buf(img, data, round_up(shm->size, sizeof(u32)));
- if (ret < 0) {
- pr_err("Failed to read IPC shared memory data\n");
- return ret;
- }
+
+ ifd = img_raw_fd(img);
+ size = round_up(shm->size, sizeof(u32));
+ off = 0;
+ do {
+ ssize_t ret;
+
+ ret = read(ifd, data + off, size - off);
+ if (ret <= 0) {
+ pr_perror("Failed to write IPC shared memory data");
+ return (int)ret;
+ }
+
+ off += ret;
+ } while (off < size);
if (shmdt(data)) {
pr_perror("Failed to detach IPC shared memory");
return -errno;