<div dir="ltr">Ok, it&#39;s reasonable, will redo.<br>
</div><div dir="ltr"><br>
</div><div dir="ltr"><br>
</div><div dir="ltr"><br>
</div><div class="wps_signature">Best regards, Tikhomirov Pavel.</div><div class="wps_quotion">Dmitry Safonov &lt;0x7f454c46@gmail.com&gt; | От: 9 февр. 2018 г. 20:02 | Сообщение:<br type="attribution"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><p></p><p dir="ltr">2018-02-09 16:06 GMT+00:00 Pavel Tikhomirov &lt;<a href="mailto:ptikhomirov@virtuozzo.com">ptikhomirov@virtuozzo.com</a>&gt;: <br>
&gt; We have a problem when a pid is reused between consequent dumps we can&#39;t <br>
&gt; understand if pagemap and pages from images of parent dump are invalid <br>
&gt; to restore these pid already. That can lead even to wrong memory <br>
&gt; restored for these pid, see the test in last patch. <br>
&gt; <br>
&gt; So these is a try do separate processes with (likely) invalid previous <br>
&gt; memory dump from processes with 100% valid previous dump. <br>
&gt; <br>
&gt; For that we use the value of /proc/&lt;pid&gt;/stat&#39;s start_time and also the <br>
&gt; timestamp of each (pre)dump. If the start time is strictly less than the <br>
&gt; timestamp, that means that the pagemap for these pid from previous dump <br>
&gt; is valid - was done for exactly the same process. <br>
&gt; <br>
&gt; Creation time is in centiseconds by default so if predump is really fast <br>
&gt; (&lt;1csec) we can have false negative decisions for some processes, but in <br>
&gt; case of long running processes we are fine. <br>
&gt; <br>
&gt; <a href="https://jira.sw.ru/browse/PSBM-67502">https://jira.sw.ru/browse/PSBM-67502</a> <br>
&gt; <br>
&gt; Signed-off-by: Pavel Tikhomirov &lt;<a href="mailto:ptikhomirov@virtuozzo.com">ptikhomirov@virtuozzo.com</a>&gt; <br>
&gt; --- <br>
&gt;  criu/mem.c | 37 ++++++++++++++++++++++++++++++++++++- <br>
&gt;  1 file changed, 36 insertions(+), 1 deletion(-) <br>
&gt; <br>
&gt; diff --git a/criu/mem.c b/criu/mem.c <br>
&gt; index 4c6942a11..355c992c7 100644 <br>
&gt; --- a/criu/mem.c <br>
&gt; +++ b/criu/mem.c <br>
&gt; @@ -30,9 +30,11 @@ <br>
&gt;  #include &quot;fault-injection.h&quot; <br>
&gt;  #include &quot;prctl.h&quot; <br>
&gt;  #include &lt;compel/compel.h&gt; <br>
&gt; +#include &quot;proc_parse.h&quot; <br>
&gt; <br>
&gt;  #include &quot;protobuf.h&quot; <br>
&gt;  #include &quot;images/pagemap.pb-c.h&quot; <br>
&gt; +#include &quot;images/stats.pb-c.h&quot; <br>
&gt; <br>
&gt;  static int task_reset_dirty_track(int pid) <br>
&gt;  { <br>
&gt; @@ -303,6 +305,7 @@ static int __parasite_dump_pages_seized(struct pstree_item *item, <br>
&gt;         int ret = -1; <br>
&gt;         unsigned cpp_flags = 0; <br>
&gt;         unsigned long pmc_size; <br>
&gt; +       bool possible_pid_reuse = false; <br>
&gt; <br>
&gt;         if (opts.check_only) <br>
&gt;                 return 0; <br>
&gt; @@ -360,6 +363,38 @@ static int __parasite_dump_pages_seized(struct pstree_item *item, <br>
&gt;                         xfer.parent = NULL + 1; <br>
&gt;         } <br>
&gt; <br>
&gt; +       if (xfer.parent) { <br>
&gt; +               struct proc_pid_stat pps_buf; <br>
&gt; +               StatsEntry *stats = NULL; <br>
&gt; +               unsigned long dump_ticks; <br>
&gt; +               unsigned long clock_ticks; <br>
&gt; + <br>
&gt; +               clock_ticks = sysconf(_SC_CLK_TCK); <br>
&gt; +               if (clock_ticks == -1) { <br>
&gt; +                       pr_perror(&quot;Failed to get clock ticks via sysconf&quot;); <br>
&gt; +                       goto out_xfer; <br>
&gt; +               } <br>
&gt; + <br>
&gt; +               ret = parse_pid_stat(item-&gt;pid-&gt;real, &amp;pps_buf); <br>
&gt; +               if (ret &lt; 0) <br>
&gt; +                       goto out_xfer; <br>
&gt; + <br>
&gt; +               ret = get_parent_stats((void**)&amp;stats); <br>
&gt; +               if (ret &lt; 0) <br>
&gt; +                       goto out_xfer; <br>
&gt; +               dump_ticks = stats-&gt;dump-&gt;dump_uptime/(USEC_PER_SEC / clock_ticks); <br>
&gt; +               stats_entry__free_unpacked(stats, NULL); <br>
&gt; + <br>
&gt; +               if (pps_buf.start_time &gt;= dump_ticks) { <br>
&gt; +                       pr_warn(&quot;Detected possible pid reuse pid=%d, &quot; \ <br>
&gt; +                               &quot;start_time=%llu, parent&#39;s dump_uptime=%lu\n&quot;, <br>
&gt; +                               item-&gt;pid-&gt;real, pps_buf.start_time, <br>
&gt; +                               dump_ticks); <br>
&gt; +                       possible_pid_reuse = true; <br>
<br>
What the meaning of this warning in logs? <br>
Can we separate the two cases: <br>
1. pps_buf.start_time &gt; dump_ticks <br>
    Real pid-reuse, silently re-dumping pid. <br>
2. pps_buf.start_time == dump_ticks) <br>
    Warn that the reuse is possible and re-dump. <br>
<br>
For (2) we may really be interested how often it&#39;s happening <br>
because if it happens way too often - we might be interested <br>
in improving this detection.. Like inserting 1csec delay before <br>
saving uptime. <br>
<br>
--  <br>
             Dmitry <br>
</p>
</blockquote></div>