On Sat, Jul 2, 2011 at 2:32 AM, Kevin Constantine
<[email protected]> wrote:
> 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 {
Here could you try not to get the controller, I know its weird and
will be fixed but as a work around could you try ignoring what
cgroup_get_cgroup() returned. Since you know what you want to write,
I'd recommend what you do in the retval != 0 path, but instead of
cgroup_create_cgroup(), do cgroup_modify_cgroup().
> 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: ");
> }
> }
> }
Balbir Singh
------------------------------------------------------------------------------
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/libcg-devel