<div dir="ltr">Thanks, that would be great and then we could work on top of that!<div><br></div><div>Let me know when the merge is done.</div><div><br></div><div>best,</div><div>rodrigo</div></div><div class="gmail_extra"><br><div class="gmail_quote">2018-05-16 6:35 GMT+01:00 Andrei Vagin <span dir="ltr">&lt;<a href="mailto:avagin@virtuozzo.com" target="_blank">avagin@virtuozzo.com</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Tue, May 15, 2018 at 08:52:03AM +0100, Rodrigo Bruno wrote:<br>
&gt; Hi Andrei,<br>
&gt; <br>
&gt; thank you.<br>
&gt; <br>
&gt; So we can start working on fixing bugs in order for the zdtm tests to pass<br>
&gt; sending patches against<br>
&gt; <a href="https://github.com/avagin/criu/tree/remote" rel="noreferrer" target="_blank">https://github.com/avagin/<wbr>criu/tree/remote</a> ?<br>
<br>
</span>I&#39;m going to merge these patches into criu-dev soon.<br>
<div class="HOEnZb"><div class="h5"><br>
&gt; <br>
&gt; cheers,<br>
&gt; rodrigo<br>
&gt; <br>
&gt; 2018-05-15 7:49 GMT+01:00 Andrei Vagin &lt;<a href="mailto:avagin@virtuozzo.com">avagin@virtuozzo.com</a>&gt;:<br>
&gt; <br>
&gt; &gt;<br>
&gt; &gt; I rebased these patches and added a few minor fixes:<br>
&gt; &gt; <a href="https://github.com/avagin/criu/tree/remote" rel="noreferrer" target="_blank">https://github.com/avagin/<wbr>criu/tree/remote</a><br>
&gt; &gt;<br>
&gt; &gt; On Mon, May 14, 2018 at 01:29:47AM +0100, rodrigo-bruno wrote:<br>
&gt; &gt; &gt; From: Rodrigo Bruno &lt;<a href="mailto:rbruno@gsd.inesc-id.pt">rbruno@gsd.inesc-id.pt</a>&gt;<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; ---<br>
&gt; &gt; &gt;  criu/img-remote.c         | 93 +++++++++++++++++++++++++++++-<wbr>---------<br>
&gt; &gt; &gt;  criu/include/img-remote.h | 28 ++++++++++--<br>
&gt; &gt; &gt;  2 files changed, 93 insertions(+), 28 deletions(-)<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; diff --git a/criu/img-remote.c b/criu/img-remote.c<br>
&gt; &gt; &gt; index f812c52d..70db71e2 100644<br>
&gt; &gt; &gt; --- a/criu/img-remote.c<br>
&gt; &gt; &gt; +++ b/criu/img-remote.c<br>
&gt; &gt; &gt; @@ -470,8 +470,6 @@ static struct rimage *new_remote_image(char *path,<br>
&gt; &gt; char *snapshot_id)<br>
&gt; &gt; &gt;       buf-&gt;nbytes = 0;<br>
&gt; &gt; &gt;       INIT_LIST_HEAD(&amp;(rimg-&gt;buf_<wbr>head));<br>
&gt; &gt; &gt;       list_add_tail(&amp;(buf-&gt;l), &amp;(rimg-&gt;buf_head));<br>
&gt; &gt; &gt; -     rimg-&gt;curr_sent_buf = list_entry(rimg-&gt;buf_head.<wbr>next, struct<br>
&gt; &gt; rbuf, l);<br>
&gt; &gt; &gt; -     rimg-&gt;curr_sent_bytes = 0;<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;       if (pthread_mutex_init(&amp;(rimg-&gt;<wbr>in_use), NULL) != 0) {<br>
&gt; &gt; &gt;               pr_err(&quot;Remote image in_use mutex init failed\n&quot;);<br>
&gt; &gt; &gt; @@ -498,8 +496,6 @@ static struct rimage *clear_remote_image(struct<br>
&gt; &gt; rimage *rimg)<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;       list_entry(rimg-&gt;buf_head.<wbr>next, struct rbuf, l)-&gt;nbytes = 0;<br>
&gt; &gt; &gt;       rimg-&gt;size = 0;<br>
&gt; &gt; &gt; -     rimg-&gt;curr_sent_buf = list_entry(rimg-&gt;buf_head.<wbr>next, struct<br>
&gt; &gt; rbuf, l);<br>
&gt; &gt; &gt; -     rimg-&gt;curr_sent_bytes = 0;<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;       pthread_mutex_unlock(&amp;(rimg-&gt;<wbr>in_use));<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; @@ -669,18 +665,43 @@ err:<br>
&gt; &gt; &gt;       return NULL;<br>
&gt; &gt; &gt;  }<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; +<br>
&gt; &gt; &gt; +int64_t recv_image(int fd, struct rimage *rimg, uint64_t size, int<br>
&gt; &gt; flags, bool close_fd)<br>
&gt; &gt; &gt; +{<br>
&gt; &gt; &gt; +     int ret;<br>
&gt; &gt; &gt; +     struct roperation *op = malloc(sizeof(struct roperation));<br>
&gt; &gt; &gt; +     bzero(op, sizeof(struct roperation));<br>
&gt; &gt; &gt; +     op-&gt;fd = fd;<br>
&gt; &gt; &gt; +     op-&gt;rimg = rimg;<br>
&gt; &gt; &gt; +     op-&gt;size = size;<br>
&gt; &gt; &gt; +     op-&gt;flags = flags;<br>
&gt; &gt; &gt; +     op-&gt;close_fd = close_fd;<br>
&gt; &gt; &gt; +     op-&gt;curr_recv_buf = list_entry(rimg-&gt;buf_head.<wbr>next, struct rbuf,<br>
&gt; &gt; l);<br>
&gt; &gt; &gt; +     while ((ret = recv_image_async(op)) &lt; 0)<br>
&gt; &gt; &gt; +             if (ret != EAGAIN &amp;&amp; ret != EWOULDBLOCK)<br>
&gt; &gt; &gt; +                     return -1;<br>
&gt; &gt; &gt; +     return ret;<br>
&gt; &gt; &gt; +}<br>
&gt; &gt; &gt; +<br>
&gt; &gt; &gt;  /* Note: size is a limit on how much we want to read from the socket.<br>
&gt; &gt; Zero means<br>
&gt; &gt; &gt;   * read until the socket is closed.<br>
&gt; &gt; &gt;   */<br>
&gt; &gt; &gt; -int64_t recv_image(int fd, struct rimage *rimg, uint64_t size, int<br>
&gt; &gt; flags, bool close_fd)<br>
&gt; &gt; &gt; +int64_t recv_image_async(struct roperation *op)<br>
&gt; &gt; &gt;  {<br>
&gt; &gt; &gt; -     struct rbuf *curr_buf = NULL;<br>
&gt; &gt; &gt; +     int fd = op-&gt;fd;<br>
&gt; &gt; &gt; +     struct rimage *rimg = op-&gt;rimg;<br>
&gt; &gt; &gt; +     uint64_t size = op-&gt;size;<br>
&gt; &gt; &gt; +     int flags = op-&gt;flags;<br>
&gt; &gt; &gt; +     bool close_fd = op-&gt;close_fd;<br>
&gt; &gt; &gt; +     struct rbuf *curr_buf = op-&gt;curr_recv_buf;<br>
&gt; &gt; &gt;       int n;<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; -     if (flags == O_APPEND)<br>
&gt; &gt; &gt; -             curr_buf = list_entry(rimg-&gt;buf_head.<wbr>prev, struct rbuf,<br>
&gt; &gt; l);<br>
&gt; &gt; &gt; -     else<br>
&gt; &gt; &gt; -             curr_buf = list_entry(rimg-&gt;buf_head.<wbr>next, struct rbuf,<br>
&gt; &gt; l);<br>
&gt; &gt; &gt; +     if (curr_buf == NULL) {<br>
&gt; &gt; &gt; +             if (flags == O_APPEND)<br>
&gt; &gt; &gt; +                     curr_buf = list_entry(rimg-&gt;buf_head.<wbr>prev, struct<br>
&gt; &gt; rbuf, l);<br>
&gt; &gt; &gt; +             else<br>
&gt; &gt; &gt; +                     curr_buf = list_entry(rimg-&gt;buf_head.<wbr>next, struct<br>
&gt; &gt; rbuf, l);<br>
&gt; &gt; &gt; +     }<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;       while (1) {<br>
&gt; &gt; &gt;               n = read(fd,<br>
&gt; &gt; &gt; @@ -712,6 +733,8 @@ int64_t recv_image(int fd, struct rimage *rimg,<br>
&gt; &gt; uint64_t size, int flags, bool c<br>
&gt; &gt; &gt;                                       close(fd);<br>
&gt; &gt; &gt;                               return rimg-&gt;size;<br>
&gt; &gt; &gt;                       }<br>
&gt; &gt; &gt; +             } else if (errno == EAGAIN || errno == EWOULDBLOCK) {<br>
&gt; &gt; &gt; +                     return errno;<br>
&gt; &gt; &gt;               } else {<br>
&gt; &gt; &gt;                       pr_perror(&quot;Read on %s:%s socket failed&quot;,<br>
&gt; &gt; &gt;                               rimg-&gt;path, rimg-&gt;snapshot_id);<br>
&gt; &gt; &gt; @@ -724,37 +747,59 @@ int64_t recv_image(int fd, struct rimage *rimg,<br>
&gt; &gt; uint64_t size, int flags, bool c<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;  int64_t send_image(int fd, struct rimage *rimg, int flags, bool<br>
&gt; &gt; close_fd)<br>
&gt; &gt; &gt;  {<br>
&gt; &gt; &gt; +     int ret;<br>
&gt; &gt; &gt; +     struct roperation *op = malloc(sizeof(struct roperation));<br>
&gt; &gt; &gt; +     bzero(op, sizeof(struct roperation));<br>
&gt; &gt; &gt; +     op-&gt;fd = fd;<br>
&gt; &gt; &gt; +     op-&gt;rimg = rimg;<br>
&gt; &gt; &gt; +     op-&gt;flags = flags;<br>
&gt; &gt; &gt; +     op-&gt;close_fd = close_fd;<br>
&gt; &gt; &gt; +     op-&gt;curr_sent_buf = list_entry(rimg-&gt;buf_head.<wbr>next, struct rbuf,<br>
&gt; &gt; l);<br>
&gt; &gt; &gt; +     while ((ret = send_image_async(op)) &lt; 0)<br>
&gt; &gt; &gt; +             if (ret != EAGAIN &amp;&amp; ret != EWOULDBLOCK)<br>
&gt; &gt; &gt; +                     return -1;<br>
&gt; &gt; &gt; +     return ret;<br>
&gt; &gt; &gt; +}<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; -     int n, nblocks = 0;<br>
&gt; &gt; &gt; +int64_t send_image_async(struct roperation *op)<br>
&gt; &gt; &gt; +{<br>
&gt; &gt; &gt; +     int fd = op-&gt;fd;<br>
&gt; &gt; &gt; +     struct rimage *rimg = op-&gt;rimg;<br>
&gt; &gt; &gt; +     int flags = op-&gt;flags;<br>
&gt; &gt; &gt; +     bool close_fd = op-&gt;close_fd;<br>
&gt; &gt; &gt; +     int n;<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;       if (flags != O_APPEND) {<br>
&gt; &gt; &gt; -             rimg-&gt;curr_sent_buf = list_entry(rimg-&gt;buf_head.<wbr>next,<br>
&gt; &gt; struct rbuf, l);<br>
&gt; &gt; &gt; -             rimg-&gt;curr_sent_bytes = 0;<br>
&gt; &gt; &gt; +             op-&gt;curr_sent_buf = list_entry(rimg-&gt;buf_head.<wbr>next,<br>
&gt; &gt; struct rbuf, l);<br>
&gt; &gt; &gt; +             op-&gt;curr_sent_bytes = 0;<br>
&gt; &gt; &gt;       }<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;       while (1) {<br>
&gt; &gt; &gt;               n = send(<br>
&gt; &gt; &gt;                   fd,<br>
&gt; &gt; &gt; -                 rimg-&gt;curr_sent_buf-&gt;buffer + rimg-&gt;curr_sent_bytes,<br>
&gt; &gt; &gt; -                 min(BUF_SIZE, rimg-&gt;curr_sent_buf-&gt;nbytes) -<br>
&gt; &gt; rimg-&gt;curr_sent_bytes,<br>
&gt; &gt; &gt; +                 op-&gt;curr_sent_buf-&gt;buffer + op-&gt;curr_sent_bytes,<br>
&gt; &gt; &gt; +                 min(BUF_SIZE, op-&gt;curr_sent_buf-&gt;nbytes) -<br>
&gt; &gt; op-&gt;curr_sent_bytes,<br>
&gt; &gt; &gt;                   MSG_NOSIGNAL);<br>
&gt; &gt; &gt;               if (n &gt; -1) {<br>
&gt; &gt; &gt; -                     rimg-&gt;curr_sent_bytes += n;<br>
&gt; &gt; &gt; -                     if (rimg-&gt;curr_sent_bytes == BUF_SIZE) {<br>
&gt; &gt; &gt; -                             rimg-&gt;curr_sent_buf =<br>
&gt; &gt; &gt; -                                 list_entry(rimg-&gt;curr_sent_<wbr>buf-&gt;l.next,<br>
&gt; &gt; struct rbuf, l);<br>
&gt; &gt; &gt; -                             nblocks++;<br>
&gt; &gt; &gt; -                             rimg-&gt;curr_sent_bytes = 0;<br>
&gt; &gt; &gt; -                     } else if (rimg-&gt;curr_sent_bytes ==<br>
&gt; &gt; rimg-&gt;curr_sent_buf-&gt;nbytes) {<br>
&gt; &gt; &gt; +                     op-&gt;curr_sent_bytes += n;<br>
&gt; &gt; &gt; +                     if (op-&gt;curr_sent_bytes == BUF_SIZE) {<br>
&gt; &gt; &gt; +                             op-&gt;curr_sent_buf =<br>
&gt; &gt; &gt; +                                 list_entry(op-&gt;curr_sent_buf-&gt;<wbr>l.next,<br>
&gt; &gt; struct rbuf, l);<br>
&gt; &gt; &gt; +                             op-&gt;nblocks++;<br>
&gt; &gt; &gt; +                             op-&gt;curr_sent_bytes = 0;<br>
&gt; &gt; &gt; +                     } else if (op-&gt;curr_sent_bytes ==<br>
&gt; &gt; op-&gt;curr_sent_buf-&gt;nbytes) {<br>
&gt; &gt; &gt;                               if (close_fd)<br>
&gt; &gt; &gt;                                       close(fd);<br>
&gt; &gt; &gt; -                             return nblocks*BUF_SIZE +<br>
&gt; &gt; rimg-&gt;curr_sent_buf-&gt;nbytes;<br>
&gt; &gt; &gt; +                             return op-&gt;nblocks*BUF_SIZE +<br>
&gt; &gt; op-&gt;curr_sent_buf-&gt;nbytes;<br>
&gt; &gt; &gt;                       }<br>
&gt; &gt; &gt;               } else if (errno == EPIPE || errno == ECONNRESET) {<br>
&gt; &gt; &gt;                       pr_warn(&quot;Connection for %s:%s was closed early<br>
&gt; &gt; than expected\n&quot;,<br>
&gt; &gt; &gt;                               rimg-&gt;path, rimg-&gt;snapshot_id);<br>
&gt; &gt; &gt;                       return 0;<br>
&gt; &gt; &gt; -             } else {<br>
&gt; &gt; &gt; +             } else if (errno == EAGAIN || errno == EWOULDBLOCK) {<br>
&gt; &gt; &gt; +                     return errno;<br>
&gt; &gt; &gt; +             }<br>
&gt; &gt; &gt; +             else {<br>
&gt; &gt; &gt;                       pr_perror(&quot;Write on %s:%s socket failed&quot;,<br>
&gt; &gt; &gt;                               rimg-&gt;path, rimg-&gt;snapshot_id);<br>
&gt; &gt; &gt;                       return -1;<br>
&gt; &gt; &gt; diff --git a/criu/include/img-remote.h b/criu/include/img-remote.h<br>
&gt; &gt; &gt; index 1771d310..0947e7f0 100644<br>
&gt; &gt; &gt; --- a/criu/include/img-remote.h<br>
&gt; &gt; &gt; +++ b/criu/include/img-remote.h<br>
&gt; &gt; &gt; @@ -36,10 +36,6 @@ struct rimage {<br>
&gt; &gt; &gt;       char snapshot_id[PATHLEN];<br>
&gt; &gt; &gt;       struct list_head l;<br>
&gt; &gt; &gt;       struct list_head buf_head;<br>
&gt; &gt; &gt; -     /* Used to track already sent buffers when the image is appended.<br>
&gt; &gt; */<br>
&gt; &gt; &gt; -     struct rbuf *curr_sent_buf;<br>
&gt; &gt; &gt; -     /* Similar to the previous field. Number of bytes sent in<br>
&gt; &gt; &#39;curr_sent_buf&#39;. */<br>
&gt; &gt; &gt; -     int curr_sent_bytes;<br>
&gt; &gt; &gt;       uint64_t size; /* number of bytes */<br>
&gt; &gt; &gt;       pthread_mutex_t in_use; /* Only one operation at a time, per<br>
&gt; &gt; image. */<br>
&gt; &gt; &gt;  };<br>
&gt; &gt; &gt; @@ -57,6 +53,28 @@ struct wthread {<br>
&gt; &gt; &gt;       sem_t wakeup_sem;<br>
&gt; &gt; &gt;  };<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; +/* Structure that describes the state of a remote operation on remote<br>
&gt; &gt; images. */<br>
&gt; &gt; &gt; +struct roperation {<br>
&gt; &gt; &gt; +     /* File descriptor being used. */<br>
&gt; &gt; &gt; +     int fd;<br>
&gt; &gt; &gt; +     /* Remote image being used. */<br>
&gt; &gt; &gt; +     struct rimage *rimg;<br>
&gt; &gt; &gt; +     /* Flags for the operation. */<br>
&gt; &gt; &gt; +     int flags;<br>
&gt; &gt; &gt; +     /* If fd should be closed when the operation is done. */<br>
&gt; &gt; &gt; +     bool close_fd;<br>
&gt; &gt; &gt; +     /* Note: recv operation only. How much bytes should be received. */<br>
&gt; &gt; &gt; +     uint64_t size;<br>
&gt; &gt; &gt; +     /* Note: recv operation only. Buffer being writen. */<br>
&gt; &gt; &gt; +     struct rbuf *curr_recv_buf;<br>
&gt; &gt; &gt; +     /* Note: send operation only. Number of blocks already sent. */<br>
&gt; &gt; &gt; +     int nblocks;<br>
&gt; &gt; &gt; +     /* Note: send operation only. Pointer to buffer being sent. */<br>
&gt; &gt; &gt; +     struct rbuf *curr_sent_buf;<br>
&gt; &gt; &gt; +     /* Note: send operation only. Number of bytes sent in<br>
&gt; &gt; &#39;curr_send_buf. */<br>
&gt; &gt; &gt; +     uint64_t curr_sent_bytes;<br>
&gt; &gt; &gt; +};<br>
&gt; &gt; &gt; +<br>
&gt; &gt; &gt;  /* This variable is used to indicate when the dump is finished. */<br>
&gt; &gt; &gt;  extern bool finished;<br>
&gt; &gt; &gt;  /* This is the proxy to cache TCP socket FD. */<br>
&gt; &gt; &gt; @@ -80,7 +98,9 @@ void *accept_remote_image_<wbr>connections(void *ptr);<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;  int64_t forward_image(struct rimage *rimg);<br>
&gt; &gt; &gt;  int64_t send_image(int fd, struct rimage *rimg, int flags, bool<br>
&gt; &gt; image_check);<br>
&gt; &gt; &gt; +int64_t send_image_async(struct roperation *op);<br>
&gt; &gt; &gt;  int64_t recv_image(int fd, struct rimage *rimg, uint64_t size, int<br>
&gt; &gt; flags, bool image_check);<br>
&gt; &gt; &gt; +int64_t recv_image_async(struct roperation *op);<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;  int64_t read_remote_header(int fd, char *snapshot_id, char *path, int<br>
&gt; &gt; *open_mode, uint64_t *size);<br>
&gt; &gt; &gt;  int64_t write_remote_header(int fd, char *snapshot_id, char *path, int<br>
&gt; &gt; open_mode, uint64_t size);<br>
&gt; &gt; &gt; --<br>
&gt; &gt; &gt; 2.17.0<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; ______________________________<wbr>_________________<br>
&gt; &gt; &gt; CRIU mailing list<br>
&gt; &gt; &gt; <a href="mailto:CRIU@openvz.org">CRIU@openvz.org</a><br>
&gt; &gt; &gt; <a href="https://lists.openvz.org/mailman/listinfo/criu" rel="noreferrer" target="_blank">https://lists.openvz.org/<wbr>mailman/listinfo/criu</a><br>
&gt; &gt;<br>
</div></div></blockquote></div><br></div>