<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Aug 13, 2014 at 12:43 PM, Andrew Vagin <span dir="ltr">&lt;<a href="mailto:avagin@parallels.com" target="_blank">avagin@parallels.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 11:59:33AM -0700, <a href="mailto:gbellack@google.com">gbellack@google.com</a> wrote:<br>

&gt; From: Garrison Bellack &lt;<a href="mailto:gbellack@google.com">gbellack@google.com</a>&gt;<br>
&gt;<br>
&gt; Because different kernel versions have different cgroup properties, criu<br>
&gt; shouldn&#39;t crash just because the properties statically listed aren&#39;t exact.<br>
&gt; Instead, during dump, ignore properties the kernel doesn&#39;t have and continue.<br>
&gt; In addition, during restore, in the event of migration to a kernel that is<br>
&gt; missing a property that was dumped, print an error but continue.<br>
<br>
</div>I am not sure that we can continue in this case. Why do you think that<br>
it&#39;s safe? I think we need to ask a user about this. So can we add a new<br>
option to allow continuing in this case?</blockquote><div><br></div><div>I&#39;m a little confused about your concerns of safety. Are you referring to missing properties on the dump or restore side?</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">
<div><div class="h5">
&gt;<br>
&gt; Change-Id: I5a8b93d6a8a3a9664914f10cf8e2110340dd8b31<br>
&gt; Signed-off-by: Garrison Bellack &lt;<a href="mailto:gbellack@google.com">gbellack@google.com</a>&gt;<br>
&gt; ---<br>
&gt;  cgroup.c | 40 ++++++++++++++++++++++++++--------------<br>
&gt;  1 file changed, 26 insertions(+), 14 deletions(-)<br>
&gt;<br>
&gt; diff --git a/cgroup.c b/cgroup.c<br>
&gt; index f8dbbde..b727a50 100644<br>
&gt; --- a/cgroup.c<br>
&gt; +++ b/cgroup.c<br>
&gt; @@ -284,35 +284,30 @@ static int find_dir(const char *path, struct list_head *dirs, struct cgroup_dir<br>
&gt;   * Currently this function only supports properties that have 1 value, under 100<br>
&gt;   * chars<br>
&gt;   */<br>
&gt; -static int read_cgroup_prop(struct cgroup_prop *property, const char *fpath)<br>
&gt; +static int read_cgroup_prop(struct cgroup_prop *property, const char *fullpath)<br>
&gt;  {<br>
&gt; -     char pbuf[PATH_MAX], buf[100];<br>
&gt; +     char buf[100];<br>
&gt;       FILE *f;<br>
&gt;       char *endptr;<br>
&gt;<br>
&gt; -     if (snprintf(pbuf, PATH_MAX, &quot;%s/%s&quot;, fpath, property-&gt;name) &gt;= PATH_MAX) {<br>
&gt; -             pr_err(&quot;snprintf output was truncated&quot;);<br>
&gt; -             return -1;<br>
&gt; -     }<br>
&gt; -<br>
&gt; -     f = fopen(pbuf, &quot;r&quot;);<br>
&gt; +     f = fopen(fullpath, &quot;r&quot;);<br>
&gt;       if (!f) {<br>
&gt; -             pr_err(&quot;Failed opening %s\n&quot;, pbuf);<br>
&gt;               property-&gt;value = NULL;<br>
&gt; +             pr_perror(&quot;Failed opening %s\n&quot;, fullpath);<br>
&gt;               return -1;<br>
&gt;       }<br>
&gt;<br>
&gt;       memset(buf, 0, sizeof(buf));<br>
&gt;       if (fread(buf, sizeof(buf), 1, f) != 1) {<br>
&gt;               if (!feof(f)) {<br>
&gt; -                     pr_err(&quot;Failed scanning %s\n&quot;, pbuf);<br>
&gt; +                     pr_err(&quot;Failed scanning %s\n&quot;, fullpath);<br>
&gt;                       fclose(f);<br>
&gt;                       return -1;<br>
&gt;               }<br>
&gt;       }<br>
&gt;<br>
&gt;       if (fclose(f) != 0) {<br>
&gt; -             pr_err(&quot;Failed closing %s\n&quot;, pbuf);<br>
&gt; +             pr_err(&quot;Failed closing %s\n&quot;, fullpath);<br>
&gt;               return -1;<br>
&gt;       }<br>
&gt;<br>
&gt; @@ -390,6 +385,7 @@ static int add_cgroup_properties(const char *fpath, struct cgroup_dir *ncd,<br>
&gt;                                struct cg_controller *controller)<br>
&gt;  {<br>
&gt;       int i, j;<br>
&gt; +     char buf[PATH_MAX];<br>
&gt;       struct cgroup_prop *prop;<br>
&gt;<br>
&gt;       for (i = 0; i &lt; controller-&gt;n_controllers; ++i) {<br>
&gt; @@ -397,16 +393,28 @@ static int add_cgroup_properties(const char *fpath, struct cgroup_dir *ncd,<br>
&gt;               const char **prop_arr = get_known_properties(controller-&gt;controllers[i]);<br>
&gt;<br>
&gt;               for (j = 0; prop_arr != NULL &amp;&amp; prop_arr[j] != NULL; ++j) {<br>
&gt; +                     if (snprintf(buf, PATH_MAX, &quot;%s/%s&quot;, fpath, prop_arr[j]) &gt;= PATH_MAX) {<br>
&gt; +                             pr_err(&quot;snprintf output was truncated&quot;);<br>
&gt; +                             return -1;<br>
&gt; +                     }<br>
&gt; +<br>
&gt; +                     if (access(buf, F_OK) &lt; 0 &amp;&amp; errno == ENOENT) {<br>
&gt; +                             pr_info(&quot;Couldn&#39;t open %s. This cgroup property may not exist on this kernel\n&quot;, buf);<br>
&gt; +                             continue;<br>
&gt; +                     }<br>
&gt; +<br>
&gt;                       prop = create_cgroup_prop(prop_arr[j]);<br>
&gt;                       if (!prop) {<br>
&gt;                               free_all_cgroup_props(ncd);<br>
&gt;                               return -1;<br>
&gt;                       }<br>
&gt; -                     if (read_cgroup_prop(prop, fpath) &lt; 0) {<br>
&gt; +<br>
&gt; +                     if (read_cgroup_prop(prop, buf) &lt; 0) {<br>
&gt;                               free_cgroup_prop(prop);<br>
&gt;                               free_all_cgroup_props(ncd);<br>
&gt;                               return -1;<br>
&gt;                       }<br>
&gt; +<br>
&gt;                       pr_info(&quot;Dumping value %s from %s/%s\n&quot;, prop-&gt;value, fpath, prop-&gt;name);<br>
&gt;                       list_add_tail(&amp;prop-&gt;list, &amp;ncd-&gt;properties);<br>
&gt;                       ncd-&gt;n_properties++;<br>
&gt; @@ -924,8 +932,12 @@ static int restore_cgroup_prop(const CgroupPropEntry * cg_prop_entry_p,<br>
&gt;<br>
&gt;       f = fopenat(cg, path, &quot;w+&quot;);<br>
&gt;       if (!f) {<br>
&gt; -             pr_perror(&quot;Failed opening %s for writing\n&quot;, path);<br>
&gt; -             return -1;<br>
&gt; +             if (errno != ENOENT) {<br>
&gt; +                     pr_perror(&quot;Failed opening %s\n&quot;, path);<br>
&gt; +                     return -1;<br>
&gt; +             }<br>
&gt; +             pr_perror(&quot;Couldn&#39;t open %s. This cgroup property may not exist on this kernel\n&quot;, path);<br>
&gt; +             return 0;<br>
&gt;       }<br>
&gt;<br>
&gt;       if (fprintf(f, &quot;%s&quot;, cg_prop_entry_p-&gt;value) &lt; 0) {<br>
&gt; --<br>
&gt; 2.1.0.rc2.206.gedb03e5<br>
&gt;<br>
</div></div>&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>
</blockquote></div><br></div></div>