<div dir="ltr">Great!  Will send a revised patch over the next couple of days.<div><br></div><div>--Saied</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 3, 2016 at 2:10 AM, Adrian Reber <span dir="ltr">&lt;<a href="mailto:adrian@lisas.de" target="_blank">adrian@lisas.de</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Wed, Mar 02, 2016 at 10:33:08AM +0300, Pavel Emelyanov wrote:<br>
&gt; On 03/01/2016 06:48 PM, Saied Kazemi wrote:<br>
&gt; &gt; Thank you both for your feedback.  I agree that testing the minimal requirements (category 1) would be a better default action.  I was trying to maintain some sort of compatibility with how it worked before.  But if that&#39;s not an issue, how about the following?<br>
&gt; &gt;<br>
&gt; &gt; 1. criu check  Â // category 1 only<br>
&gt; &gt; 2. criu check --extra  Â // category 2 only<br>
&gt; &gt; 3. criu check --experimental  Â // category 3 only<br>
&gt; &gt; 4. criu check --all  Â // all categories<br>
&gt; &gt; 5. criu check --feature FEAT  Â // specific feature<br>
&gt;<br>
&gt; As for me, it looks great :) Thanks!<br>
<br>
</span>Exactly what I would expect. Sounds great.<br>
<span class="HOEnZb"><font color="#888888"><br>
  Â  Â  Â  Â  Â  Â  Â  Adrian<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
&gt; &gt; On Tue, Mar 1, 2016 at 2:58 AM, Adrian Reber &lt;<a href="mailto:adrian@lisas.de">adrian@lisas.de</a> &lt;mailto:<a href="mailto:adrian@lisas.de">adrian@lisas.de</a>&gt;&gt; wrote:<br>
&gt; &gt;<br>
&gt; &gt;  Â  Â On Tue, Mar 01, 2016 at 12:59:03PM +0300, Pavel Emelyanov wrote:<br>
&gt; &gt;  Â  Â &gt; On 03/01/2016 01:58 AM, Saied Kazemi wrote:<br>
&gt; &gt;  Â  Â &gt; &gt; Pavel and Adrian,<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt; Had some time this morning and did a quick rework of criu check hopefully without having broken anything.  Haven&#39;t had time for thorough testing but in the interest of time wanted to send the patch for everyone&#39;s comments.<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt; With this patch, &quot;criu check --abs&quot; passes on 3.19 but fails on 3.13 due to PR_SET_MM_MAP.<br>
&gt; &gt;  Â  Â &gt;<br>
&gt; &gt;  Â  Â &gt; I like the patch and have only two suggestions:<br>
&gt; &gt;  Â  Â &gt;<br>
&gt; &gt;  Â  Â &gt; 1. Isn&#39;t it better to make &#39;criu check&#39; w/o any option to check for minimally<br>
&gt; &gt;  Â  Â &gt;  Â  required set of features? And, the --full (or smth like this) to check for<br>
&gt; &gt;  Â  Â &gt;  Â  all the possible functionality.<br>
&gt; &gt;<br>
&gt; &gt;  Â  Â This is also what I would expect. For a new criu user the check command<br>
&gt; &gt;  Â  Â is a good start to see if criu is usable on his platform. Only checking<br>
&gt; &gt;  Â  Â for the minimum which is required to run criu would make sense and if<br>
&gt; &gt;  Â  Â advanced features are needed/desired a more detailed or better check can<br>
&gt; &gt;  Â  Â be run.<br>
&gt; &gt;<br>
&gt; &gt;  Â  Â &gt; 2. The PR_SET_MM_MAP is really optional. The criu/pie/restorer.c has proper<br>
&gt; &gt;  Â  Â &gt;  Â  fall-back in case this API is not supported and there are cases when restore<br>
&gt; &gt;  Â  Â &gt;  Â  w/o this kernel API work. So I suggest to fix the check_prctl to be optional.<br>
&gt; &gt;  Â  Â &gt;<br>
&gt; &gt;  Â  Â &gt; What do you think?<br>
&gt; &gt;  Â  Â &gt;<br>
&gt; &gt;  Â  Â &gt; -- Pavel<br>
&gt; &gt;  Â  Â &gt;<br>
&gt; &gt;  Â  Â &gt; &gt; Look forward to your review and feedback.<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt; --Saied<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt; On Mon, Feb 29, 2016 at 2:52 PM, Saied Kazemi &lt;<a href="mailto:saied@google.com">saied@google.com</a> &lt;mailto:<a href="mailto:saied@google.com">saied@google.com</a>&gt; &lt;mailto:<a href="mailto:saied@google.com">saied@google.com</a> &lt;mailto:<a href="mailto:saied@google.com">saied@google.com</a>&gt;&gt;&gt; wrote:<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â The &quot;criu check&quot; command to check if the kernel is properly configured<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â to run criu is broken.<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â The &quot;criu check --ms&quot; command used to be the way to tell criu to check<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â only for features that have been merged upstream.  But recent kernels<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â have a set of features whose presence doesn&#39;t necessarily mean dump will<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â fail but rather *may* fail to dump or restore (e.g., soft dirty tracker,<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â tun support, seccomp).<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â This patch deprecates --ms and introduces --abs for absolutely needed<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â features.<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â Typical use cases are:<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â $ sudo criu check --abs<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â Looks good.<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â $ sudo criu check<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â &lt;zero or more errors...&gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â Looks good but some kernel features are missing.<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â $ sudo criu check --feature mnt_id<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â Looks good.<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â $ sudo criu check --feature seccomp_suspend<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â Error (cr-check.c:604): Kernel doesn&#39;t support PTRACE_O_SUSPEND_SECCOMP<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â $ sudo criu check --feature list<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â mnt_id aio_remap timerfd tun userns fdinfo_lock seccomp_suspend \<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â seccomp_filters loginuid cgroupns<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â Signed-off-by: Saied Kazemi &lt;<a href="mailto:saied@google.com">saied@google.com</a> &lt;mailto:<a href="mailto:saied@google.com">saied@google.com</a>&gt; &lt;mailto:<a href="mailto:saied@google.com">saied@google.com</a> &lt;mailto:<a href="mailto:saied@google.com">saied@google.com</a>&gt;&gt;&gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â ---<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  criu/cr-check.c  Â  Â  Â  Â  Â | 178 +++++++++++++++++++++++-----------------------<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  criu/cr-service.c  Â  Â  Â  Â |  Â 4 +-<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  criu/crtools.c  Â  Â  Â  Â  Â  |  28 ++++++--<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  criu/include/cr_options.h |  Â 2 +-<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  4 files changed, 112 insertions(+), 100 deletions(-)<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â diff --git a/criu/cr-check.c b/criu/cr-check.c<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â index a67ee2d..d08e085 100644<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â --- a/criu/cr-check.c<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +++ b/criu/cr-check.c<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â @@ -171,7 +171,6 @@ static int check_kcmp(void)<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  static int check_prctl(void)<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â unsigned long user_auxv = 0;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â unsigned int *tid_addr;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â unsigned int size = 0;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â int ret;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â @@ -183,37 +182,13 @@ static int check_prctl(void)<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â }<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â /*<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  * Either new or old interface must be supported in the kernel.<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  * The new interface must be supported in the kernel.<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  */<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â ret = prctl(PR_SET_MM, PR_SET_MM_MAP_SIZE, (unsigned long)&amp;size, 0, 0);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â if (ret) {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â if (!opts.check_ms_kernel) {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â pr_msg(&quot;prctl: PR_SET_MM_MAP is not supported, which &quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  &quot;is required for restoring user namespaces\n&quot;);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â return -1;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â } else<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â pr_warn(&quot;Skipping unssuported PR_SET_MM_MAP\n&quot;);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â ret = prctl(PR_SET_MM, PR_SET_MM_BRK, brk(0), 0, 0);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â if (ret) {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â if (ret == -EPERM)<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â pr_msg(&quot;prctl: One needs CAP_SYS_RESOURCE capability to perform testing\n&quot;);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â else<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â pr_msg(&quot;prctl: PR_SET_MM is not supported\n&quot;);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â return -1;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â }<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â ret = prctl(PR_SET_MM, PR_SET_MM_EXE_FILE, -1, 0, 0);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â if (ret != -EBADF) {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â pr_msg(&quot;prctl: PR_SET_MM_EXE_FILE is not supported (%d)\n&quot;, ret);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â return -1;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â }<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â ret = prctl(PR_SET_MM, PR_SET_MM_AUXV, (long)&amp;user_auxv, sizeof(user_auxv), 0);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â if (ret) {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â pr_msg(&quot;prctl: PR_SET_MM_AUXV is not supported\n&quot;);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â return -1;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â }<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â pr_msg(&quot;prctl: PR_SET_MM_MAP is not supported, which &quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  &quot;is required for restoring user namespaces\n&quot;);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â return -1;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â }<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â return 0;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â @@ -766,11 +741,8 @@ static int check_aio_remap(void)<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â ctx = (aio_context_t)naddr;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â r = syscall(SYS_io_getevents, ctx, 0, 1, NULL, NULL);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â if (r &lt; 0) {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â if (!opts.check_ms_kernel) {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â pr_err(&quot;AIO remap doesn&#39;t work properly\n&quot;);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â return -1;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â } else<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â pr_warn(&quot;Skipping unsupported AIO remap\n&quot;);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â pr_err(&quot;AIO remap doesn&#39;t work properly\n&quot;);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â return -1;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â }<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â return 0;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â @@ -782,12 +754,8 @@ static int check_fdinfo_lock(void)<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â return -1;<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â if (!kdat.has_fdinfo_lock) {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â if (!opts.check_ms_kernel) {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â pr_err(&quot;fdinfo doesn&#39;t contain the lock field\n&quot;);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â return -1;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â } else {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â pr_warn(&quot;fdinfo doesn&#39;t contain the lock field\n&quot;);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â }<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â pr_err(&quot;fdinfo doesn&#39;t contain the lock field\n&quot;);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â return -1;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â }<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â return 0;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â @@ -823,14 +791,10 @@ static int check_clone_parent_vs_pid()<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  static int check_cgroupns(void)<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â int ret;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â if (opts.check_ms_kernel) {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â pr_warn(&quot;Skipping cgroup namespaces check\n&quot;);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â return 0;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â }<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â ret = access(&quot;/proc/self/ns/cgroup&quot;, F_OK);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â if (ret &lt; 0) {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â pr_err(&quot;cgroupns not supported. This is not fatal.&quot;);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â pr_err(&quot;cgroupns not supported. This is not fatal.\n&quot;);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â return -1;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â }<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â @@ -839,9 +803,22 @@ static int check_cgroupns(void)<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  static int (*chk_feature)(void);<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +/*<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â + * There are three categories of kernel features:<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â + *<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â + *  Â  Â 1. Absolutely required (/proc/pid/map_files, ptrace PEEKSIGINFO, etc.)<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â + *  Â  Â 2. Required only for specific cases (aio remap, tun, etc.)<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â + *  Â  Â 3. Experimental (task-diag)<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â + *<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â + * We fail if any feature in category 1 is missing but tolerate failures<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â + * in the other categories.  Currently, there is nothing in category 3.<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â + */<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +#define GOOD  Â  Â  Â  Â  Â &quot;Looks good.&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +#define GOOD_BUT  Â  Â  Â &quot;Looks good but some kernel features are missing.&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  int cr_check(void)<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â struct ns_id ns = { .type = NS_CRIU, .ns_pid = PROC_SELF, .nd = &amp;mnt_ns_desc };<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â int absret = 0;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â int ret = 0;<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â if (!is_root_user())<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â @@ -863,26 +840,39 @@ int cr_check(void)<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â return -1;<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â if (chk_feature) {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â ret = chk_feature();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â if (chk_feature())<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â return -1;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â goto out;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â }<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â ret |= check_map_files();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â ret |= check_sock_diag();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â ret |= check_ns_last_pid();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â ret |= check_sock_peek_off();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â ret |= check_kcmp();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â ret |= check_prctl();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â ret |= check_fcntl();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â ret |= check_proc_stat();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â ret |= check_tcp();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â ret |= check_fdinfo_ext();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â ret |= check_unaligned_vmsplice();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â ret |= check_tty();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â ret |= check_so_gets();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â ret |= check_ipc();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â ret |= check_sigqueuinfo();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â ret |= check_ptrace_peeksiginfo();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â /*<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  * Category 1 - absolutely required.<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  */<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â absret |= check_map_files();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â absret |= check_sock_diag();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â absret |= check_ns_last_pid();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â absret |= check_sock_peek_off();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â absret |= check_kcmp();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â absret |= check_prctl();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â absret |= check_fcntl();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â absret |= check_proc_stat();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â absret |= check_tcp();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â absret |= check_fdinfo_ext();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â absret |= check_unaligned_vmsplice();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â absret |= check_tty();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â absret |= check_so_gets();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â absret |= check_ipc();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â absret |= check_sigqueuinfo();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â absret |= check_ptrace_peeksiginfo();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â if (absret || opts.check_abs_features) {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â if (!absret)<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â print_on_level(DEFAULT_LOGLEVEL, &quot;%s\n&quot;, GOOD);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â return absret;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â }<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â /*<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  * Category 2 - required for specific cases.<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  */<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â ret |= check_ptrace_suspend_seccomp();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â ret |= check_ptrace_dump_seccomp_filters();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â ret |= check_mem_dirty_track();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â @@ -896,10 +886,8 @@ int cr_check(void)<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â ret |= check_cgroupns();<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  out:<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â if (!ret)<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â print_on_level(DEFAULT_LOGLEVEL, &quot;Looks good.\n&quot;);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â return ret;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â print_on_level(DEFAULT_LOGLEVEL, &quot;%s\n&quot;, ret ? GOOD_BUT : GOOD);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â return 0;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  }<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  static int check_tun(void)<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â @@ -947,32 +935,42 @@ static int check_loginuid(void)<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â return 0;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  }<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +struct feature_list {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â char *name;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â int (*func)();<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +};<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +static struct feature_list feature_list[] = {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â { &quot;mnt_id&quot;, check_mnt_id },<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â { &quot;aio_remap&quot;, check_aio_remap },<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â { &quot;timerfd&quot;, check_timerfd },<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â { &quot;tun&quot;, check_tun },<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â { &quot;userns&quot;, check_userns },<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â { &quot;fdinfo_lock&quot;, check_fdinfo_lock },<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â { &quot;seccomp_suspend&quot;, check_ptrace_suspend_seccomp },<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â { &quot;seccomp_filters&quot;, check_ptrace_dump_seccomp_filters },<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â { &quot;loginuid&quot;, check_loginuid },<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â { &quot;cgroupns&quot;, check_cgroupns },<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â { NULL, NULL },<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +};<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  int check_add_feature(char *feat)<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â if (!strcmp(feat, &quot;mnt_id&quot;))<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â chk_feature = check_mnt_id;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â else if (!strcmp(feat, &quot;aio_remap&quot;))<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â chk_feature = check_aio_remap;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â else if (!strcmp(feat, &quot;timerfd&quot;))<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â chk_feature = check_timerfd;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â else if (!strcmp(feat, &quot;tun&quot;))<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â chk_feature = check_tun;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â else if (!strcmp(feat, &quot;userns&quot;))<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â chk_feature = check_userns;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â else if (!strcmp(feat, &quot;fdinfo_lock&quot;))<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â chk_feature = check_fdinfo_lock;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â else if (!strcmp(feat, &quot;seccomp_suspend&quot;))<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â chk_feature = check_ptrace_suspend_seccomp;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â else if (!strcmp(feat, &quot;seccomp_filters&quot;))<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â chk_feature = check_ptrace_dump_seccomp_filters;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â else if (!strcmp(feat, &quot;loginuid&quot;))<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â chk_feature = check_loginuid;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â else if (!strcmp(feat, &quot;cgroupns&quot;))<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â chk_feature = check_cgroupns;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â else {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â pr_err(&quot;Unknown feature %s\n&quot;, feat);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â return -1;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â struct feature_list *fl;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â if (!strcmp(feat, &quot;list&quot;)) {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â for (fl = feature_list; fl-&gt;name; fl++)<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â pr_msg(&quot;%s &quot;, fl-&gt;name);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â pr_msg(&quot;\n&quot;);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â return 1;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â }<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â return 0;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â for (fl = feature_list; fl-&gt;name; fl++) {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â if (!strcmp(feat, fl-&gt;name)) {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â chk_feature = fl-&gt;func;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â return 0;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â }<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â }<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â pr_err(&quot;Unknown feature %s\n&quot;, feat);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â return -1;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  }<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â diff --git a/criu/cr-service.c b/criu/cr-service.c<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â index 88d4af7..a1d843d 100644<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â --- a/criu/cr-service.c<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +++ b/criu/cr-service.c<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â @@ -567,8 +567,8 @@ static int check(int sk)<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â setproctitle(&quot;check --rpc&quot;);<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â /* Check only minimal kernel support */<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â opts.check_ms_kernel = true;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â /* Check only abolutely needed kernel features */<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â opts.check_abs_features = true;<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â if (!cr_check())<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â resp.success = true;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â diff --git a/criu/crtools.c b/criu/crtools.c<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â index a8ddb82..2120082 100644<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â --- a/criu/crtools.c<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +++ b/criu/crtools.c<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â @@ -275,6 +275,7 @@ int main(int argc, char *argv[], char *envp[])<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â { &quot;timeout&quot;,  Â  Â  Â  Â  Â  Â  Â  Â  Â  required_argument,  Â  Â  0, 1072 },<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â { &quot;external&quot;,  Â  Â  Â  Â  Â  Â  Â  Â  Â required_argument,  Â  Â  0, 1073 },<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â { &quot;empty-ns&quot;,  Â  Â  Â  Â  Â  Â  Â  Â  Â required_argument,  Â  Â  0, 1074 },<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â { &quot;abs&quot;,  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  no_argument,  Â  Â  Â  Â  Â  0, 1075 },<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â { },<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â };<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â @@ -455,8 +456,8 @@ int main(int argc, char *argv[], char *envp[])<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â opts.force_irmap = true;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â break;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â case 1054:<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â opts.check_ms_kernel = true;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â break;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â pr_err(&quot;--ms is deprecated, use --abs instead\n&quot;);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â return 1;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â case &#39;L&#39;:<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â opts.libdir = optarg;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â break;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â @@ -490,8 +491,11 @@ int main(int argc, char *argv[], char *envp[])<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â return 1;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â break;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â case 1063:<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â if (check_add_feature(optarg) &lt; 0)<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â ret = check_add_feature(optarg);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â if (ret &lt; 0)  Â  /* invalid kernel feature name */<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â return 1;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â if (ret &gt; 0)  Â  /* list kernel features and exit */<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â return 0;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â break;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â case 1064:<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â if (!add_skip_mount(optarg))<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â @@ -554,6 +558,9 @@ int main(int argc, char *argv[], char *envp[])<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â return 1;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â }<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â break;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â case 1075:<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â opts.check_abs_features = true;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â break;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â case &#39;V&#39;:<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â pr_msg(&quot;Version: %s\n&quot;, CRIU_VERSION);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â if (strcmp(CRIU_GITID, &quot;0&quot;))<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â @@ -714,7 +721,7 @@ usage:<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  &quot;Usage:\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  &quot;  criu dump|pre-dump -t PID [&lt;options&gt;]\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  &quot;  criu restore [&lt;options&gt;]\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -&quot;  criu check [--ms]\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +&quot;  criu check [--feature FEAT]\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  &quot;  criu exec -p PID &lt;syscall-string&gt;\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  &quot;  criu page-server\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  &quot;  criu service [&lt;options&gt;]\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â @@ -807,8 +814,16 @@ usage:<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  &quot;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  socket[inode]\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  &quot;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  file[mnt_id:inode]\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  &quot;  --empty-ns {net}\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -&quot;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Create a namespace, but don&#39;t restore its properies.\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -&quot;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  An user will retore them from action scripts.\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +&quot;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Create a namespace, but don&#39;t restore its properies.\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +&quot;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  An user will retore them from action scripts.\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +&quot;Check options:\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +&quot;  --abs  Â  Â  Â  Â  Â  Â  Â  Â check availability of absolutely needed kernel features\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +&quot;  --ms  Â  Â  Â  Â  Â  Â  Â  Â  deprecated, use --abs (don&#39;t check not yet merged kernel features)\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +&quot;  --feature FEAT  Â  Â  Â  check availability of one of the following kernel features\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +&quot;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  &quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â );<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â check_add_feature(&quot;list&quot;);<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â pr_msg(<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  &quot;\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  &quot;* Logging:\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  &quot;  -o|--log-file FILE  Â  log file name\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â @@ -836,7 +851,6 @@ usage:<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  &quot;Other options:\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  &quot;  -h|--help  Â  Â  Â  Â  Â  Â show this text\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  &quot;  -V|--version  Â  Â  Â  Â  show version\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -&quot;  Â  Â --ms  Â  Â  Â  Â  Â  Â  Â don&#39;t check not yet merged kernel features\n&quot;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â );<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â return 0;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â diff --git a/criu/include/cr_options.h b/criu/include/cr_options.h<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â index a6f0b3e..ba2633a 100644<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â --- a/criu/include/cr_options.h<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +++ b/criu/include/cr_options.h<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â @@ -56,7 +56,7 @@ struct cr_options {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â int  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â final_state;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â char  Â  Â  Â  Â  Â  Â  Â  Â  Â  *show_dump_file;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â char  Â  Â  Â  Â  Â  Â  Â  Â  Â  *show_fmt;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â -  Â  Â  Â bool  Â  Â  Â  Â  Â  Â  Â  Â  Â  check_ms_kernel;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â +  Â  Â  Â bool  Â  Â  Â  Â  Â  Â  Â  Â  Â  check_abs_features;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â bool  Â  Â  Â  Â  Â  Â  Â  Â  Â  show_pages_content;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â union {<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â bool  Â  Â  Â  Â  Â  restore_detach;<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â --<br>
&gt; &gt;  Â  Â &gt; &gt;  Â  Â 2.7.0.rc3.207.g0ac5344<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
&gt; &gt;  Â  Â &gt; &gt;<br>
</div></div></blockquote></div><br></div>