[CRIU] [PATCH] pages: Share page_ids between ns dump-helpers

Pavel Emelyanov xemul at virtuozzo.com
Fri Jun 30 09:40:48 MSK 2017


On 06/29/2017 11:09 PM, Dmitry Safonov wrote:
> After the commit 9d2e1dfebedf ("ipc: Keep shmem segments contents into
> pagemap/page images"), SysV shmem pages are stored in the pages-<n>.img
> files.  Where <n> is page_ids number.
> 
> The problem here is that we dump namespaces with a helper after fork().
> This results in non-shared between child(s) and parent-criu counter
> with the result of overwriting pages-*.img files later by helpers/criu.
> This resulted in restore with corrupted shmem segments or
> in the following failures on restore:
>> (04.501019)      1: Error (criu/pagemap.c:265): Can't read mapping page 0: No such file or directory
>> (04.637516)      1: Error (criu/pagemap.c:265): Can't read mapping page 0: No such file or directory
> 
> Allocate page_ids with shmalloc() and make it atomic.
> As we need it in pre-dump, dump, page-server and rpc,
> init it early in the main().
> 
> Cc: Pavel Emelyanov <xemul at virtuozzo.com>
> Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>

Acked-by: Pavel Emelyanov <xemul at virtuozzo.com>

> ---
>  criu/crtools.c       |  3 +++
>  criu/image.c         | 25 +++++++++++++++++++++----
>  criu/include/image.h |  2 ++
>  3 files changed, 26 insertions(+), 4 deletions(-)
> 
> diff --git a/criu/crtools.c b/criu/crtools.c
> index b0f7b946cc56..a3dbbcb10668 100644
> --- a/criu/crtools.c
> +++ b/criu/crtools.c
> @@ -325,6 +325,9 @@ int main(int argc, char *argv[], char *envp[])
>  	if (fault_injection_init())
>  		return 1;
>  
> +	if (images_init())
> +		return 1;
> +
>  	cr_pb_init();
>  	setproctitle_init(argc, argv, envp);
>  
> diff --git a/criu/image.c b/criu/image.c
> index 62e8e7109e65..59b9dad5458d 100644
> --- a/criu/image.c
> +++ b/criu/image.c
> @@ -17,6 +17,7 @@
>  #include "images/inventory.pb-c.h"
>  #include "images/pagemap.pb-c.h"
>  #include "img-remote.h"
> +#include "rst-malloc.h"
>  
>  bool ns_per_id = false;
>  bool img_common_magic = true;
> @@ -505,7 +506,23 @@ void close_image_dir(void)
>  	close_service_fd(IMG_FD_OFF);
>  }
>  
> -static unsigned long page_ids = 1;
> +/*
> + * As we dump SysV shmem IPC into pages-<page_ids>.img,
> + * the keys should be shared in each dump ns-helpers and in criu.
> + */
> +static atomic_t *page_ids;
> +
> +int images_init(void)
> +{
> +	page_ids = shmalloc(sizeof(*page_ids));
> +	if (!page_ids) {
> +		pr_err("Failed to shmalloc page_ids\n");
> +		return -1;
> +	}
> +	atomic_set(page_ids, 1);
> +
> +	return 0;
> +}
>  
>  void up_page_ids_base(void)
>  {
> @@ -517,8 +534,8 @@ void up_page_ids_base(void)
>  	 * higher IDs.
>  	 */
>  
> -	BUG_ON(page_ids != 1);
> -	page_ids += 0x10000;
> +	BUG_ON(atomic_read(page_ids) != 1);
> +	atomic_add(0x10000, page_ids);
>  }
>  
>  struct cr_img *open_pages_image_at(int dfd, unsigned long flags, struct cr_img *pmi, u32 *id)
> @@ -531,7 +548,7 @@ struct cr_img *open_pages_image_at(int dfd, unsigned long flags, struct cr_img *
>  		pagemap_head__free_unpacked(h, NULL);
>  	} else {
>  		PagemapHead h = PAGEMAP_HEAD__INIT;
> -		*id = h.pages_id = page_ids++;
> +		*id = h.pages_id = atomic_inc_return(page_ids);
>  		if (pb_write_one(pmi, &h, PB_PAGEMAP_HEAD) < 0)
>  			return NULL;
>  	}
> diff --git a/criu/include/image.h b/criu/include/image.h
> index d9c4bdbc8da4..60e44297a858 100644
> --- a/criu/include/image.h
> +++ b/criu/include/image.h
> @@ -170,4 +170,6 @@ extern int read_img_str(struct cr_img *, char **pstr, int size);
>  
>  extern void close_image(struct cr_img *);
>  
> +extern int images_init(void);
> +
>  #endif /* __CR_IMAGE_H__ */
> 



More information about the CRIU mailing list