[CRIU] Re: [PATCH cr 08/16] restore: don't unmap premmapped private vma-s

Pavel Emelyanov xemul at parallels.com
Tue Oct 30 12:32:07 EDT 2012


> @@ -231,6 +233,23 @@ static int map_private_vma(pid_t pid, struct vma_area *vma, void *tgt_addr,
>  	return 0;
>  }
>  
> +/* Prevent merging vma-s outside and inside the premmapped region */

Why? Besides, having two guard pages doesn't prevent vmas from being merged.

> +static int unmap_priv_guard_pages()
> +{
> +	if (munmap(premmapped_addr, PAGE_SIZE)) {
> +		pr_perror("Could not unmap a guard page %p", premmapped_addr);
> +		return -1;
> +	}
> +
> +	if (munmap(premmapped_addr + premmapped_len - PAGE_SIZE, PAGE_SIZE)) {
> +		pr_perror("Could not unmap a guard page %p",
> +				premmapped_addr + premmapped_len);
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
>  static int read_vmas(int pid)
>  {
>  	int fd, ret = 0;
> @@ -280,13 +299,26 @@ static int read_vmas(int pid)
>  		priv_size += vma_area_len(vma);
>  	}
>  
> -	/* Reserve a place for mapping private vma-s one by one */
> -	addr = mmap(NULL, priv_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
> +	/*
> +	 * Reserve a place for mapping private vma-s one by one.
> +	 *
> +	 * Add two guard pages from both sides. This pages will be
> +	 * unmaped before reading a current vmas for this process.
> +	 * In this case we can be sure, that vmas outside and inside
> +	 * of the premmapped region are not merged to each other.
> +	 */
> +	addr = mmap(NULL, priv_size + 2 * PAGE_SIZE,
> +			PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);

If we DO need guard pages then implement this in separate patch with proper description.

>  	if (addr == MAP_FAILED) {
>  		pr_perror("Unable to reserve memory");
>  		return -1;
>  	}
>  
> +	premmapped_addr = addr;
> +	premmapped_len = priv_size + 2 * PAGE_SIZE;
> +
> +	addr += PAGE_SIZE;
> +
>  	list_for_each_entry(vma, &vma_list, list) {
>  		if (!vma_priv(&vma->vma))
>  			continue;
> @@ -321,6 +321,10 @@ long __export_restore_task(struct task_restore_core_args *args)
>  		if (!vma_entry_is(vma_entry, VMA_AREA_REGULAR))
>  			continue;
>  
> +		if (args->premmapped_addr <= vma_entry->start &&
> +		    vma_entry->end <= args->premmapped_addr + args->premmapped_len)
> +			continue;

Why so complex? Isn't it easier just to remove this are from self_vma_list in cr-restore?

> +
>  		if (sys_munmap((void *)vma_entry->start, vma_entry_len(vma_entry))) {
>  			pr_err("Munmap fail for %lx\n", vma_entry->start);
>  			goto core_restore_end;
> 




More information about the CRIU mailing list