<div dir="ltr"><div>Summary of test/zdtm.py run -a --ignore-taint --keep-going is<br></div><div>################## ALL TEST(S) PASSED (TOTAL 204/SKIPPED 21) ###################</div><div><br></div><div>Sending complete console output separately.<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Jun 10, 2019 at 10:50 PM Andrei Vagin &lt;<a href="mailto:avagin@gmail.com">avagin@gmail.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Mon, Jun 10, 2019 at 2:50 AM abhishek dubey<br>
&lt;<a href="mailto:dubeyabhishek777@gmail.com" target="_blank">dubeyabhishek777@gmail.com</a>&gt; wrote:<br>
&gt;<br>
&gt;<br>
&gt; On 10/06/19 12:59 PM, Andrei Vagin (C) wrote:<br>
&gt; &gt; On Wed, Jun 05, 2019 at 12:49:03PM +0000, Pavel Emelianov wrote:<br>
&gt; &gt;&gt; On 6/4/19 7:50 PM, Abhishek Dubey wrote:<br>
&gt; &gt;&gt;&gt; Hi,<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; On running &quot;zdtm.py run -a&quot;, testcases of zdtm/static directory are checked and that of zdtm/transition are skipped. Do all testcases of transition directory need manual run?<br>
&gt; &gt;&gt; Yes.<br>
&gt; &gt; I don&#39;t understand what you mean here.<br>
&gt; &gt;<br>
&gt; &gt; <a href="https://ci.openvz.org/job/CRIU/job/CRIU-x86_64/job/criu-dev/5439/console" rel="noreferrer" target="_blank">https://ci.openvz.org/job/CRIU/job/CRIU-x86_64/job/criu-dev/5439/console</a><br>
&gt; &gt;<br>
&gt; &gt; Here we can see that all trasition tests were checked...<br>
&gt; Here I refer to locally running zdtm tests as given on<br>
&gt; <a href="https://www.criu.org/ZDTM_test_suite" rel="noreferrer" target="_blank">https://www.criu.org/ZDTM_test_suite</a><br>
<br>
Could you show output for zdtm.py run -a?<br>
<br>
&gt; &gt;<br>
&gt; &gt;&gt;&gt; What is specific about transition testcases?<br>
&gt; &gt;&gt; They take time to accomplish, so the default run is limited.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;&gt; For the first step of fetching VMAs between freeze and unfreeze of pre-dump:<br>
&gt; &gt;&gt;&gt; - To maintain correspondence between PID and collected VMA, added new entry in struct pstree_item<br>
&gt; &gt;&gt;&gt; - Moved out unfreeze code from cr_pre_dump_finish()<br>
&gt; &gt;&gt;&gt; - Moved out collect_mappings() from pre_dump_one_task<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; I have tested these changes with env00-basic example and zdtm.py test-suite. All test-cases under zdtm/static directory are Passing. Remaining transition test cases are skipped.<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; Share your thoughts on this approach. I am attaching patch-file for reference.<br>
&gt; &gt;&gt;&gt; Hi,<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; On running &quot;zdtm.py run -a&quot;, testcases of zdtm/static directory are checked and that of zdtm/transition are skipped. Do all testcases of transition directory need manual run?<br>
&gt; &gt;&gt;&gt; What is specific about transition testcases?<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; For the first step of fetching VMAs between freeze and unfreeze of pre-dump:<br>
&gt; &gt;&gt;&gt; - To maintain correspondence between PID and collected VMA, added new entry in struct pstree_item<br>
&gt; &gt;&gt;&gt; - Moved out unfreeze code from cr_pre_dump_finish()<br>
&gt; &gt;&gt;&gt; - Moved out collect_mappings() from pre_dump_one_task<br>
&gt; &gt;&gt; Please, describe why you need this. Current code does &quot;fetching vmas between freeze and unfreeze&quot;,<br>
&gt; &gt;&gt; what&#39;s wrong with it so you need this change?<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;&gt; I have tested these changes with env00-basic example and zdtm.py test-suite. All test-cases under zdtm/static directory are Passing. Remaining transition test cases are skipped.<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; Share your thoughts on this approach. I am attaching patch-file for reference.<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; -Abhishek<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; 0001-freezing-target-task-to-collect-memory-mappings-foll.patch<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;  From 5b131559ce20ebbdb8a04be2cced321b55d864f4 Mon Sep 17 00:00:00 2001<br>
&gt; &gt;&gt; Please mind the <a href="https://criu.org/How_to_submit_patches" rel="noreferrer" target="_blank">https://criu.org/How_to_submit_patches</a> article. Patch should go inline, not attached,<br>
&gt; &gt;&gt; and properly formatted. Also comments are inline.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;&gt; From: abhidubey4178 &lt;<a href="mailto:abhishekdubey4178940@gmail.com" target="_blank">abhishekdubey4178940@gmail.com</a>&gt;<br>
&gt; &gt;&gt;&gt; Date: Tue, 4 Jun 2019 19:59:21 +0530<br>
&gt; &gt;&gt;&gt; Subject: [PATCH] freezing target task to collect memory mappings, followed by<br>
&gt; &gt;&gt;&gt;   unfreeze<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; ---<br>
&gt; &gt;&gt;&gt;   criu/cr-dump.c        | 103 +++++++++++++++++++++++++++++++-----------<br>
&gt; &gt;&gt;&gt;   criu/include/pstree.h |   1 +<br>
&gt; &gt;&gt;&gt;   2 files changed, 78 insertions(+), 26 deletions(-)<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; diff --git a/criu/cr-dump.c b/criu/cr-dump.c<br>
&gt; &gt;&gt;&gt; index 7f2e5edf..40bc7594 100644<br>
&gt; &gt;&gt;&gt; --- a/criu/cr-dump.c<br>
&gt; &gt;&gt;&gt; +++ b/criu/cr-dump.c<br>
&gt; &gt;&gt;&gt; @@ -1154,20 +1154,19 @@ static int pre_dump_one_task(struct pstree_item *item, InventoryEntry *parent_ie<br>
&gt; &gt;&gt;&gt;     if (item-&gt;pid-&gt;state == TASK_DEAD)<br>
&gt; &gt;&gt;&gt;             return 0;<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; -   ret = collect_mappings(pid, &amp;vmas, NULL);<br>
&gt; &gt;&gt; Up above there have been left the now unused vmas variable.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;&gt; -   if (ret) {<br>
&gt; &gt;&gt;&gt; +   if (!item-&gt;vmas) {<br>
&gt; &gt;&gt;&gt;             pr_err(&quot;Collect mappings (pid: %d) failed with %d\n&quot;, pid, ret);<br>
&gt; &gt;&gt;&gt;             goto err;<br>
&gt; &gt;&gt;&gt;     }<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;     ret = -1;<br>
&gt; &gt;&gt;&gt; -   parasite_ctl = parasite_infect_seized(pid, item, &amp;vmas);<br>
&gt; &gt;&gt;&gt; +   parasite_ctl = parasite_infect_seized(pid, item, item-&gt;vmas);<br>
&gt; &gt;&gt;&gt;     if (!parasite_ctl) {<br>
&gt; &gt;&gt;&gt;             pr_err(&quot;Can&#39;t infect (pid: %d) with parasite\n&quot;, pid);<br>
&gt; &gt;&gt;&gt;             goto err_free;<br>
&gt; &gt;&gt;&gt;     }<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; -   ret = parasite_fixup_vdso(parasite_ctl, pid, &amp;vmas);<br>
&gt; &gt;&gt;&gt; +   ret = parasite_fixup_vdso(parasite_ctl, pid, item-&gt;vmas);<br>
&gt; &gt;&gt;&gt;     if (ret) {<br>
&gt; &gt;&gt;&gt;             pr_err(&quot;Can&#39;t fixup vdso VMAs (pid: %d)\n&quot;, pid);<br>
&gt; &gt;&gt;&gt;             goto err_cure;<br>
&gt; &gt;&gt;&gt; @@ -1192,14 +1191,14 @@ static int pre_dump_one_task(struct pstree_item *item, InventoryEntry *parent_ie<br>
&gt; &gt;&gt;&gt;     mdc.stat = NULL;<br>
&gt; &gt;&gt;&gt;     mdc.parent_ie = parent_ie;<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; -   ret = parasite_dump_pages_seized(item, &amp;vmas, &amp;mdc, parasite_ctl);<br>
&gt; &gt;&gt;&gt; +   ret = parasite_dump_pages_seized(item, item-&gt;vmas, &amp;mdc, parasite_ctl);<br>
&gt; &gt;&gt;&gt;     if (ret)<br>
&gt; &gt;&gt;&gt;             goto err_cure;<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;     if (compel_cure_remote(parasite_ctl))<br>
&gt; &gt;&gt;&gt;             pr_err(&quot;Can&#39;t cure (pid: %d) from parasite\n&quot;, pid);<br>
&gt; &gt;&gt;&gt;   err_free:<br>
&gt; &gt;&gt;&gt; -   free_mappings(&amp;vmas);<br>
&gt; &gt;&gt;&gt; +   free_mappings(item-&gt;vmas);<br>
&gt; &gt;&gt;&gt;   err:<br>
&gt; &gt;&gt;&gt;     return ret;<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; @@ -1471,26 +1470,9 @@ static int setup_alarm_handler()<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;   static int cr_pre_dump_finish(int status)<br>
&gt; &gt;&gt;&gt;   {<br>
&gt; &gt;&gt;&gt; -   InventoryEntry he = INVENTORY_ENTRY__INIT;<br>
&gt; &gt;&gt;&gt;     struct pstree_item *item;<br>
&gt; &gt;&gt;&gt;     int ret;<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; -   /*<br>
&gt; &gt;&gt;&gt; -    * Restore registers for tasks only. The threads have not been<br>
&gt; &gt;&gt;&gt; -    * infected. Therefore, the thread register sets have not been changed.<br>
&gt; &gt;&gt;&gt; -    */<br>
&gt; &gt;&gt;&gt; -   ret = arch_set_thread_regs(root_item, false);<br>
&gt; &gt;&gt;&gt; -   if (ret)<br>
&gt; &gt;&gt;&gt; -           goto err;<br>
&gt; &gt;&gt;&gt; -<br>
&gt; &gt;&gt;&gt; -   ret = inventory_save_uptime(&amp;he);<br>
&gt; &gt;&gt;&gt; -   if (ret)<br>
&gt; &gt;&gt;&gt; -           goto err;<br>
&gt; &gt;&gt;&gt; -<br>
&gt; &gt;&gt;&gt; -   pstree_switch_state(root_item, TASK_ALIVE);<br>
&gt; &gt;&gt;&gt; -<br>
&gt; &gt;&gt;&gt; -   timing_stop(TIME_FROZEN);<br>
&gt; &gt;&gt;&gt; -<br>
&gt; &gt;&gt;&gt;     if (status &lt; 0) {<br>
&gt; &gt;&gt;&gt;             ret = status;<br>
&gt; &gt;&gt;&gt;             goto err;<br>
&gt; &gt;&gt;&gt; @@ -1540,9 +1522,6 @@ err:<br>
&gt; &gt;&gt;&gt;     if (bfd_flush_images())<br>
&gt; &gt;&gt;&gt;             ret = -1;<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; -   if (write_img_inventory(&amp;he))<br>
&gt; &gt;&gt;&gt; -           ret = -1;<br>
&gt; &gt;&gt;&gt; -<br>
&gt; &gt;&gt; You write inventory too early, I&#39;m not 100% sure this is correct.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;&gt;     if (ret)<br>
&gt; &gt;&gt;&gt;             pr_err(&quot;Pre-dumping FAILED.\n&quot;);<br>
&gt; &gt;&gt;&gt;     else {<br>
&gt; &gt;&gt;&gt; @@ -1552,6 +1531,68 @@ err:<br>
&gt; &gt;&gt;&gt;     return ret;<br>
&gt; &gt;&gt;&gt;   }<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; +<br>
&gt; &gt;&gt;&gt; +static int pre_dump_collect_vmas(struct pstree_item *item)<br>
&gt; &gt;&gt;&gt; +{<br>
&gt; &gt;&gt;&gt; +       pid_t pid = item-&gt;pid-&gt;real;<br>
&gt; &gt;&gt;&gt; +       struct vm_area_list *vmas;<br>
&gt; &gt;&gt;&gt; +       int ret = -1;<br>
&gt; &gt;&gt;&gt; +<br>
&gt; &gt;&gt;&gt; +       vmas = xmalloc(sizeof(struct vm_area_list));<br>
&gt; &gt;&gt; This memory is never free-d.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;&gt; +       if(!vmas)<br>
&gt; &gt;&gt;&gt; +            return -1;<br>
&gt; &gt;&gt;&gt; +       INIT_LIST_HEAD(&amp;vmas-&gt;h);<br>
&gt; &gt;&gt;&gt; +       vmas-&gt;nr = 0;<br>
&gt; &gt;&gt;&gt; +<br>
&gt; &gt;&gt;&gt; +       pr_info(&quot;========================================\n&quot;);<br>
&gt; &gt;&gt;&gt; +       pr_info(&quot;Collecting VMAs of (pid: %d)\n&quot;, pid);<br>
&gt; &gt;&gt;&gt; +       pr_info(&quot;========================================\n&quot;);<br>
&gt; &gt;&gt;&gt; +<br>
&gt; &gt;&gt;&gt; +       if (item-&gt;pid-&gt;state == TASK_STOPPED) {<br>
&gt; &gt;&gt;&gt; +               pr_warn(&quot;Stopped tasks are not supported\n&quot;);<br>
&gt; &gt;&gt;&gt; +                    return 0;<br>
&gt; &gt;&gt;&gt; +            }<br>
&gt; &gt;&gt; Formatting.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;&gt; +<br>
&gt; &gt;&gt;&gt; +       if (item-&gt;pid-&gt;state == TASK_DEAD)<br>
&gt; &gt;&gt;&gt; +                    return 0;<br>
&gt; &gt;&gt; Vmas allocation can happen here.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;&gt; +<br>
&gt; &gt;&gt;&gt; +       ret = collect_mappings(pid, vmas, NULL);<br>
&gt; &gt;&gt;&gt; +       if (ret) {<br>
&gt; &gt;&gt;&gt; +               pr_err(&quot;Collect mappings (pid: %d) failed with %d\n&quot;, pid, ret);<br>
&gt; &gt;&gt;&gt; +               return -1;<br>
&gt; &gt;&gt;&gt; +            }<br>
&gt; &gt;&gt;&gt; +<br>
&gt; &gt;&gt;&gt; +       item-&gt;vmas = vmas;<br>
&gt; &gt;&gt;&gt; +       return 0;<br>
&gt; &gt;&gt;&gt; +}<br>
&gt; &gt;&gt;&gt; +<br>
&gt; &gt;&gt;&gt; +<br>
&gt; &gt;&gt;&gt; +static int unfreeze_pstree()<br>
&gt; &gt;&gt;&gt; +{<br>
&gt; &gt;&gt;&gt; +   InventoryEntry he = INVENTORY_ENTRY__INIT;<br>
&gt; &gt;&gt;&gt; +   int ret;<br>
&gt; &gt;&gt;&gt; +<br>
&gt; &gt;&gt;&gt; +   /*<br>
&gt; &gt;&gt;&gt; +    * Restore registers for tasks only. The threads have not been<br>
&gt; &gt;&gt;&gt; +    * infected. Therefore, the thread register sets have not been changed.<br>
&gt; &gt;&gt;&gt; +    */<br>
&gt; &gt;&gt;&gt; +   ret = arch_set_thread_regs(root_item, false);<br>
&gt; &gt;&gt;&gt; +   if (ret)<br>
&gt; &gt;&gt;&gt; +           return -1;<br>
&gt; &gt;&gt;&gt; +<br>
&gt; &gt;&gt;&gt; +   ret = inventory_save_uptime(&amp;he);<br>
&gt; &gt;&gt;&gt; +   if (ret)<br>
&gt; &gt;&gt;&gt; +           return -1;<br>
&gt; &gt;&gt;&gt; +<br>
&gt; &gt;&gt;&gt; +   if (write_img_inventory(&amp;he))<br>
&gt; &gt;&gt;&gt; +           return -1;<br>
&gt; &gt;&gt;&gt; +<br>
&gt; &gt;&gt;&gt; +   pstree_switch_state(root_item, TASK_ALIVE);<br>
&gt; &gt;&gt;&gt; +   timing_stop(TIME_FROZEN);<br>
&gt; &gt;&gt;&gt; +<br>
&gt; &gt;&gt;&gt; +   return 0;<br>
&gt; &gt;&gt;&gt; +}<br>
&gt; &gt;&gt;&gt; +<br>
&gt; &gt;&gt;&gt;   int cr_pre_dump_tasks(pid_t pid)<br>
&gt; &gt;&gt;&gt;   {<br>
&gt; &gt;&gt;&gt;     InventoryEntry *parent_ie = NULL;<br>
&gt; &gt;&gt;&gt; @@ -1619,6 +1660,16 @@ int cr_pre_dump_tasks(pid_t pid)<br>
&gt; &gt;&gt;&gt;     /* Errors handled later in detect_pid_reuse */<br>
&gt; &gt;&gt;&gt;     parent_ie = get_parent_inventory();<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt; +   /* Collecting VMAs of all processes in pstree */<br>
&gt; &gt;&gt;&gt; +   for_each_pstree_item(item)<br>
&gt; &gt;&gt;&gt; +           if (pre_dump_collect_vmas(item))<br>
&gt; &gt;&gt;&gt; +                   goto err;<br>
&gt; &gt;&gt;&gt; +<br>
&gt; &gt;&gt;&gt; +   /* Unfreeze pstree */<br>
&gt; &gt;&gt; This is pointless comment as it 100% repeats the subsequent function name :)<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;&gt; +   ret = unfreeze_pstree();<br>
&gt; &gt;&gt;&gt; +   if(ret)<br>
&gt; &gt;&gt;&gt; +           goto err;<br>
&gt; &gt;&gt;&gt; +<br>
&gt; &gt;&gt;&gt;     for_each_pstree_item(item)<br>
&gt; &gt;&gt;&gt;             if (pre_dump_one_task(item, parent_ie))<br>
&gt; &gt;&gt;&gt;                     goto err;<br>
&gt; &gt;&gt;&gt; diff --git a/criu/include/pstree.h b/criu/include/pstree.h<br>
&gt; &gt;&gt;&gt; index 7303c1fe..69562608 100644<br>
&gt; &gt;&gt;&gt; --- a/criu/include/pstree.h<br>
&gt; &gt;&gt;&gt; +++ b/criu/include/pstree.h<br>
&gt; &gt;&gt;&gt; @@ -30,6 +30,7 @@ struct pstree_item {<br>
&gt; &gt;&gt;&gt;             futex_t         task_st;<br>
&gt; &gt;&gt;&gt;             unsigned long   task_st_le_bits;<br>
&gt; &gt;&gt;&gt;     };<br>
&gt; &gt;&gt;&gt; +   struct vm_area_list *vmas;<br>
&gt; &gt;&gt; This is dump-only field, it should be placed on dmp_info instead.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;&gt;   };<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt;&gt;   static inline pid_t vpid(const struct pstree_item *i)<br>
&gt; &gt;&gt;&gt; --<br>
&gt; &gt;&gt;&gt; 2.17.1<br>
&gt; &gt;&gt;&gt;<br>
&gt; &gt;&gt; -- Pavel<br>
</blockquote></div>