[CRIU] [PATCH] ipc: Fix huge ipcshm segments data dump/restore
Andrei Vagin
avagin at virtuozzo.com
Mon Mar 6 09:14:24 PST 2017
Applied, thanks!
On Mon, Mar 06, 2017 at 11:01:30AM +0300, Pavel Emelyanov wrote:
> 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 at virtuozzo.com>
> ---
> criu/image-desc.c | 2 +-
> criu/ipc_ns.c | 53 +++++++++++++++++++++++++++++++++++++++++------------
> 2 files changed, 42 insertions(+), 13 deletions(-)
>
> diff --git a/criu/image-desc.c b/criu/image-desc.c
> index 71fae9e..3394300 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 c9468d8..af1cb7c 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;
> --
> 2.5.5
>
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
More information about the CRIU
mailing list