[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