I'm seeing an issue with cgroup_modify_cgroup() and read-only values 
parameters.  The code below should be run twice to demonstrate the 
issue.  The first time through, cgroup_get_cgroup fails because the 
cgroup doesn't exist yet.  It then creates a cgroup /asdf with the 
memory and the cpuset controllers.  It sets memory.limit_in_bytes to 2G. 
  That all works as expected.

The second time you run it, cgroup_get_cgroup succeeds and we go try to 
modify memory.limit_in_bytes to be 4G.  cgroup_modify_cgroup() always 
seems to fail trying to write "0" to 
/cgroup/cpuset/asdf/cpuset.memory_pressure (a read-only parameter).

Here's a snippet of the failing strace:

munmap(0x7f168191a000, 4096)            = 0 <0.000015>
open("/cgroup/cpuset//asdf/cpuset.memory_pressure", O_RDWR) = 3 <0.000018>
fstat(3, {st_mode=S_IFREG|0775, st_size=0, ...}) = 0 <0.000011>
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) 
= 0x7f168191a000 <0.000012>
write(3, "0", 1)                        = -1 EACCES (Permission denied) 
<0.000012>
close(3)                                = 0 <0.000011>
munmap(0x7f168191a000, 4096)            = 0 <0.000015>
write(1, "Modify Error:  Cgroup operation "..., 39Modify Error:  Cgroup 
operation failed
) = 39 <0.000015>
exit_group(0)                           = ?

It looks like when cgroup_modify_cgroup() encounters an error, it 
immediately stops and returns an error which is why 
memory.limit_in_bytes never gets set to 4G the second time through.  Any 
suggestions on what to do in this situation?


Here's the code to reproduce the issue.

#include <iostream>
#include <string>
#include <libcgroup.h>


using namespace std;

void cgErrHandle(int retval, string msg) {
     if (retval == ECGOTHER) {
         cout << msg << " " << cgroup_strerror(cgroup_get_last_errno()) 
<< endl;
     } else if (retval != 0) {
         cout << msg << ": " << cgroup_strerror(retval) << endl;
     }
}

int main(int argc, char *argv[]){

     int retval = 0;
     retval = cgroup_init();
     cgErrHandle(retval, "init");
     if (retval != 0) {
         return false;
     }

     struct cgroup *tmpcg = NULL;
     tmpcg = cgroup_new_cgroup("/asdf");
     if (tmpcg == NULL) {
         printf("NULL");
     }
     retval = cgroup_get_cgroup(tmpcg);
     if (retval != 0) {
         cgroup_add_controller(tmpcg, "memory");
         cgroup_add_controller(tmpcg, "cpuset");
         retval = cgroup_set_value_string(cgroup_get_controller(tmpcg, 
"memory"), "memory.limit_in_bytes", "2G");
         cgErrHandle(retval, "setValue Error: ");
         retval = cgroup_set_value_string(cgroup_get_controller(tmpcg, 
"cpuset"), "cpuset.cpus", "1");
         cgErrHandle(retval, "setValue Error: ");
         retval = cgroup_create_cgroup(tmpcg, 0);
         cgErrHandle(retval, "create Error: ");
     } else {
         struct cgroup_controller *cgctrl = NULL;
         cgctrl = cgroup_get_controller(tmpcg, "memory");
         if (cgctrl == NULL) {
             printf("no memory controller");
         } else {
             cout << "modifying limit_in_bytes" << endl;
             retval = cgroup_set_value_string(cgctrl, 
"memory.limit_in_bytes", "4G");
             cout << retval << endl;
             cgErrHandle(retval, "setValue Error: ");
             retval = cgroup_modify_cgroup(tmpcg);
             cgErrHandle(retval, "Modify Error: ");
         }
     }
}

------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security 
threats, fraudulent activity, and more. Splunk takes this data and makes 
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2
_______________________________________________
Libcg-devel mailing list
Libcg-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to