[CRIU] [PATCH] pagemap: fix reading pages from socket for --remote case
Mike Rapoprt
rppt at linux.vnet.ibm.com
Tue Apr 25 14:25:35 PDT 2017
On April 25, 2017 11:47:59 PM GMT+03:00, Andrei Vagin <avagin at virtuozzo.com> wrote:
>On Tue, Apr 25, 2017 at 01:38:01PM +0300, Mike Rapoport wrote:
>> On Tue, Apr 25, 2017 at 08:56:19AM +0100, Rodrigo Bruno wrote:
>> > Hi,
>> >
>> > 2017-04-24 18:00 GMT+01:00 Pavel Emelyanov <xemul at virtuozzo.com>:
>> >
>> > > >>
>> > > >> Maybe it's better to introduce separate ->maybe_read_page
>callback for
>> > > opts.remote case?
>> > > >> This would let us localize the cache/proxy pages reading code
>in one
>> > > place.
>> > > >
>> > > > Well, we could. E.g. something like the patch below (untested).
>Note that
>> > > > we already have maybe_read_page_remote for the remote lazy
>restore case,
>> > > > and, ideally, the cache/proxy and lazy cases should use the
>same code to
>> > > > read pages.
>> > >
>> > > Yup. I like this patch :)
>> > > Rodrigo, what do you think?
>> > >
>> >
>> > I agree.
>>
>> All right, below is the more formal version of the patch. I'd suggest
>to
>> start with it to make --remote able to restore the memory. The next
>step
>> related to --remote and the page-read would be to see if it's
>possible to
>> use ASYNC with sockets, what should be refactored to enable it and
>how we
>> reduce code and functionality duplication.
>>
>>
>> From 645c2f8e5afe090ee362d3225b97e2b5f1bc95cb Mon Sep 17 00:00:00
>2001
>> From: Mike Rapoport <rppt at linux.vnet.ibm.com>
>> Date: Fri, 21 Apr 2017 17:29:10 +0300
>> Subject: [CRIU][PATCH v3] pagemap: fix reading pages from socket for
>--remote case
>>
>> When --remote option is specified, read_local_page tries to pread
>from a
>> socket, and fails with "Illegal seek" error.
>> Restore single pread call for regular image files case and introduce
>> maybe_read_page_img_cache version of maybe_read_page method.
>>
>> Generally-approved-by: Rodrigo Bruno <rbruno at gsd.inesc-id.pt>
>> Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
>> ---
>> v3: use different ->maybe_read_page method for --remote case
>> v2: simplify call to pread in non-remote case, it does not need
>'curr'
>>
>> criu/pagemap.c | 52
>+++++++++++++++++++++++++++++++++++++++++-----------
>> 1 file changed, 41 insertions(+), 11 deletions(-)
>>
>> diff --git a/criu/pagemap.c b/criu/pagemap.c
>> index 6c741b4..353c469 100644
>> --- a/criu/pagemap.c
>> +++ b/criu/pagemap.c
>> @@ -255,7 +255,6 @@ static int read_local_page(struct page_read *pr,
>unsigned long vaddr,
>> {
>> int fd = img_raw_fd(pr->pi);
>> int ret;
>> - size_t curr = 0;
>>
>> /*
>> * Flush any pending async requests if any not to break the
>> @@ -265,15 +264,10 @@ static int read_local_page(struct page_read
>*pr, unsigned long vaddr,
>> return -1;
>>
>> pr_debug("\tpr%d-%u Read page from self %lx/%"PRIx64"\n", pr->pid,
>pr->id, pr->cvaddr, pr->pi_off);
>> - while (1) {
>> - ret = pread(fd, buf + curr, len - curr, pr->pi_off + curr);
>> - if (ret < 1) {
>> - pr_perror("Can't read mapping page %d", ret);
>> - return -1;
>> - }
>> - curr += ret;
>> - if (curr == len)
>> - break;
>
>Why do you remove this loop?
This loop is introduced by the commit 86b9170ff3cd "page-read: Support reading by chunks" to allow read data from image-cache through socket.
pread and socket don't play well together, so read_local_page is used only with local images and data from the socket is read in maybe_read_page_image_cache.
>> + ret = pread(fd, buf, len, pr->pi_off);
>> + if (ret != len) {
>> + pr_perror("Can't read mapping page %d", ret);
>> + return -1;
>> }
>>
>> if (opts.auto_dedup) {
>> @@ -390,6 +384,40 @@ static int maybe_read_page_local(struct
>page_read *pr, unsigned long vaddr,
>> return ret;
>> }
>>
>> +static int maybe_read_page_img_cache(struct page_read *pr, unsigned
>long vaddr,
>> + int nr, void *buf, unsigned flags)
>> +{
>> + unsigned long len = nr * PAGE_SIZE;
>> + int fd = img_raw_fd(pr->pi);
>> + int ret;
>> + size_t curr = 0;
>> +
>> + pr_debug("\tpr%d-%u Read page from self %lx/%"PRIx64"\n", pr->pid,
>pr->id, pr->cvaddr, pr->pi_off);
>> + while (1) {
>> + ret = read(fd, buf + curr, len - curr);
>> + if (ret < 0) {
>> + pr_perror("Can't read mapping page %d", ret);
>> + return -1;
>> + }
>> + curr += ret;
>> + if (curr == len)
>> + break;
>> + }
>> +
>> + if (opts.auto_dedup) {
>> + ret = punch_hole(pr, pr->pi_off, len, false);
>> + if (ret == -1)
>> + return -1;
>> + }
>> +
>> + if (ret == 0 && pr->io_complete)
>> + ret = pr->io_complete(pr, vaddr, nr);
>> +
>> + pr->pi_off += len;
>> +
>> + return ret;
>> +}
>> +
>> static int read_page_complete(int pid, unsigned long vaddr, int
>nr_pages, void *priv)
>> {
>> int ret = 0;
>> @@ -803,7 +831,9 @@ int open_page_read_at(int dfd, int pid, struct
>page_read *pr, int pr_flags)
>> pr->id = ids++;
>> pr->pid = pid;
>>
>> - if (remote)
>> + if (opts.remote)
>> + pr->maybe_read_page = maybe_read_page_img_cache;
>> + else if (remote)
>> pr->maybe_read_page = maybe_read_page_remote;
>> else
>> pr->maybe_read_page = maybe_read_page_local;
>> --
>> 1.9.1
>>
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
More information about the CRIU
mailing list