<div dir="ltr">I have made the changes you requested. The exact properties to be restored are actually different here internally and I&#39;m not sure specifically which properties upstream wants included and which they don&#39;t, can I send the completion of the properties list as a separate patch? For now I have separated them and I will send both patches momentarily. </div>
<div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Aug 5, 2014 at 10:58 PM, Pavel Emelyanov <span dir="ltr">&lt;<a href="mailto:xemul@parallels.com" target="_blank">xemul@parallels.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="">On 08/05/2014 11:50 PM, <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; Restores 2 cgroup properties after the criu restoration of tasks.<br>
&gt; Currently the cgroup files to be restored are static but<br>
&gt; are easily extendable. If a cgroup exists during restoration,<br>
&gt; its properties will not be overwritten.<br>
&gt; Work based off Tycho Anderson <a href="mailto:tycho.andersen@canonical.com">tycho.andersen@canonical.com</a><br>
<br>
</div>Thanks, Garrison! I like the patch, only a couple of small comments inline.<br>
<div class=""><br>
&gt; --- a/cgroup.c<br>
&gt; +++ b/cgroup.c<br>
&gt; @@ -20,6 +20,23 @@<br>
&gt;  #include &quot;protobuf/cgroup.pb-c.h&quot;<br>
&gt;<br>
&gt;  /*<br>
&gt; + * These string arrays have the names of all the properties that will be<br>
&gt; + * restored. To add a property for a cgroup type, add it to the<br>
&gt; + * corresponding char array above the NULL terminator.<br>
&gt; + * Currently the code only supports properties with 1 value<br>
&gt; + */<br>
&gt; +<br>
&gt; +static const char *cpu_props[] = {<br>
&gt; +     &quot;cpu.shares&quot;,<br>
&gt; +     NULL<br>
&gt; +};<br>
&gt; +<br>
&gt; +static const char *memory_props[] = {<br>
&gt; +     &quot;memory.limit_in_bytes&quot;,<br>
&gt; +     NULL<br>
&gt; +};<br>
<br>
</div>Would you accomplish these lists?<br>
<div class=""><br>
&gt; +<br>
&gt; +/*<br>
&gt;   * This structure describes set of controller groups<br>
&gt;   * a task lives in. The cg_ctl entries are stored in<br>
&gt;   * the @ctls list sorted by the .name field and then<br>
<br>
</div><div class="">&gt; @@ -267,6 +407,16 @@ static int add_cgroup(const char *fpath, const struct stat *sb, int typeflag)<br>
&gt;<br>
&gt;               INIT_LIST_HEAD(&amp;ncd-&gt;children);<br>
&gt;               ncd-&gt;n_children = 0;<br>
&gt; +<br>
&gt; +             INIT_LIST_HEAD(&amp;ncd-&gt;properties);<br>
&gt; +             ncd-&gt;n_properties = 0;<br>
&gt; +             if (add_cgroup_properties(fpath, &amp;ncd-&gt;properties,<br>
&gt; +                                       &amp;ncd-&gt;n_properties,<br>
&gt; +                                       current_controller) &lt; 0) {<br>
<br>
</div>Presumably we can feed the ncd itself into add_cgroup_properties and<br>
let the latter init and set list and n_properties itself.<br>
<div class=""><br>
&gt; +                     ret = -1;<br>
&gt; +                     goto out;<br>
&gt; +             }<br>
&gt; +<br>
&gt;               return 0;<br>
&gt;       } else<br>
&gt;               return 0;<br>
<br>
</div><div class="">&gt; @@ -659,6 +857,126 @@ void fini_cgroup(void)<br>
&gt;       xfree(cg_yard);<br>
&gt;  }<br>
&gt;<br>
&gt; +static int restore_cgroup_prop(const CgroupPropEntry * cg_prop_entry_p,<br>
&gt; +                            const char *cname, const char *dir, const int *cg_p)<br>
&gt; +{<br>
&gt; +     char path[PATH_MAX];<br>
&gt; +     FILE *f;<br>
&gt; +<br>
&gt; +     if (!cg_prop_entry_p-&gt;value)<br>
<br>
</div>How can this happen? Would you add a code comment here?<br>
<div><div class="h5"><br>
&gt; +             return 0;<br>
&gt; +<br>
&gt; +     if (snprintf(path, PATH_MAX, &quot;%s/%s/%s&quot;, cname, dir, cg_prop_entry_p-&gt;name) &gt;= PATH_MAX) {<br>
&gt; +             pr_err(&quot;snprintf output was truncated for %s\n&quot;, cg_prop_entry_p-&gt;name);<br>
&gt; +             return -1;<br>
&gt; +     }<br>
&gt; +<br>
&gt; +     f = fopenat(*cg_p, 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; +     }<br>
&gt; +<br>
&gt; +     if (fprintf(f, &quot;%s&quot;, cg_prop_entry_p-&gt;value) &lt; 0) {<br>
&gt; +             fclose(f);<br>
&gt; +             pr_err(&quot;Failed writing %s to %s\n&quot;, cg_prop_entry_p-&gt;value, path);<br>
&gt; +             return -1;<br>
&gt; +     }<br>
&gt; +<br>
&gt; +     if (fclose(f) != 0) {<br>
&gt; +             pr_err(&quot;Failed closing %s\n&quot;, path);<br>
&gt; +             return -1;<br>
&gt; +     }<br>
&gt; +<br>
&gt; +     pr_info(&quot;Restored cgroup property value %s to %s\n&quot;, cg_prop_entry_p-&gt;value, path);<br>
&gt; +     return 0;<br>
&gt; +}<br>
&gt; +<br>
&gt; +static int prepare_cgroup_dir_properties(char *controller, CgroupDirEntry **ents,<br>
&gt; +                                      unsigned int n_ents)<br>
&gt; +{<br>
&gt; +     unsigned int i, j;<br>
&gt; +     int cg;<br>
&gt; +<br>
&gt; +     cg = get_service_fd(CGROUP_YARD);<br>
&gt; +<br>
&gt; +     for (i = 0; i &lt; n_ents; i++) {<br>
&gt; +             CgroupDirEntry *e = ents[i];<br>
&gt; +<br>
&gt; +             /*<br>
&gt; +              * Check to see if we made e-&gt;properties NULL during restore<br>
&gt; +              * because directory already existed and as such we don&#39;t want to<br>
&gt; +              * change its properties<br>
&gt; +              */<br>
&gt; +             if (e-&gt;properties) {<br>
&gt; +                     for (j = 0; j &lt; e-&gt;n_properties; ++j) {<br>
&gt; +                             if (restore_cgroup_prop(e-&gt;properties[j], controller, e-&gt;path, &amp;cg) &lt; 0)<br>
<br>
</div></div>The cg can be passed as value, instead of pointer.<br>
<div class=""><br>
&gt; +                                     return -1;<br>
&gt; +                     }<br>
&gt; +             }<br>
&gt; +<br>
&gt; +             if (prepare_cgroup_dir_properties(controller, e-&gt;children, e-&gt;n_children) &lt; 0)<br>
&gt; +                     return -1;<br>
&gt; +     }<br>
&gt; +<br>
&gt; +     return 0;<br>
&gt; +}<br>
<br>
</div><div class="">&gt; --- a/protobuf/cgroup.proto<br>
&gt; +++ b/protobuf/cgroup.proto<br>
&gt; @@ -1,6 +1,12 @@<br>
&gt; +message cgroup_prop_entry {<br>
&gt; +     required string                 name            = 1;<br>
&gt; +     required string                 value           = 2;<br>
&gt; +}<br>
&gt; +<br>
&gt;  message cgroup_dir_entry {<br>
&gt;       required string                 path            = 1;<br>
&gt; -     repeated cgroup_dir_entry       children        = 4;<br>
&gt; +     repeated cgroup_dir_entry       children        = 2;<br>
<br>
</div>I&#39;d appreciate if protobuf field renumbering goes in separate (quite small) patch.<br>
<div class="HOEnZb"><div class="h5"><br>
&gt; +     repeated cgroup_prop_entry      properties      = 3;<br>
&gt;  }<br>
&gt;<br>
&gt;  message cg_controller_entry {<br>
&gt;<br>
<br>
</div></div></blockquote></div><br></div>