예제 #1
0
파일: shmem.c 프로젝트: kvser/criu
static int restore_shmem_content(void *addr, struct shmem_info *si)
{
    int ret = 0;
    struct page_read pr;
    unsigned long off_real;

    ret = open_page_read(si->shmid, &pr, opts.auto_dedup ? O_RDWR : O_RSTR, true);
    if (ret)
        goto err_unmap;

    while (1) {
        unsigned long vaddr;
        unsigned nr_pages;
        struct iovec iov;

        ret = pr.get_pagemap(&pr, &iov);
        if (ret <= 0)
            break;

        vaddr = (unsigned long)iov.iov_base;
        nr_pages = iov.iov_len / PAGE_SIZE;

        if (vaddr + nr_pages * PAGE_SIZE > si->size)
            break;

        off_real = lseek(pr.fd_pg, 0, SEEK_CUR);

        ret = read(pr.fd_pg, addr + vaddr, nr_pages * PAGE_SIZE);
        if (ret != nr_pages * PAGE_SIZE) {
            ret = -1;
            break;
        }

        if (opts.auto_dedup) {
            ret = punch_hole(&pr, off_real, nr_pages * PAGE_SIZE, false);
            if (ret == -1) {
                break;
            }
        }

        if (pr.put_pagemap)
            pr.put_pagemap(&pr);
    }

    pr.close(&pr);
    return ret;
err_unmap:
    munmap(addr,  si->size);
    return -1;
}
예제 #2
0
파일: cr-dedup.c 프로젝트: lesilva00/criu
static int cr_dedup_one_pagemap(int pid)
{
	int ret;
	struct page_read pr;
	struct page_read * prp;
	struct iovec iov;

	ret = open_page_read(pid, &pr, O_RDWR, false);
	if (ret) {
		ret = -1;
		goto exit;
	}

	prp = pr.parent;
	if (!prp)
		goto exit;

	ret = pr.get_pagemap(&pr, &iov);
	if (ret <= 0)
		goto exit;

	while (1) {
		pr_debug("dedup iovec base=%p, len=%zu\n", iov.iov_base, iov.iov_len);
		if (!pr.pe->in_parent) {
			ret = dedup_one_iovec(prp, &iov);
			if (ret)
				goto exit;
		}

		pr.put_pagemap(&pr);
		ret = pr.get_pagemap(&pr, &iov);
		if (ret <= 0)
			goto exit;
	}
exit:
	pr.close(&pr);

	if (ret < 0)
		return ret;

	return 0;
}