[CRIU] [PATCH v4] Try to include userfaultfd with criu

Adrian Reber adrian at lisas.de
Wed Mar 9 23:39:46 PST 2016


I tried to address all the code changes in the upcoming patch series (v5).

I added another patch on top, which only re-orders code to support
post-copy/lazy migration between two hosts. This new last patch should only
re-order existing code.

On Wed, Mar 09, 2016 at 02:44:11PM +0300, Pavel Emelyanov wrote:
[...]
> > +static void criu_init()
> > +{
> > +	/* TODO: return code checking */
> > +	check_img_inventory();
> > +	prepare_task_entries();
> > +	prepare_pstree();
> > +	collect_remaps_and_regfiles();
> > +	prepare_shared_reg_files();
> > +	prepare_remaps();
> > +	prepare_mm_pid(root_item);
> 
> Wow! Do you really need all this stuff in uffd daemon? What for?

I actually don't know. I was trying to use the existing CRIU
infrastructure to access the pages*.img files and only after adding all
those functions I was able to use the existing page* functions.

> > +
> > +	/* We found a PID */
> > +	pr_debug("root_item->pid.virt %d\n", root_item->pid.virt);
> > +	pr_debug("root_item->pid.real %d\n", root_item->pid.real);
> > +}
> > +
> > +int uffd_listen()
> > +{
> > +	__u64 address;
> > +	void *dest;
> > +	__u64 flags;
> > +	struct uffd_msg msg;
> > +	struct page_read pr;
> > +	unsigned long ps;
> > +	int rc;
> > +	fd_set set;
> > +	struct timeval timeout;
> > +	int uffd;
> > +	unsigned long uffd_copied_pages = 0;
> > +	int uffd_flags;
> > +	struct uffd_pages_struct *uffd_pages;
> > +	bool vdso_sent = false;
> > +	unsigned long vma_size = 0;
> > +
> > +	LIST_HEAD(uffd_list);
> > +
> > +	if (!opts.addr) {
> > +		pr_info("Please specify a file name for the unix domain socket\n");
> > +		pr_info("used to communicate between the lazy-pages server\n");
> > +		pr_info("and the restore process. Use the --address option like\n");
> > +		pr_info("criu --lazy-pages --address /tmp/userfault.socket\n");
> > +		return -1;
> > +	}
> > +
> > +	pr_debug("Waiting for incoming connections on %s\n", opts.addr);
> > +	if ((uffd = ud_open()) < 0)
> > +		exit(0);
> > +
> > +	pr_debug("uffd is 0x%d\n", uffd);
> > +	uffd_flags = fcntl(uffd, F_GETFD, NULL);
> > +	pr_debug("uffd_flags are 0x%x\n", uffd_flags);
> > +
> > +	/* Setting up criu infrastructure to easily access the dump results */
> > +	criu_init();
> > +
> > +	/* Initialize FD sets for read() with timeouts (using select()) */
> > +	FD_ZERO(&set);
> > +	FD_SET(uffd, &set);
> > +
> > +	/* All operations will be done on page size */
> > +	ps = page_size();
> > +	dest = malloc(ps);
> > +
> > +	rc = open_page_read(root_item->pid.virt, &pr, PR_TASK);
> 
> This seem to work only with one single task, doesn't it?

Yes, right now my test case is a simple C program with a one page malloc
and a loop. If possible I would like to get the code for the simple case
ready and then continue to improve it for other programs. This is
probably also related to your non-cooperative patch set which needs be
resurrected.

		Adrian


More information about the CRIU mailing list