<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Aug 13, 2014 at 1:55 PM, Tycho Andersen <span dir="ltr">&lt;<a href="mailto:tycho.andersen@canonical.com" target="_blank">tycho.andersen@canonical.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class="">On Wed, Aug 13, 2014 at 01:32:01PM -0700, Garrison Bellack wrote:<br>

&gt; On Wed, Aug 13, 2014 at 12:43 PM, Andrew Vagin &lt;<a href="mailto:avagin@parallels.com">avagin@parallels.com</a>&gt; wrote:<br>
&gt;<br>
&gt; &gt; On Wed, Aug 13, 2014 at 11:59:33AM -0700, <a href="mailto:gbellack@google.com">gbellack@google.com</a> wrote:<br>
&gt; &gt; &gt; From: Garrison Bellack &lt;<a href="mailto:gbellack@google.com">gbellack@google.com</a>&gt;<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; Because different kernel versions have different cgroup properties, criu<br>
&gt; &gt; &gt; shouldn&#39;t crash just because the properties statically listed aren&#39;t<br>
&gt; &gt; exact.<br>
&gt; &gt; &gt; Instead, during dump, ignore properties the kernel doesn&#39;t have and<br>
&gt; &gt; continue.<br>
&gt; &gt; &gt; In addition, during restore, in the event of migration to a kernel that<br>
&gt; &gt; is<br>
&gt; &gt; &gt; missing a property that was dumped, print an error but continue.<br>
&gt; &gt;<br>
&gt; &gt; I am not sure that we can continue in this case. Why do you think that<br>
&gt; &gt; it&#39;s safe? I think we need to ask a user about this. So can we add a new<br>
&gt; &gt; option to allow continuing in this case?<br>
&gt;<br>
&gt;<br>
&gt; I&#39;m a little confused about your concerns of safety. Are you referring to<br>
&gt; missing properties on the dump or restore side?<br>
<br>
</div>I think restore side. I also wondered the same thing -- it seems that<br>
missing properties on restore should be an error (perhaps as Andrew<br>
says with an --allow-missing-cg-props flag on the restore side to<br>
allow you to override this error).</blockquote><div><br></div><div>Here is the reasoning behind this decision. Let say you are migrating properties A,B,C,D where B doesn&#39;t exist.</div><div><br></div><div>This is how it currently works:</div>
<div>A will be restored. B prints an error and causes failure because it is missing. However, because cgroup property restoration is the last thing to happen during restore, and because of designs further up the call chain, the restoration of the process still goes through. C,D are not restored because of previous criu failure.</div>
<div>End result -- Process and property A restored, C and D are not restored even though they exist on the new machine</div><div><br></div><div>With this patch:</div><div>A will be restored. B prints an error and continues. C and D are restored.</div>
<div>End result --  Process and property A, C, D all restored.</div><div><br></div><div>I think between these two options we clearly prefer the later behavior.</div><div>  </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<span class=""><font color="#888888"><br></font></span><div class=""><div class="h5">
&gt;<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; Change-Id: I5a8b93d6a8a3a9664914f10cf8e2110340dd8b31<br>
&gt; &gt; &gt; Signed-off-by: Garrison Bellack &lt;<a href="mailto:gbellack@google.com">gbellack@google.com</a>&gt;<br>
&gt; &gt; &gt; ---<br>
&gt; &gt; &gt;  cgroup.c | 40 ++++++++++++++++++++++++++--------------<br>
&gt; &gt; &gt;  1 file changed, 26 insertions(+), 14 deletions(-)<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; diff --git a/cgroup.c b/cgroup.c<br>
&gt; &gt; &gt; index f8dbbde..b727a50 100644<br>
&gt; &gt; &gt; --- a/cgroup.c<br>
&gt; &gt; &gt; +++ b/cgroup.c<br>
&gt; &gt; &gt; @@ -284,35 +284,30 @@ static int find_dir(const char *path, struct<br>
&gt; &gt; list_head *dirs, struct cgroup_dir<br>
&gt; &gt; &gt;   * Currently this function only supports properties that have 1 value,<br>
&gt; &gt; under 100<br>
&gt; &gt; &gt;   * chars<br>
&gt; &gt; &gt;   */<br>
&gt; &gt; &gt; -static int read_cgroup_prop(struct cgroup_prop *property, const char<br>
&gt; &gt; *fpath)<br>
&gt; &gt; &gt; +static int read_cgroup_prop(struct cgroup_prop *property, const char<br>
&gt; &gt; *fullpath)<br>
&gt; &gt; &gt;  {<br>
&gt; &gt; &gt; -     char pbuf[PATH_MAX], buf[100];<br>
&gt; &gt; &gt; +     char buf[100];<br>
&gt; &gt; &gt;       FILE *f;<br>
&gt; &gt; &gt;       char *endptr;<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; -     if (snprintf(pbuf, PATH_MAX, &quot;%s/%s&quot;, fpath, property-&gt;name) &gt;=<br>
&gt; &gt; PATH_MAX) {<br>
&gt; &gt; &gt; -             pr_err(&quot;snprintf output was truncated&quot;);<br>
&gt; &gt; &gt; -             return -1;<br>
&gt; &gt; &gt; -     }<br>
&gt; &gt; &gt; -<br>
&gt; &gt; &gt; -     f = fopen(pbuf, &quot;r&quot;);<br>
&gt; &gt; &gt; +     f = fopen(fullpath, &quot;r&quot;);<br>
&gt; &gt; &gt;       if (!f) {<br>
&gt; &gt; &gt; -             pr_err(&quot;Failed opening %s\n&quot;, pbuf);<br>
&gt; &gt; &gt;               property-&gt;value = NULL;<br>
&gt; &gt; &gt; +             pr_perror(&quot;Failed opening %s\n&quot;, fullpath);<br>
&gt; &gt; &gt;               return -1;<br>
&gt; &gt; &gt;       }<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;       memset(buf, 0, sizeof(buf));<br>
&gt; &gt; &gt;       if (fread(buf, sizeof(buf), 1, f) != 1) {<br>
&gt; &gt; &gt;               if (!feof(f)) {<br>
&gt; &gt; &gt; -                     pr_err(&quot;Failed scanning %s\n&quot;, pbuf);<br>
&gt; &gt; &gt; +                     pr_err(&quot;Failed scanning %s\n&quot;, fullpath);<br>
&gt; &gt; &gt;                       fclose(f);<br>
&gt; &gt; &gt;                       return -1;<br>
&gt; &gt; &gt;               }<br>
&gt; &gt; &gt;       }<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;       if (fclose(f) != 0) {<br>
&gt; &gt; &gt; -             pr_err(&quot;Failed closing %s\n&quot;, pbuf);<br>
&gt; &gt; &gt; +             pr_err(&quot;Failed closing %s\n&quot;, fullpath);<br>
&gt; &gt; &gt;               return -1;<br>
&gt; &gt; &gt;       }<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; @@ -390,6 +385,7 @@ static int add_cgroup_properties(const char *fpath,<br>
&gt; &gt; struct cgroup_dir *ncd,<br>
&gt; &gt; &gt;                                struct cg_controller *controller)<br>
&gt; &gt; &gt;  {<br>
&gt; &gt; &gt;       int i, j;<br>
&gt; &gt; &gt; +     char buf[PATH_MAX];<br>
&gt; &gt; &gt;       struct cgroup_prop *prop;<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;       for (i = 0; i &lt; controller-&gt;n_controllers; ++i) {<br>
&gt; &gt; &gt; @@ -397,16 +393,28 @@ static int add_cgroup_properties(const char<br>
&gt; &gt; *fpath, struct cgroup_dir *ncd,<br>
&gt; &gt; &gt;               const char **prop_arr =<br>
&gt; &gt; get_known_properties(controller-&gt;controllers[i]);<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;               for (j = 0; prop_arr != NULL &amp;&amp; prop_arr[j] != NULL; ++j) {<br>
&gt; &gt; &gt; +                     if (snprintf(buf, PATH_MAX, &quot;%s/%s&quot;, fpath,<br>
&gt; &gt; prop_arr[j]) &gt;= PATH_MAX) {<br>
&gt; &gt; &gt; +                             pr_err(&quot;snprintf output was truncated&quot;);<br>
&gt; &gt; &gt; +                             return -1;<br>
&gt; &gt; &gt; +                     }<br>
&gt; &gt; &gt; +<br>
&gt; &gt; &gt; +                     if (access(buf, F_OK) &lt; 0 &amp;&amp; errno == ENOENT) {<br>
&gt; &gt; &gt; +                             pr_info(&quot;Couldn&#39;t open %s. This cgroup<br>
&gt; &gt; property may not exist on this kernel\n&quot;, buf);<br>
&gt; &gt; &gt; +                             continue;<br>
&gt; &gt; &gt; +                     }<br>
&gt; &gt; &gt; +<br>
&gt; &gt; &gt;                       prop = create_cgroup_prop(prop_arr[j]);<br>
&gt; &gt; &gt;                       if (!prop) {<br>
&gt; &gt; &gt;                               free_all_cgroup_props(ncd);<br>
&gt; &gt; &gt;                               return -1;<br>
&gt; &gt; &gt;                       }<br>
&gt; &gt; &gt; -                     if (read_cgroup_prop(prop, fpath) &lt; 0) {<br>
&gt; &gt; &gt; +<br>
&gt; &gt; &gt; +                     if (read_cgroup_prop(prop, buf) &lt; 0) {<br>
&gt; &gt; &gt;                               free_cgroup_prop(prop);<br>
&gt; &gt; &gt;                               free_all_cgroup_props(ncd);<br>
&gt; &gt; &gt;                               return -1;<br>
&gt; &gt; &gt;                       }<br>
&gt; &gt; &gt; +<br>
&gt; &gt; &gt;                       pr_info(&quot;Dumping value %s from %s/%s\n&quot;,<br>
&gt; &gt; prop-&gt;value, fpath, prop-&gt;name);<br>
&gt; &gt; &gt;                       list_add_tail(&amp;prop-&gt;list, &amp;ncd-&gt;properties);<br>
&gt; &gt; &gt;                       ncd-&gt;n_properties++;<br>
&gt; &gt; &gt; @@ -924,8 +932,12 @@ static int restore_cgroup_prop(const<br>
&gt; &gt; CgroupPropEntry * cg_prop_entry_p,<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;       f = fopenat(cg, path, &quot;w+&quot;);<br>
&gt; &gt; &gt;       if (!f) {<br>
&gt; &gt; &gt; -             pr_perror(&quot;Failed opening %s for writing\n&quot;, path);<br>
&gt; &gt; &gt; -             return -1;<br>
&gt; &gt; &gt; +             if (errno != ENOENT) {<br>
&gt; &gt; &gt; +                     pr_perror(&quot;Failed opening %s\n&quot;, path);<br>
&gt; &gt; &gt; +                     return -1;<br>
&gt; &gt; &gt; +             }<br>
&gt; &gt; &gt; +             pr_perror(&quot;Couldn&#39;t open %s. This cgroup property may not<br>
&gt; &gt; exist on this kernel\n&quot;, path);<br>
&gt; &gt; &gt; +             return 0;<br>
&gt; &gt; &gt;       }<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;       if (fprintf(f, &quot;%s&quot;, cg_prop_entry_p-&gt;value) &lt; 0) {<br>
&gt; &gt; &gt; --<br>
&gt; &gt; &gt; 2.1.0.rc2.206.gedb03e5<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; _______________________________________________<br>
&gt; &gt; &gt; CRIU mailing list<br>
&gt; &gt; &gt; <a href="mailto:CRIU@openvz.org">CRIU@openvz.org</a><br>
&gt; &gt; &gt; <a href="https://lists.openvz.org/mailman/listinfo/criu" target="_blank">https://lists.openvz.org/mailman/listinfo/criu</a><br>
&gt; &gt;<br>
<br>
&gt; _______________________________________________<br>
&gt; CRIU mailing list<br>
&gt; <a href="mailto:CRIU@openvz.org">CRIU@openvz.org</a><br>
&gt; <a href="https://lists.openvz.org/mailman/listinfo/criu" target="_blank">https://lists.openvz.org/mailman/listinfo/criu</a><br>
<br>
</div></div></blockquote></div><br></div></div>