<div dir="ltr">Pavel,<div><br></div><div>Good news.  Making the following change to try_ext_bind_mount() after applying your --ext-mount patches and using -M on dump and -M/var/lib/docker on restore, it&#39;s possible to resume a Docker container process _without_ any plugins.  Please note that as mentioned before, the restore is successful as far as CRIU is concerned and is not visible to the Docker daemon.</div>
<div><br></div><div>--Saied</div><div><br></div><div><div>diff --git a/mount.c b/mount.c</div><div>index eca3fa5..0f4a807 100644</div><div>--- a/mount.c</div><div>+++ b/mount.c</div><div>@@ -1174,22 +1174,32 @@ static int do_new_mount(struct mount_info *mi)</div>
<div> </div><div> static int try_ext_bind_mount(struct mount_info *mi)</div><div> {</div><div>-       if (opts.ext_mount_mode == EXT_MOUNT_NONE) {</div><div>-              pr_err(&quot;Restoring external bind mount %s is not enabled\n&quot;,</div>
<div>-                              mi-&gt;mountpoint);</div><div>-              return -1;</div><div>-       }</div><div>+       char buf[256];</div><div>+       char *source;</div><div> </div><div>-       if (opts.ext_mount_mode != EXT_MOUNT_OK)</div>
<div>-              return -1;</div><div>+       if (opts.ext_mount_mode == EXT_MOUNT_NONE) {</div><div>+               pr_err(&quot;Restoring external bind mount %s is not enabled\n&quot;,</div><div>+                       mi-&gt;mountpoint);</div>
<div>+               return -1;</div><div>+       }</div><div> </div><div>-       pr_info(&quot;Bind-mounting %s to %s\n&quot;, mi-&gt;root, mi-&gt;mountpoint);</div><div>-       if (mount(mi-&gt;root, mi-&gt;mountpoint, NULL, MS_BIND, NULL)) {</div>
<div>-              pr_perror(&quot;Can&#39;t bind ext mount&quot;);</div><div>-              return -1;</div><div>-       }</div><div>+       if (opts.ext_mount_mode == EXT_MOUNT_PREP) {</div><div>+               snprintf(buf, 256, &quot;%s/%s&quot;, opts.em_arg_1, mi-&gt;root);</div>
<div>+               source = buf;</div><div>+       } else</div><div>+               source = mi-&gt;root;</div><div>+</div><div>+       if (opts.ext_mount_mode != EXT_MOUNT_OK &amp;&amp;</div><div>+           opts.ext_mount_mode != EXT_MOUNT_PREP)</div>
<div>+               return -1;</div><div> </div><div>-       return 0;</div><div>+       pr_info(&quot;Bind-mounting %s to %s\n&quot;, source, mi-&gt;mountpoint);</div><div>+       if (mount(source, mi-&gt;mountpoint, NULL, MS_BIND, NULL)) {</div>
<div>+               pr_perror(&quot;Can&#39;t bind ext mount&quot;);</div><div>+               return -1;</div><div>+       }</div><div>+</div><div>+       return 0;</div><div> }</div></div><div><br></div></div><div class="gmail_extra">
<br><br><div class="gmail_quote">On Tue, Jun 3, 2014 at 1:44 PM, Saied Kazemi <span dir="ltr">&lt;<a href="mailto:saied@google.com" target="_blank">saied@google.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr">Hi Pavel,<div><br></div><div>It&#39;d make using CRIU much easier :)  For now, I&#39;ve been using a Docker plugin in my experiments to dump and restore a process inside a Docker container:</div><div><br></div>

<div>1. On the dump side, I am passing m-&gt;root to the Docker plugin (in addition to m-&gt;mountpoint and m-&gt;mnt_id) so that the path can be recorded in the img file.</div><div><div><br></div><div>        ret = cr_plugin_dump_ext_mount(m-&gt;root, m-&gt;mountpoint + 1, m-&gt;mnt_id);</div>

</div><div><br></div><div>2. On the restore side, I pass opts.root from --root on the command line instead of always passing &quot;/&quot; (this was probably your original intention).  Then the Docker plugin prepends /var/lib/docker to the path that was recorded in the img file during dump.</div>

<div><br></div><div>        ret = cr_plugin_restore_ext_mount(mi-&gt;mnt_id, mi-&gt;mountpoint, opts.root ? : &quot;/&quot;, NULL);</div><div><br></div><div>Like the plugin in the run.sh example, the Docker plugin is using an environment variable (CR_EXT_BIND_MOUNTS) to identify its files.  It&#39;d be great to get rid of this environment variable.</div>

<div><br></div><div>Finally, I have to manually set up the cgroups (e.g., /sys/fs/cgroup/cpu/docker/&lt;ID&gt;) before restoring:</div><div><br></div><div><div>        criu restore -o restore.log --root /var/lib/docker/vfs/dir/&lt;ID&gt; -D img -v4 -j -n mnt -n pid --lib /path/to/plugin</div>

</div><div><br></div><div>The end result is that the process is successfully restored and resumes operation.  Currently, however, the Docker daemon is totally unaware of the process being resurrected and docker ps won&#39;t show it.  We need supporting code in Docker.</div>
<span class="HOEnZb"><font color="#888888">
<div><br></div><div>--Saied</div><div><br></div><div><br></div><div><br></div><div><br></div></font></span></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jun 3, 2014 at 9:26 AM, Pavel Emelyanov <span dir="ltr">&lt;<a href="mailto:xemul@parallels.com" target="_blank">xemul@parallels.com</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
I&#39;d like to propose an API to support external mount points w/o plugins.<br>
It&#39;s a typical scenario when people just do a bind mount before going<br>
into chroot/pivot_root and starting a container. Such a construction is<br>
not dumpable by CRIU, but I think it&#39;s possibly to handle the common and<br>
typical scenario.<br>
<br>
That said, the proposal is to introduce the --ext-mount option with the<br>
syntax:<br>
<br>
--ext-mount without arguments on dump says, that mount point with the<br>
source sitting outside of the namespace root should be dumped &quot;as is&quot;.<br>
On restore this will say to try create bind mount with unchanged source<br>
path. It&#39;s useful for suspend/resume scenario and for live-migration<br>
between hosts with identical FS paths.<br>
<br>
--ext-mount p&lt;path&gt;, e.g. --ext-mount p/foo on restore will cause the<br>
&lt;path&gt; be prepended to any bind mount source. IOW /bar bind mounted into<br>
/root will result in /foo/bar get bind mounted into /root on restore<br>
<br>
--ext-mount s&lt;delim&gt;&lt;path1&gt;&lt;delim&gt;&lt;path2&gt;, e.g. --ext-mount s:/foo:/bar<br>
will case the &lt;path1&gt; prefix get substituted with &lt;path2&gt; prefix for<br>
every external bind mount on restore. IOW /foo/foobar bind mounted into<br>
/root will result in /bar/foobar bind mounted to /root on restore.<br>
<br>
The patchset is not complete, it just demonstrates the intention. Saied,<br>
it seems to handle your scripted case, the external file gets mounted into<br>
proper place with plain --ext-mount option, but there&#39;s still unresolved<br>
issue with proc :(<br>
<br>
Comments are welcome.<br>
<br>
TODO<br>
<br>
1. check that flags (ro, shared) are dumped and restore correctly<br>
2. implement p and s modes for --ext-mount option on restore<br>
3. support ext-mount option in RPC API<br>
4. add option help text and documentation<br>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>