<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">2016-10-12 11:54 GMT+03:00 Pavel Emelyanov <span dir="ltr">&lt;<a href="mailto:xemul@virtuozzo.com" target="_blank">xemul@virtuozzo.com</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><span class="gmail-">On 09/11/2016 08:14 PM, Eugene Batalov wrote:<br>
&gt; We reuse minimal subset of criu restore command logic sufficient<br>
&gt; to locate all the link remaps in all ps tree mnt namespaces.<br>
&gt; No ps tree processes are created but all the ps tree mnt<br>
&gt; namespaces and mountpoints are created. After creation of ps<br>
&gt; tree mnt namespaces each link remap is deleted in its namespace.<br>
&gt;<br>
&gt; Exact logic is the following:<br>
&gt; 1. check_img_inventory() - prepare_pstree(). These calls are needed to<br>
&gt;    initialize root_ns_mask that is used during ps tree mnt namespaces<br>
&gt;    creation.<br>
<br>
</span>The root_ns_mask() is set up only in prepare_pstree() (which does much<br>
more than just this). But what is check_img_inventory() for?<br></blockquote><div><br></div><div>check_img_inventory() call is intended to check that criu dump files that we pass to criu gc are supported and somewhat valid.<br></div><div>check_img_inventory() is also called in the beginning of criu restore and cr_lazy_pages.<br></div><div>So it looks like we should have it in cr-gc.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<span class="gmail-"><br>
&gt; 2. prepare_shared_fdinfo() - collect_remaps_and_regfiles(). These calls<br>
&gt;    are needed to collect information about link remaps and reg files of<br>
&gt;    ps tree from dump.<br>
<br>
</span>Why prepare_shared_fdinfo() needed?<br></blockquote><div><br></div><div>prepare_shared_fdinfo() is needed because during collect_remaps_and_regfiles() call collect_one_regfile() is called<br></div><div>and collect_one_regfile() calls file_desc_add().</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<span class="gmail-"><br>
&gt; 3. gc_setup_mntns() (if needed) creates all the ps tree mnt namespaces<br>
&gt;    and performs mounting of proper fs hierachies into them.<br>
<br>
</span>The read_mntns_img() does this, no?<br></blockquote><div><br></div><div>No. The whole logic of gc_setup_mntns() does this. The main component of gc_setup_mntns() is prepare_mnt_ns() call that instantiates</div><div>all the ps tree mnt namespaces and their root file systems.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<div class="gmail-HOEnZb"><div class="gmail-h5"><br>
&gt; 4. prepare_remaps() call is needed to associate link remaps and reg<br>
&gt;    files structs we&#39;ve read from dump. It also works with ps tree fs<br>
&gt;    so mnt namespaces should be created before this call.<br>
&gt;<br>
&gt; 5. gc_link_remaps() - delete all the link remaps in their mnt namespaces.<br>
&gt;<br>
&gt; Signed-off-by: Eugene Batalov &lt;<a href="mailto:eabatalov89@gmail.com">eabatalov89@gmail.com</a>&gt;<br>
&gt; ---<br>
&gt;  criu/cr-gc.c             | 104 ++++++++++++++++++++++++++++++<wbr>++++++++++++++++-<br>
&gt;  criu/files-reg.c         |  37 +++++++++++++++++<br>
&gt;  criu/include/files-reg.h |   1 +<br>
&gt;  3 files changed, 141 insertions(+), 1 deletion(-)<br>
&gt;<br>
&gt; diff --git a/criu/cr-gc.c b/criu/cr-gc.c<br>
&gt; index bdd3723..e248e66 100644<br>
&gt; --- a/criu/cr-gc.c<br>
&gt; +++ b/criu/cr-gc.c<br>
&gt; @@ -1,6 +1,108 @@<br>
&gt; +#include &lt;sched.h&gt;<br>
&gt; +#include &lt;unistd.h&gt;<br>
&gt; +<br>
&gt; +#include &quot;criu-log.h&quot;<br>
&gt;  #include &quot;crtools.h&quot;<br>
&gt; +#include &quot;pstree.h&quot;<br>
&gt; +#include &quot;files.h&quot;<br>
&gt; +#include &quot;files-reg.h&quot;<br>
&gt; +#include &quot;mount.h&quot;<br>
&gt; +#include &quot;namespaces.h&quot;<br>
&gt; +#include &quot;util.h&quot;<br>
&gt;<br>
&gt; -int cr_gc(void)<br>
&gt; +static int root_mntns = -1;<br>
&gt; +<br>
&gt; +static int gc_setup_mntns(void)<br>
&gt; +{<br>
&gt; +     if (mntns_maybe_create_roots() &lt; 0)<br>
&gt; +             return -1;<br>
&gt; +<br>
&gt; +     if (read_mnt_ns_img() &lt; 0)<br>
&gt; +             return -1;<br>
&gt; +<br>
&gt; +     if (root_ns_mask &amp; CLONE_NEWNS) {<br>
&gt; +             /* prepare_mnt_ns() expects that root mnt ns is already created */<br>
&gt; +             if (unshare(CLONE_NEWNS)) {<br>
&gt; +                     pr_perror(&quot;Couldn&#39;t create root mount namespace\n&quot;);<br>
&gt; +                     return -1;<br>
&gt; +             }<br>
&gt; +<br>
&gt; +             root_mntns = open_proc(PROC_SELF, &quot;ns/mnt&quot;);<br>
&gt; +             if (root_mntns &lt; 0)<br>
&gt; +                     return -1;<br>
&gt; +     }<br>
&gt; +<br>
&gt; +     if (prepare_mnt_ns() &lt; 0)<br>
&gt; +             return -1;<br>
&gt; +<br>
&gt; +     return 0;<br>
&gt; +}<br>
&gt; +<br>
&gt; +static int gc_cleanup_mntns(void)<br>
&gt; +{<br>
&gt; +     int ret = depopulate_roots_yard(root_<wbr>mntns, false);<br>
&gt; +<br>
&gt; +     if ((root_mntns != -1) &amp;&amp; close(root_mntns)) {<br>
&gt; +             pr_perror(&quot;Couldn&#39;t close root mntns fd&quot;);<br>
&gt; +             ret = -1;<br>
&gt; +     }<br>
&gt; +<br>
&gt; +     return ret;<br>
&gt; +}<br>
&gt; +<br>
&gt; +static int gc_do(void)<br>
&gt;  {<br>
&gt; +     if (gc_link_remaps() &lt; 0)<br>
&gt; +             return -1;<br>
&gt; +<br>
&gt;       return 0;<br>
&gt;  }<br>
&gt; +<br>
&gt; +int cr_gc(void)<br>
&gt; +{<br>
&gt; +     int ret = 0;<br>
&gt; +<br>
&gt; +     if (check_img_inventory() &lt; 0) {<br>
&gt; +             ret = -1;<br>
&gt; +             goto exit;<br>
&gt; +     }<br>
&gt; +<br>
&gt; +     if (prepare_task_entries() &lt; 0) {<br>
&gt; +             ret = -1;<br>
&gt; +             goto exit;<br>
&gt; +     }<br>
&gt; +<br>
&gt; +     if (prepare_pstree() &lt; 0) {<br>
&gt; +             ret = -1;<br>
&gt; +             goto exit;<br>
&gt; +     }<br>
&gt; +<br>
&gt; +     if (prepare_shared_fdinfo() &lt; 0) {<br>
&gt; +             ret = -1;<br>
&gt; +             goto exit;<br>
&gt; +     }<br>
&gt; +<br>
&gt; +     if (collect_remaps_and_regfiles()<wbr>) {<br>
&gt; +             ret = -1;<br>
&gt; +             goto exit;<br>
&gt; +     }<br>
&gt; +<br>
&gt; +     if (gc_setup_mntns()) {<br>
&gt; +             ret = -1;<br>
&gt; +             goto exit;<br>
&gt; +     }<br>
&gt; +<br>
&gt; +     if (prepare_remaps() &lt; 0) {<br>
&gt; +             ret = -1;<br>
&gt; +             goto exit;<br>
&gt; +     }<br>
&gt; +<br>
&gt; +     if (gc_do())<br>
&gt; +             ret = -1;<br>
&gt; +<br>
&gt; +exit:<br>
&gt; +     if (gc_cleanup_mntns())<br>
&gt; +             ret = -1;<br>
&gt; +<br>
&gt; +     return ret;<br>
&gt; +}<br>
&gt; diff --git a/criu/files-reg.c b/criu/files-reg.c<br>
&gt; index 45100f9..07e9772 100644<br>
&gt; --- a/criu/files-reg.c<br>
&gt; +++ b/criu/files-reg.c<br>
&gt; @@ -712,6 +712,43 @@ static void __rollback_link_remaps(bool do_unlink)<br>
&gt;  void delete_link_remaps(void) { __rollback_link_remaps(true); }<br>
&gt;  void free_link_remaps(void) { __rollback_link_remaps(false); }<br>
&gt;<br>
&gt; +int gc_link_remaps(void)<br>
&gt; +{<br>
&gt; +     struct remap_info *ri;<br>
&gt; +     struct file_remap *remap;<br>
&gt; +<br>
&gt; +     list_for_each_entry(ri, &amp;remaps, list) {<br>
&gt; +             if (ri-&gt;rfe-&gt;remap_type != REMAP_TYPE__LINKED)<br>
&gt; +                     continue;<br>
&gt; +<br>
&gt; +             remap = ri-&gt;rfi-&gt;remap;<br>
&gt; +             struct ns_id *remap_mntns = lookup_nsid_by_mnt_id(remap-&gt;<wbr>rmnt_id);<br>
&gt; +<br>
&gt; +             if (!remap_mntns) {<br>
&gt; +                     pr_err(&quot;Can&#39;t get remap %s mnt ns %d\n&quot;,<br>
&gt; +                                     remap-&gt;rpath, remap-&gt;rmnt_id);<br>
&gt; +                     return -1;<br>
&gt; +             }<br>
&gt; +<br>
&gt; +             if (remap_mntns-&gt;nd-&gt;cflag != CLONE_NEWNS) {<br>
&gt; +                     pr_err(&quot;Wrong clone flag of remap mntns %x (id:%d)&quot;,<br>
&gt; +                                     remap_mntns-&gt;nd-&gt;cflag, remap-&gt;rmnt_id);<br>
&gt; +                     return -1;<br>
&gt; +             }<br>
&gt; +<br>
&gt; +             /*<br>
&gt; +              * We are root ps tree item in restore cmd terms.<br>
&gt; +              * All the mnt namespaces and their fds are created<br>
&gt; +              * by root ps tree item on restore.<br>
&gt; +              * So we can simply use mnt ns fds here.<br>
&gt; +              */<br>
&gt; +             if (clean_one_remap(remap, remap_mntns-&gt;mnt.root_fd))<br>
&gt; +                     return -1;<br>
&gt; +     }<br>
&gt; +<br>
&gt; +     return 0;<br>
&gt; +}<br>
&gt; +<br>
&gt;  static int create_link_remap(char *path, int len, int lfd,<br>
&gt;                               u32 *idp, struct ns_id *nsid)<br>
&gt;  {<br>
&gt; diff --git a/criu/include/files-reg.h b/criu/include/files-reg.h<br>
&gt; index 6cc2454..ff54303 100644<br>
&gt; --- a/criu/include/files-reg.h<br>
&gt; +++ b/criu/include/files-reg.h<br>
&gt; @@ -52,6 +52,7 @@ extern void delete_link_remaps(void);<br>
&gt;  extern void free_link_remaps(void);<br>
&gt;  extern int prepare_remaps(void);<br>
&gt;  extern void try_clean_remaps(void);<br>
&gt; +extern int gc_link_remaps(void);<br>
&gt;<br>
&gt;  extern int strip_deleted(struct fd_link *link);<br>
&gt;<br>
&gt;<br>
<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature">Best regards,<br>Eugene Batalov.</div>
</div></div>