[CRIU] [PATCH 8/9] vdso: Escape double dumping of rt-vdso if proxy present

Pavel Emelyanov xemul at parallels.com
Fri May 24 05:32:22 EDT 2013


On 05/24/2013 01:42 AM, Cyrill Gorcunov wrote:
> 
> In case if we have created vdso proxy the rt-vdso should
> not be dumped because it will be re-created on next restore
> anyway. Thus with help of parasite service routine find
> the rt-vdso and tear it off from VMAs list.
> 
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
>  cr-dump.c                  |   7 +++
>  include/parasite-syscall.h |   3 ++
>  include/parasite.h         |   8 +++
>  include/vdso.h             |   7 +++
>  parasite-syscall.c         | 121 +++++++++++++++++++++++++++++++++++++++++++++
>  pie/parasite.c             |  18 +++++++
>  6 files changed, 164 insertions(+)
> 


> +int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
> +			struct vm_area_list *vma_area_list)
> +{
> +	unsigned long proxy_addr = VDSO_BAD_ADDR;
> +	struct parasite_vdso_vma_entry *args;
> +	struct vma_area *marked = NULL;
> +	struct vma_area *vma;
> +	int fd, ret = -1;
> +	off_t off;
> +	u64 pfn;
> +
> +	args = parasite_args(ctl, struct parasite_vdso_vma_entry);
> +	fd = open_proc(pid, "pagemap");
> +	if (fd < 0)
> +		return -1;
> +
> +	list_for_each_entry(vma, &vma_area_list->h, list) {
> +		if (!vma_area_is(vma, VMA_AREA_REGULAR))
> +			continue;
> +
> +		if ((vma->vma.prot & VDSO_PROT) != VDSO_PROT)
> +			continue;
> +
> +		/*
> +		 * I need to poke every potentially marked vma,
> +		 * otherwise if task never called for vdso functions
> +		 * page frame number won't be reported.
> +		 */
> +		args->start = vma->vma.start;
> +		args->len = vma_area_len(vma);
> +
> +		if (parasite_execute(PARASITE_CMD_CHECK_VDSO_MARK, ctl)) {

I'm not very happy with going to parasite for every (even pre-checked) vma.
Make it in one go to parasite with an array of vmas.

> +			pr_err("vdso: Parasite failed to poke for mark\n");
> +			ret = -1;
> +			goto err;
> +		}
> +
> +		off = (vma->vma.start / PAGE_SIZE) * sizeof(u64);
> +		if (lseek(fd, off, SEEK_SET) != off) {
> +			pr_perror("Failed to seek address %lx\n", vma->vma.start);
> +			ret = -1;
> +			goto err;
> +		}
> +
> +		ret = read(fd, &pfn, sizeof(pfn));
> +		if (ret < 0 || ret != sizeof(pfn)) {
> +			pr_perror("Can't read pme for pid %d", pid);
> +			ret = -1;
> +			goto err;
> +		}
> +
> +		pfn = PME_PFRAME(pfn);
> +		BUG_ON(!pfn);

You don't need this value for args->is_marked case.

> +
> +		/*
> +		 * Defer handling marked vdso.
> +		 */
> +		if (unlikely(args->is_marked)) {
> +			BUG_ON(args->proxy_addr == VDSO_BAD_ADDR);
> +			BUG_ON(marked);
> +			marked = vma;
> +			proxy_addr = args->proxy_addr;
> +			continue;
> +		}
> +
> +		/*
> +		 * Set proper VMA statuses.
> +		 */
> +		if (pfn == vdso_pfn) {
> +			if (!vma_area_is(vma, VMA_AREA_VDSO)) {
> +				pr_debug("vdso: Restore status by pfn at %lx\n",
> +					 (long)vma->vma.start);
> +				vma->vma.status |= VMA_AREA_VDSO;
> +			}
> +		} else {
> +			if (vma_area_is(vma, VMA_AREA_VDSO)) {
> +				pr_debug("vdso: Drop mishinted status at %lx\n",
> +					 (long)vma->vma.start);
> +				vma->vma.status &= ~VMA_AREA_VDSO;
> +			}
> +		}
> +	}
> +
> +	/*
> +	 * There is marked vdso, it means such vdso is autogenerated
> +	 * and must be dropped from vma list.
> +	 */
> +	if (marked) {
> +		pr_debug("vdso: Found marked at %lx (proxy at %lx)\n",
> +			 (long)marked->vma.start, (long)proxy_addr);
> +
> +		/*
> +		 * Don't forget to restore the proxy vdso status, since
> +		 * it's being not recognized by the kernel as vdso.
> +		 */
> +		list_for_each_entry(vma, &vma_area_list->h, list) {
> +			if (vma->vma.start == proxy_addr) {
> +				vma->vma.status |= VMA_AREA_REGULAR | VMA_AREA_VDSO;
> +				pr_debug("vdso: Restore proxy status at %lx\n",
> +					 (long)vma->vma.start);
> +				break;
> +			}
> +		}
> +
> +		pr_debug("vdso: Droppping marked vdso at %lx\n",
> +			 (long)vma->vma.start);
> +		list_del(&marked->list);
> +		xfree(marked);
> +	}
> +	ret = 0;
> +err:
> +	close(fd);
> +	return ret;
> +}



More information about the CRIU mailing list