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