]> git.ipfire.org Git - thirdparty/libcgroup.git/commit
api.c: write dirty settings only in cgroup_set_values_recursive()
authorKamalesh Babulal <kamalesh.babulal@oracle.com>
Tue, 21 Mar 2023 09:04:46 +0000 (09:04 +0000)
committerTom Hromatka <tom.hromatka@oracle.com>
Thu, 23 Mar 2023 18:26:42 +0000 (12:26 -0600)
commit58fbebc0ec73e170381ffe13d8f2dfbfcbe41cf4
tree2b8800271d9ccebd360cb37fe398077d23bc790f
parent749adba530fa3a3ec5e0948381d14109b97ac591
api.c: write dirty settings only in cgroup_set_values_recursive()

cgroup_set_values_recursive() is called by cgroup_modify_cgroup() to
modify controller values, where all the settings modified or not are
written to the disk.  This breaks when writing a new value of a setting
that is linked to another setting of the controller, followed by writing
an unmodified value to the linked setting. This effectively undoes the
modification. For example, consider two linked settings of the cpu
controller: cpu.weight and cpu.weight.nice, where writing the new value
of cpu.weight is followed by unmodified cpu.weight.nice value. Writing
of the latter will undo the new value of the former.

Reproducer:
-----------

int print_cpu_weight()
{
        FILE *fp;
        char value[10];

        fp = fopen(PROC_CPU_WEIGHT, "r");
        if (!fp) {
                fprintf(stderr, "Failed to open %s\n", PROC_CPU_WEIGHT);
                return 1;
        }

        fgets(value, 10, fp);
        fprintf(stderr, "cpu.weight %s", value);
        fclose(fp);

        return 0;
}

int main(void)
{
        struct cgroup_controller *cgc;
        struct cgroup *cgroup;
        int ret;

        ret = cgroup_init();
        if (ret) {
                fprintf(stderr, "cgroup initialization failed\n");
                exit (1);
        }

         /* Create */
        cgroup = cgroup_new_cgroup(CGRP_NAME);
        if (!cgroup) {
                fprintf(stderr, "Failed to allocate cgroup %s\n", CGRP_NAME);
                exit(1);
        }

        cgc = cgroup_add_controller(cgroup, CTRL_NAME);
        if (!cgc) {
                fprintf(stderr, "Failed to add controller %s\n", CTRL_NAME);
                exit (1);
        }

        ret = cgroup_create_cgroup(cgroup, 0);
        if (ret) {
                fprintf(stderr, "Failed to create cgroup %s\n", CGRP_NAME);
                goto out;
        }

        ret = print_cpu_weight();
        if (ret)
                goto out;

        cgroup_free(&cgroup);

        /* Load and modify */
        cgroup = cgroup_new_cgroup(CGRP_NAME);
        if (!cgroup) {
                fprintf(stderr, "Failed to allocate cgroup %s\n", CGRP_NAME);
                exit(1);
        }

        ret = cgroup_get_cgroup(cgroup);
        if (ret) {
                fprintf(stderr, "Failed to get cgroup %s\n", CGRP_NAME);
                goto out;
        }

        cgc = NULL;
        cgc = cgroup_get_controller(cgroup, CTRL_NAME);
        if (!cgc) {
                fprintf(stderr, "Failed to get controller %s\n", CTRL_NAME);
                exit (1);
        }

        ret = cgroup_set_value_string(cgc, CTRL_SETTING, "8");
        if (ret) {
                fprintf(stderr, "Failed to set the %s value\n", CTRL_SETTING);
                goto out;
        }

        ret = cgroup_modify_cgroup(cgroup);
        if (ret) {
                fprintf(stderr, "Failed to modify cgroup\n");\
                goto out;
        }

        ret = print_cpu_weight();
        if (ret)
                goto out;

out:
        cgroup_free(&cgroup);
        return 0;
}

This patch additionally cleans up cgroup_set_values_recursive(), by
renaming the third argument ignore_non_dirty_failure to
ignore_non_dirty_values.  This rename also changes the purpose of the
flag, where the calling functions, set it to ignore the writing of the
controller setting, which is not modified/dirty and introduces extensive
checks for writing the controller setting.

Fixes: https://github.com/libcgroup/libcgroup/issues/323
Reported-by: Justin Israel <justinisrael@gmail.com>
[Justin contributed to the reproducer]
Signed-off-by: Kamalesh Babulal <kamalesh.babulal@oracle.com>
Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
(cherry picked from commit 395f942761061fc8605b6555cf9d66836633f8db)
src/api.c