Git Product home page Git Product logo

libcgroup's Introduction

Build Status Coverage Status Doxygen Documentation CodeQL

The entire libcgroup README is available here.

libcgroup's People

Contributors

adriaan42 avatar blueness avatar bsingharora avatar dependabot[bot] avatar drakenclimber avatar ebrower avatar elenril avatar giani avatar hutarova avatar inguin avatar ingvagabund avatar ioggstream avatar jamacku avatar jbernard avatar jrfastab avatar jsafrane avatar justinfx avatar kamalesh-babulal avatar kaysievers avatar kloczek avatar kraj avatar masayukig avatar miska avatar nelhage avatar nforro avatar poettering avatar rossburton avatar thesamesam avatar wengmeiling avatar werkov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libcgroup's Issues

0.42.2: autoreconf warnings

autoreconf: Entering directory `.'
autoreconf: configure.in: not using Gettext
autoreconf: running: aclocal --force -I m4
aclocal: warning: autoconf input should be named 'configure.ac', not 'configure.in'
autoreconf: configure.in: tracing
autoreconf: configure.in: creating directory build-aux
autoreconf: running: libtoolize --copy --force
aclocal: warning: autoconf input should be named 'configure.ac', not 'configure.in'
autoreconf: running: /usr/bin/autoconf --force
autoreconf: running: /usr/bin/autoheader --force
autoreconf: running: automake --add-missing --copy --force-missing
automake: warning: autoconf input should be named 'configure.ac', not 'configure.in'
configure.in:35: installing 'build-aux/ar-lib'
configure.in:35: installing 'build-aux/compile'
configure.in:36: installing 'build-aux/config.guess'
configure.in:36: installing 'build-aux/config.sub'
configure.in:23: installing 'build-aux/install-sh'
configure.in:23: installing 'build-aux/missing'
automake: warning: autoconf input should be named 'configure.ac', not 'configure.in'
src/Makefile.am:16: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
src/Makefile.am: installing 'build-aux/depcomp'
configure.in: installing 'build-aux/ylwrap'
src/bindings/Makefile.am:2: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
src/daemon/Makefile.am:1: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
src/pam/Makefile.am:1: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
src/tools/Makefile.am:3: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
tests/Makefile.am:3: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
parallel-tests: installing 'build-aux/test-driver'
autoreconf: Leaving directory `.'

0.42.2: compile time warnings

gcc 10

/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src/parse.y:48.14-15: warning: POSIX yacc reserves %type to nonterminals [-Wyacc]
   48 | %type <name> ID DEFAULT group_name
      |              ^~
/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src/parse.y:48.17-23: warning: POSIX yacc reserves %type to nonterminals [-Wyacc]
   48 | %type <name> ID DEFAULT group_name
      |                 ^~~~~~~
/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src/parse.y: warning: 4 shift/reduce conflicts [-Wconflicts-sr]
wrapper.c: In function 'cgroup_add_value_string':
wrapper.c:199:50: warning: format '%d' expects argument of type 'int', but argument 3 has type 'long unsigned int' [-Wformat=]
  199 |   fprintf(stderr, "value exceeds the maximum of %d characters\n",
      |                                                 ~^
      |                                                  |
      |                                                  int
      |                                                 %ld
  200 |    sizeof(cntl_value->value) - 1);
      |    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |    |
      |    long unsigned int
wrapper.c: In function 'cgroup_add_value_string':
wrapper.c:199:50: warning: format '%d' expects argument of type 'int', but argument 3 has type 'long unsigned int' [-Wformat=]
  199 |   fprintf(stderr, "value exceeds the maximum of %d characters\n",
      |                                                 ~^
      |                                                  |
      |                                                  int
      |                                                 %ld
  200 |    sizeof(cntl_value->value) - 1);
      |    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |    |
      |    long unsigned int
api.c: In function 'cgroup_change_cgroup_flags':
api.c:3585:37: warning: passing argument 1 of '__xpg_basename' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
 3585 |      if(procname && strlen(basename(procname))) {
      |                                     ^~~~~~~~
In file included from api.c:48:
/usr/include/libgen.h:34:36: note: expected 'char *' but argument is of type 'const char *'
   34 | extern char *__xpg_basename (char *__path) __THROW;
      |                              ~~~~~~^~~~~~
api.c:3588:17: warning: passing argument 1 of '__xpg_basename' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
 3588 |        basename(procname));
      |                 ^~~~~~~~
In file included from api.c:48:
/usr/include/libgen.h:34:36: note: expected 'char *' but argument is of type 'const char *'
   34 | extern char *__xpg_basename (char *__path) __THROW;
      |                              ~~~~~~^~~~~~
api.c: In function 'cgroup_change_cgroup_flags':
api.c:3585:37: warning: passing argument 1 of '__xpg_basename' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
 3585 |      if(procname && strlen(basename(procname))) {
      |                                     ^~~~~~~~
In file included from api.c:48:
/usr/include/libgen.h:34:36: note: expected 'char *' but argument is of type 'const char *'
   34 | extern char *__xpg_basename (char *__path) __THROW;
      |                              ~~~~~~^~~~~~
api.c:3588:17: warning: passing argument 1 of '__xpg_basename' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
 3588 |        basename(procname));
      |                 ^~~~~~~~
In file included from api.c:48:
/usr/include/libgen.h:34:36: note: expected 'char *' but argument is of type 'const char *'
   34 | extern char *__xpg_basename (char *__path) __THROW;
      |                              ~~~~~~^~~~~~
test_functions.c: In function 'is_subsystem_enabled':
test_functions.c:335:3: warning: ignoring return value of 'fscanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  335 |   fscanf(fd, "%s, %d, %d, %d", subsys_name,
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  336 |       &hierarchy, &num_cgroups, &enabled);
      |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test_functions.c: In function 'group_modified':
test_functions.c:436:3: warning: ignoring return value of 'fscanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  436 |   fscanf(fd, "%d", &aux);
      |   ^~~~~~~~~~~~~~~~~~~~~~
test_functions.c:442:3: warning: ignoring return value of 'fscanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  442 |   fscanf(fd, "%" SCNi64, &int64_val);
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test_functions.c:447:3: warning: ignoring return value of 'fscanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  447 |   fscanf(fd, "%" SCNu64, &uint64_val);
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test_functions.c:452:3: warning: ignoring return value of 'fscanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  452 |   fscanf(fd, "%s", string_val);
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
test_functions.c: In function 'check_task':
test_functions.c:648:3: warning: ignoring return value of 'fscanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  648 |   fscanf(file, "%u", &tid);
      |   ^~~~~~~~~~~~~~~~~~~~~~~~

ENH: Add support for creating an "empty" cgroup v2 cgroup

Add support to cgcreate and the underlying C APIs to allow something like the following:
cgcreate -g :foo

The goal is to allow the user to create a cgroup v2 cgroup (called foo in this example) with no controllers enabled within it.

No such commit 918443b in libcgroup-tests

I'm trying to make a Rust binding for this repo. However I meet an error when fetching this repo with git in cargo:

Caused by:
  object not found - no match for id (918443bd89efb807d92c1754b0b3fbff4bd3304f); class=Odb (9); code=NotFound (-3)

Seems the commit 918443b can not' be found.

Then I clone libcgroup-tests and I confirm that 918443b is not a valid commit for libcgroup-tests.

However, If I run this:

$ git clone https://github.com/libcgroup/libcgroup
$ git submodule update --init --recursive

I can found that 918443b is checked-out for tests!

It really confuses me. Could you help me?

BUG: cgroup.threads not supported

libcgroup has incorrect support for cgroup2 threads in cgroup_attach_task, where the documentation says
pid = tid, attaching a thread to a cgroup2 group actually adds the thread to cgroup.procs, which causes all
threads of the process to be added

ENH: Add abstraction logic to cgroup_read_stats*()

Add abstraction logic to cgroup_read_stats_begin(), cgroup_read_stats_next(), and cgroup_read_stats_end().

Two major requirements:

  1. Support controller name changes, e.g. cpuacct.stat in v1 to cpu.stat in v2
  2. Convert the contents, e.g. user in cpuacct.stat in v1 to user_usec in v2

It should be possible to modify the handle parameter to point to a structure which contains the handle and the requisite conversion information.

Hardcoded and misleading error printf in cgset

The fprintf at line 234 of cgset.c is hardcoded to return the group can't be modified and ignores the ret value returned from cgroup_modify_cgroup()

This can cause user confusion when an invalid value is passed to cgset. For example, on a system with a valid possible cpuset.cpus list of 0-7, cgset currently behaves as follows:

thromatka@M910 ~/scripts/bugs $ cgset -r cpuset.cpus=0-8 CgroupFoo
cgset: the group can't be modified

A more user friendly error message would be something like:

thromatka@M910 ~/scripts/bugs $ cgset -r cpuset.cpus=0-8 CgroupFoo
cgroup modify error: Numerical result out of range

I will submit a patch shortly.

tests submodule points to broken SHA

The tests submodule on main points to 918443bd89efb807d92c1754b0b3fbff4bd3304f, which is a broken commit on libcgroup-tests as it has this change:

-TESTS = 001-cgget-basic_cgget_v1.py \
-       002-cgdelete-recursive_delete.py \
-       003-cgget-basic_cgget_v2.py
+TESTS = ftests.py -l 10 -L ftests.log

TESTS is treated as a list of scripts by automake, so it ends up calling rm -L.log.

I guess the submodule reference should be bumped to the HEAD of libcgroup-tests?

cgroup_get_cgroup() broken for cgroupv2?

I'm running libcgroup v3.0.0 on Linux 6.1:

# uname -a
Linux box 6.1.0-0-rt-amd64 #1 SMP PREEMPT_RT Debian 6.1~rc3-1~exp1 (2022-11-02) x86_64 GNU/Linux
# mount | grep cgroup
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate,memory_recursiveprot)

With the following reproducer:

#include <stdlib.h>
#include <unistd.h>
#include <libcgroup.h>
#include "libcgroup-internal.h"

struct cgroup* get_or_create_cgroup(char *name)
{
    struct cgroup *cg = cgroup_new_cgroup(name);
    int ret = cgroup_get_cgroup(cg);
    if (ret == ECGROUPNOTEXIST) {
        struct cgroup_controller *cgc = cgroup_add_controller(cg, "cpuset");
        int ret2 = cgroup_create_cgroup(cg, 1);
        if (ret2) {
            printf("failed to create %s: %s\n", name, cgroup_strerror(ret2));
            exit(1);
        }
        printf("created %s\n", name);
    } else if (ret) {
        printf("failed to get %s: %s\n", name, cgroup_strerror(ret));
        exit(1);
    } else {
        printf("found existing %s\n", name);
#ifdef WORKAROUND
        cgroup_free(&cg);
        cg = cgroup_new_cgroup(name);
#endif
    }
    printf("  controllers:");
    for (int i = 0; i < CG_CONTROLLER_MAX; i++) {
        if (!cg->controller[i])
            break;
        printf(" %s", cg->controller[i]->name);
    }
    printf("\n");
    return cg;
}

int main(int, char*[]) {
    int ret = cgroup_init();
    if (ret) {
        printf("failed to initialize: %s\n", cgroup_strerror(ret));
        exit(1);
    }

    get_or_create_cgroup("my.slice");
    struct cgroup *cg = get_or_create_cgroup("my.slice/sub.slice");
    ret = cgroup_attach_task(cg);
    if (ret) {
        printf("failed to attach thread: %s\n", cgroup_strerror(ret));
        exit(1);
    }
    printf("success!\n");
}

And I'm seeing:

# gcc -o cgtest cgtest.c -lcgroup
# rmdir /sys/fs/cgroup/my.slice/sub.slice/ /sys/fs/cgroup/my.slice/
# ./cgtest
created my.slice
  controllers: cpuset
created my.slice/sub.slice
  controllers: cpuset
success!
# ./cgtest
found existing my.slice
  controllers: cpuset cpu io memory hugetlb pids rdma misc
found existing my.slice/sub.slice
  controllers: cpuset cpu io memory hugetlb pids rdma misc
failed to attach thread: Cgroup is not mounted

It looks to me that

  • cgroup_get_cgroup() always populates the cgroup struct with all possible controllers, even if they're not in cgroup.controllers
  • cgroup_attach_task() wants to attach the task to all controllers in the cgroup struct, and fails (returns error) if one of them doesn't actually exist.
  • However, if the first controller does exist, the task is actually attached, but still an error is returned.

If I use the cgroup right after cgroup_new_cgroup() without calling cgroup_get_cgroup(), there is no error, and the task is attached to the cgroup.

# gcc -o cgtest cgtest.c -lcgroup -DWORKAROUND
# rmdir /sys/fs/cgroup/my.slice/sub.slice/ /sys/fs/cgroup/my.slice/
# ./cgtest
created my.slice
  controllers: cpuset
created my.slice/sub.slice
  controllers: cpuset
success!
# ./cgtest
found existing my.slice
  controllers:
found existing my.slice/sub.slice
  controllers:
success!

RFE: Reading existing values of "cgroup.*"

Hi there. I've been a user of libcgroup with cgroup v1 since 2013, and I am just now updating my custom python bindings to support the new v2 support. But I am struggling to understand the intended way to access "cgroup.*" values that are not specific to the traditional controllers.

This question is very much related to #131 where a similar question was asked regarding setting "cgroup.type". I had worked out from reading the source code that it is valid to add a "cgroup" controller and then I was able to set the value of "cgroup.freezer" to 1. However I am failing to understand how to initially read the values. It seems the "add_value" api wants to modify the value in addition to loading it into the internal structure. And it doesnt seem one can read a value unless its listed in the internal structure for the controller value names. But when I add the "cgroup" controller, the value count is 0.

So then, how does one read a value like "cgroup.freezer" or other "cgroup.*" values before they are written to?

0.42.2: parallel build fails

When make is executed with -j1 everything is fine.

+ /usr/bin/make -O -j48 V=1 VERBOSE=1
/usr/bin/make  all-recursive
Making all in dist
make[2]: Nothing to be done for 'all'.
Making all in doc
Making all in man
make[3]: Nothing to be done for 'all'.
make[3]: Nothing to be done for 'all-am'.
Making all in include
make[2]: Nothing to be done for 'all'.
Making all in samples
make[2]: Nothing to be done for 'all'.
Making all in scripts
make[2]: Nothing to be done for 'all'.
Making all in src
Making all in .
make[3]: Entering directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
/bin/sh ../build-aux/ylwrap lex.l lex.yy.c lex.c -- flex
make[3]: Leaving directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
make[3]: Entering directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
/bin/sh ../libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -I../include    -DSTATIC=static -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -flto=auto -flto-partition=none -Os -Wall -c -o libcgroup_la-log.lo `test -f 'log.c' || echo './'`log.c
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I../include -DSTATIC=static -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -flto=auto -flto-partition=none -Os -Wall -c log.c  -fPIC -DPIC -o .libs/libcgroup_la-log.o
make[3]: Leaving directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
make[3]: Entering directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
/bin/sh ../libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -I../include    -DSTATIC= -DUNIT_TEST -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -flto=auto -flto-partition=none -Os -Wall -c -o libcgroupfortesting_la-log.lo `test -f 'log.c' || echo './'`log.c
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I../include -DSTATIC= -DUNIT_TEST -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -flto=auto -flto-partition=none -Os -Wall -c log.c  -fPIC -DPIC -o .libs/libcgroupfortesting_la-log.o
make[3]: Leaving directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
make[3]: Entering directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
/bin/sh ../libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -I../include    -DSTATIC= -DUNIT_TEST -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -flto=auto -flto-partition=none -Os -Wall -c -o libcgroupfortesting_la-wrapper.lo `test -f 'wrapper.c' || echo './'`wrapper.c
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I../include -DSTATIC= -DUNIT_TEST -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -flto=auto -flto-partition=none -Os -Wall -c wrapper.c  -fPIC -DPIC -o .libs/libcgroupfortesting_la-wrapper.o
wrapper.c: In function 'cgroup_add_value_string':
wrapper.c:199:50: warning: format '%d' expects argument of type 'int', but argument 3 has type 'long unsigned int' [-Wformat=]
  199 |   fprintf(stderr, "value exceeds the maximum of %d characters\n",
      |                                                 ~^
      |                                                  |
      |                                                  int
      |                                                 %ld
  200 |    sizeof(cntl_value->value) - 1);
      |    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |    |
      |    long unsigned int
make[3]: Leaving directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
make[3]: Entering directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
/bin/sh ../libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -I../include    -DSTATIC= -DUNIT_TEST -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -flto=auto -flto-partition=none -Os -Wall -c -o libcgroupfortesting_la-lex.lo `test -f 'lex.c' || echo './'`lex.c
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I../include -DSTATIC= -DUNIT_TEST -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -flto=auto -flto-partition=none -Os -Wall -c lex.c  -fPIC -DPIC -o .libs/libcgroupfortesting_la-lex.o
lex.l:18:10: fatal error: parse.h: No such file or directory
   18 | #include "parse.h"
      |          ^~~~~~~~~
compilation terminated.
make[3]: *** [Makefile:634: libcgroupfortesting_la-lex.lo] Error 1
make[3]: Leaving directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
make[3]: *** Waiting for unfinished jobs....
make[3]: Entering directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
/bin/sh ../build-aux/ylwrap parse.y y.tab.c parse.c y.tab.h `echo parse.c | sed -e s/cc$/hh/ -e s/cpp$/hpp/ -e s/cxx$/hxx/ -e s/c++$/h++/ -e s/c$/h/` y.output parse.output -- bison -y -d
/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src/parse.y:48.14-15: warning: POSIX yacc reserves %type to nonterminals [-Wyacc]
   48 | %type <name> ID DEFAULT group_name
      |              ^~
/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src/parse.y:48.17-23: warning: POSIX yacc reserves %type to nonterminals [-Wyacc]
   48 | %type <name> ID DEFAULT group_name
      |                 ^~~~~~~
/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src/parse.y: warning: 4 shift/reduce conflicts [-Wconflicts-sr]
updating parse.h
make[3]: Leaving directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
make[3]: Entering directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
/bin/sh ../libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -I../include    -DSTATIC=static -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -flto=auto -flto-partition=none -Os -Wall -c -o libcgroup_la-wrapper.lo `test -f 'wrapper.c' || echo './'`wrapper.c
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I../include -DSTATIC=static -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -flto=auto -flto-partition=none -Os -Wall -c wrapper.c  -fPIC -DPIC -o .libs/libcgroup_la-wrapper.o
wrapper.c: In function 'cgroup_add_value_string':
wrapper.c:199:50: warning: format '%d' expects argument of type 'int', but argument 3 has type 'long unsigned int' [-Wformat=]
  199 |   fprintf(stderr, "value exceeds the maximum of %d characters\n",
      |                                                 ~^
      |                                                  |
      |                                                  int
      |                                                 %ld
  200 |    sizeof(cntl_value->value) - 1);
      |    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |    |
      |    long unsigned int
make[3]: Leaving directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
make[3]: Entering directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
/bin/sh ../libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -I../include    -DSTATIC=static -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -flto=auto -flto-partition=none -Os -Wall -c -o libcgroup_la-config.lo `test -f 'config.c' || echo './'`config.c
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I../include -DSTATIC=static -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -flto=auto -flto-partition=none -Os -Wall -c config.c  -fPIC -DPIC -o .libs/libcgroup_la-config.o
make[3]: Leaving directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
make[3]: Entering directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
/bin/sh ../libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -I../include    -DSTATIC= -DUNIT_TEST -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -flto=auto -flto-partition=none -Os -Wall -c -o libcgroupfortesting_la-config.lo `test -f 'config.c' || echo './'`config.c
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I../include -DSTATIC= -DUNIT_TEST -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -flto=auto -flto-partition=none -Os -Wall -c config.c  -fPIC -DPIC -o .libs/libcgroupfortesting_la-config.o
make[3]: Leaving directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
make[3]: Entering directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
/bin/sh ../libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -I../include    -DSTATIC=static -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -flto=auto -flto-partition=none -Os -Wall -c -o libcgroup_la-lex.lo `test -f 'lex.c' || echo './'`lex.c
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I../include -DSTATIC=static -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -flto=auto -flto-partition=none -Os -Wall -c lex.c  -fPIC -DPIC -o .libs/libcgroup_la-lex.o
make[3]: Leaving directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
make[3]: Entering directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
/bin/sh ../libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -I../include    -DSTATIC=static -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -flto=auto -flto-partition=none -Os -Wall -c -o libcgroup_la-api.lo `test -f 'api.c' || echo './'`api.c
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I../include -DSTATIC=static -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -flto=auto -flto-partition=none -Os -Wall -c api.c  -fPIC -DPIC -o .libs/libcgroup_la-api.o
api.c: In function 'cgroup_change_cgroup_flags':
api.c:3460:37: warning: passing argument 1 of '__xpg_basename' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
 3460 |      if(procname && strlen(basename(procname))) {
      |                                     ^~~~~~~~
In file included from api.c:48:
/usr/include/libgen.h:34:36: note: expected 'char *' but argument is of type 'const char *'
   34 | extern char *__xpg_basename (char *__path) __THROW;
      |                              ~~~~~~^~~~~~
api.c:3463:17: warning: passing argument 1 of '__xpg_basename' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
 3463 |        basename(procname));
      |                 ^~~~~~~~
In file included from api.c:48:
/usr/include/libgen.h:34:36: note: expected 'char *' but argument is of type 'const char *'
   34 | extern char *__xpg_basename (char *__path) __THROW;
      |                              ~~~~~~^~~~~~
make[3]: Leaving directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
make[3]: Entering directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
/bin/sh ../libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -I../include    -DSTATIC= -DUNIT_TEST -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -flto=auto -flto-partition=none -Os -Wall -c -o libcgroupfortesting_la-api.lo `test -f 'api.c' || echo './'`api.c
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I../include -DSTATIC= -DUNIT_TEST -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -flto=auto -flto-partition=none -Os -Wall -c api.c  -fPIC -DPIC -o .libs/libcgroupfortesting_la-api.o
api.c: In function 'cgroup_change_cgroup_flags':
api.c:3460:37: warning: passing argument 1 of '__xpg_basename' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
 3460 |      if(procname && strlen(basename(procname))) {
      |                                     ^~~~~~~~
In file included from api.c:48:
/usr/include/libgen.h:34:36: note: expected 'char *' but argument is of type 'const char *'
   34 | extern char *__xpg_basename (char *__path) __THROW;
      |                              ~~~~~~^~~~~~
api.c:3463:17: warning: passing argument 1 of '__xpg_basename' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
 3463 |        basename(procname));
      |                 ^~~~~~~~
In file included from api.c:48:
/usr/include/libgen.h:34:36: note: expected 'char *' but argument is of type 'const char *'
   34 | extern char *__xpg_basename (char *__path) __THROW;
      |                              ~~~~~~^~~~~~
make[3]: Leaving directory '/home/tkloczko/rpmbuild/BUILD/libcgroup-0.42.2/src'
make[2]: *** [Makefile:683: all-recursive] Error 1
make[1]: *** [Makefile:490: all-recursive] Error 1

Add cgroup v2 support

This issue is to track the addition of cgroup v2 support to the various tools in libcgroup.

Below is the list of libcgroup's current applications and their cgroup v2 status:

/usr/bin/

/usr/sbin/

BUG: libcgset.so.0 is underlinked with libcgroup.so.1

Warning: undefined symbols in /usr/lib64/libcgset.so.0.0.0: cgroup_new_cgroup cgroup_init create_cgroup_from_name_value_pairs cgroup_log cgroup_strerror cgroup_free cgroup_copy_cgroup cgroup_get_cgroup cgroup_modify_cgroup

Those symbols are in libcgroup.so.1, but libcgset.so.0 is not linked with it.

Building with -Wl,--no-undefined fails the build because of this.

set cgroup.type value

Dear all, in order to set the cgroup.type to threaded via C API, I use this "workaround"

err = cgroup_add_value_string(cgroup_get_controller(cg_jd, "cpuset") ,"cgroup.type","threaded");
err = cgroup_modify_cgroup(cg_jd); 

because I can't find an interface as

int cgroup_add_value_string (struct cgroup *cgroup,  const char *name,  const char *value)

that I expected to set the cgroup.type value. Did I misunderstand something?

thx for your support.

cgroup v1 - cgroup deletion fails with mount shared by controllers

While debugging #125, there was another issue discovered while deleting a
cgroup created on mount-point shared between two controllers. For example:

$ mount|grep -i cpuacct
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)

$ ll /sys/fs/cgroup/|grep -i cpuacct
lrwxrwxrwx  1 root root  11 Mar 31 08:24 cpu -> cpu,cpuacct/
lrwxrwxrwx  1 root root  11 Mar 31 08:24 cpuacct -> cpu,cpuacct/
dr-xr-xr-x  5 root root   0 Mar 31 08:24 cpu,cpuacct/

both cpu and cpuacct are mounted on /sys/fs/cgroup/cpu,cpuacct and individually they are
symlinks to the same mountpoint. There is no issue when both the controllers are added to the
cgroup during the creation but when trying to recursively delete the created cgroup the deletion
fails due to missing cgroup. The reason being the cgroup on the shared mount point is deleted
when accessed by the first of the shared controller and goes missing for the second controller,
while it tries to delete it.

$ cat test.c

#include <stdio.h>
#include <libcgroup.h>

int main(int argc, char **argv)
{
        struct cgroup *cgroup_name = NULL;
        int ret;

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

        cgroup_name = cgroup_new_cgroup("mygroup");
        if (!cgroup_name) {
                fprintf(stderr, "failed new_Cgroup\n");
                return (1);
        }

        if (!cgroup_add_controller(cgroup_name, "cpuset")) {
                fprintf(stderr, "failed add_controller cpuset\n");
                return (1);
        }

        if (!cgroup_add_controller(cgroup_name, "cpu")) {
                fprintf(stderr, "failed add_controller cpu\n");
                return (1);
        }

        if (!cgroup_add_controller(cgroup_name, "cpuacct")) {
                fprintf(stderr, "failed add_controller cpuacct\n");
                return (1);
        }
        if (!cgroup_add_controller(cgroup_name, "memory")) {
                fprintf(stderr, "failed add_controller memory\n");
                return (1);
        }

        ret = cgroup_create_cgroup(cgroup_name, 0);
        if (ret) {
                fprintf(stderr, "failed create_cgroup\n");
                return (1);
        }

        ret = cgroup_delete_cgroup_ext(cgroup_name, CGFLAG_DELETE_RECURSIVE);
        if (ret) {
                fprintf(stderr, "Deletion failed %d\n", ret);
                return (1);
        }

        return (0);
}

Deletion of v2 cgroup with no controllers fails

A cgroup v2 created with no controllers, fails to delete, following is a reproducer
(extension of samples/c/empty_cgroup_v2.c):

#include <libcgroup.h>

#include <stdlib.h>
#include <stdio.h>

#define CGRP_NAME "empty_cgrp"

int main(int argc, char **argv)
{
        struct cgroup *cgroup = NULL;
        int ret = 0;

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

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

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

        ret = cgroup_delete_cgroup_ext(cgroup, CGFLAG_DELETE_RECURSIVE);
        if (ret)
                fprintf(stderr, "Failed to delete cgroup %s\n", CGRP_NAME);

        cgroup_free(&cgroup);

        return ret;
}

RFE: Add cgroup v1/v2 abstraction layer

This issue is to track the addition of cgroup v1/v2 abstraction layer to the various tools in libcgroup.

Below is the list of libcgroup's current features and their cgroup v1/v2 abstraction status:

/usr/bin/

  • cgclassify
  • cgcreate
  • cgdelete
  • cgexec
  • cgget
  • cgset
  • cgsnapshot
  • lscgroup
  • lssubsys

/usr/sbin/

  • cgclear
  • cgconfigparser
  • cgrulesengd

BUG: unused shared libraries installed?

Hi there,

libcgroup installs files of two shared libraries: libcgroupfortesting and libcgset that I think are unused (correct me please if I am wrong). libcgroup shouldn't avoid installing those?

Cheers,

-- S

BUG: libcgroup fails without /proc/cgroups even when it's not necessary

libcgroup (or at least pam_cgroup) fails to initialize when /proc/cgroups isn't present, even on a cgroup2-only system where "/proc/cgroups is meaningless" (https://docs.kernel.org/admin-guide/cgroup-v2.html#deprecated-v1-core-features).

This can cause libcgroup to fail on mainline Linux today if procfs is mounted with subset=pid, which is, as you might expect, a version of procfs with just the files relating to processes & none of the other top-level stuff.

(tested with libcgroup v2.0 & libcgroup ed283ea)

cgconfigparser is not working as expected

OS : SLES 15 SP1
kernel : 4.12.14-197.45

consider the following group : group memory_test{​​​​ memory {​​​​ memory.low = 1G; memory.max = 24G; }​​​​ }​​​​
Only the first configuration line is being set and the rest of them are being neglected , the same is the status with other settings as well (io, cpu) (Tested on SLES15 SP2)

configure: sample C code warnings

When ./bootstrap.sh is run, it issues a flood of warnings about the samples/c/ programs:

samples/c/Makefile.am:23: warning: variable 'empty_cgroup_v2_SOURCES' is defined but no program or
samples/c/Makefile.am:23: library has 'empty_cgroup_v2' as canonical name (possible typo)
samples/c/Makefile.am:17: warning: variable 'get_all_controller_SOURCES' is defined but no program or
samples/c/Makefile.am:17: library has 'get_all_controller' as canonical name (possible typo)
samples/c/Makefile.am:14: warning: variable 'get_controller_SOURCES' is defined but no program or
samples/c/Makefile.am:14: library has 'get_controller' as canonical name (possible typo)
samples/c/Makefile.am:15: warning: variable 'get_mount_point_SOURCES' is defined but no program or
samples/c/Makefile.am:15: library has 'get_mount_point' as canonical name (possible typo)
samples/c/Makefile.am:20: warning: variable 'get_procs_SOURCES' is defined but no program or
samples/c/Makefile.am:20: library has 'get_procs' as canonical name (possible typo)
samples/c/Makefile.am:18: warning: variable 'get_variable_names_SOURCES' is defined but no program or
samples/c/Makefile.am:18: library has 'get_variable_names' as canonical name (possible typo)
samples/c/Makefile.am:22: warning: variable 'logger_SOURCES' is defined but no program or
samples/c/Makefile.am:22: library has 'logger' as canonical name (possible typo)
samples/c/Makefile.am:16: warning: variable 'proctest_SOURCES' is defined but no program or
samples/c/Makefile.am:16: library has 'proctest' as canonical name (possible typo)
samples/c/Makefile.am:12: warning: variable 'read_stats_SOURCES' is defined but no program or
samples/c/Makefile.am:12: library has 'read_stats' as canonical name (possible typo)
samples/c/Makefile.am:10: warning: variable 'setuid_SOURCES' is defined but no program or
samples/c/Makefile.am:10: library has 'setuid' as canonical name (possible typo)
samples/c/Makefile.am:19: warning: variable 'test_named_hierarchy_SOURCES' is defined but no program or
samples/c/Makefile.am:19: library has 'test_named_hierarchy' as canonical name (possible typo)
samples/c/Makefile.am:13: warning: variable 'walk_task_SOURCES' is defined but no program or
samples/c/Makefile.am:13: library has 'walk_task' as canonical name (possible typo)
samples/c/Makefile.am:11: warning: variable 'walk_test_SOURCES' is defined but no program or
samples/c/Makefile.am:11: library has 'walk_test' as canonical name (possible typo)
samples/c/Makefile.am:21: warning: variable 'wrapper_test_SOURCES' is defined but no program or
samples/c/Makefile.am:21: library has 'wrapper_test' as canonical name (possible typo)
src/Makefile.am: installing 'build-aux/depcomp'

Attaching a tid to empty cgroup v2 cgroup fails

A cgroup on cgroup v2 with no controllers attached is a valid cgroup,
and attaching a task tid to such group fails. Following is the reproducer:

#include <stdlib.h>
#include <libcgroup.h>

#define CGRP_EMPTY "myempty_group"

int main(int argc, char **argv)
{
        struct cgroup *cgrp_empty = NULL;
        pid_t tid;
        int ret;

        if (argc  != 2) {
                fprintf(stderr, "Usage: sudo %s <tid to attach>\n", argv[0]);
                return (1);
        }

        tid = atoi(argv[1]);

        ret = cgroup_init();
        if (ret) {
                fprintf(stderr, "failed cgroup_init\n");
                return ret;
        }

        cgrp_empty = cgroup_new_cgroup(CGRP_EMPTY);
        if (!cgrp_empty) {
                fprintf(stderr, "failed new_cgroup %s\n", CGRP_EMPTY);
                return (1);
        }

        ret = cgroup_create_cgroup(cgrp_empty, 0);
        if (ret) {
                fprintf(stderr, "failed create_cgroup %s\n", CGRP_EMPTY);
                goto err;
        }

        ret = cgroup_attach_task_pid(cgrp_empty, tid);
        if (ret) {
                fprintf(stderr, "failed to tid %d to cgroup %s\n", tid, CGRP_EMPTY);
                goto err;
        }

        ret = cgroup_delete_cgroup_ext(cgrp_empty, CGFLAG_DELETE_RECURSIVE);
        if (ret)
                fprintf(stderr, "%s Deletion failed %d\n", CGRP_EMPTY, ret);

err:
        cgroup_free(&cgrp_empty);

        return ret;
}

BUG: pam_cgroup simply doesn't work with cgroup2

pam_cgroup, at least under a cgroup2-only environment (maybe cgroup1 as well, I haven't tested), simply doesn't seem to work at all. It still acts as if it succeeded.

Tracing a random sshd instance for every file it opens, there are only 3:

25666 sshd                3   0 /proc/cgroups
25666 sshd                5   0 /proc/mounts
25666 sshd                7   0 /sys/fs/cgroup/cgroup.controllers

(nothing else cgroup or libcgroup-related)
For whatever reason cgrules.conf is never loaded. Despite this, it claims it changed the cgroup successfully (with debug flag):

Dec 26 13:49:12 h pam_cgroup(sshd:session): Changed cgroup for process 25666  with username [redacted].

This is not true, as we can see from the just logged in session:

[redacted]@h $ cat /proc/self/cgroup
0::/

This failure also doesn't result in the login failing, even though in my PAM configuration pam_cgroup is not optional but required.

(tested with libcgroup v2.0)

Created coordination between self-hosted runners

Currently, there are three self-hosted runners on each VM, there is a chance of
runners stomping over each other. We need better coordination. One idea is using
ACTIONS_RUNNER_HOOK_JOB_STARTED or ACTIONS_RUNNER_HOOK_JOB_COMPLETED
to systemctl stop <other runner service> and systemctl start <other runner service>
creating a mutual exclusion. Its not bulletproof but might work

Resources getting back to default for system.slice and user.slice for Cgroup v2

We are using cgconfigparser utility for setting the resource of system.slice and user.slice for cpu and memory controller. It is able to set the resources, but it's getting reverted after few seconds. Is it the expected behavior?

E.g. cgconfig.conf file
group system.slice {
memory {
memory.max="20G";
}
}

OS : SLES15 SP2
Hierarchy : unified(Pure V2)

cpu.weight value is not written when cgroup has 'cpu' enabled in cgroup.subtree_control

I've been working through this for a few hours and I cannot tell if this is a bug or some kind of under-documented rule.

Goal

I want to modify the value of 'cpu.weight' from the default 100 to a value, such as 8

What I have tried

The following does not work

  1. Construct a new cgroup, under the root (for simplicity), such as "my_group"
  2. Add controller 'cpu'
  3. Create the cgroup on disk
  4. Load cgroup object back (ie we have loaded a previously created cgroup)
  5. Set the value of "cpu.weight" to 8
  6. Modify the cgroup to commit the value. Notice that the value of "my_group/cpu.weight" on disk remains 100

The following does work

  1. Construct a new cgroup, under the root (for simplicity), such as "my_group2"
  2. Add controller 'cpu'
  3. Set the value of "cpu.weight" to 8
  4. Create the cgroup on disk
  5. Notice that the value of "my_group2/cpu.weight" is set to 8

Observations

It seems libcgroup does not actually manage to set "cpu.weight" if the 'cpu' controller is already enabled in the "cgroup.subtree_control", even though debug logging implies it is trying to set the correct value. This does not seem to be a limit of cgroup v2 from the kernel, as I can manually write a value from the shell and see it reflected in all cases.

RFE: Add option to install tests

In cross-compilation environments we can't just run the tests on the build machine. Please consider adding a way to install the test suite, so that it can be executed on the target.

Whether is a way to keep cgred's result from overriding by systemd ?

Expected Behavior

Cgrulesengd move high priority service's pids to specified cpu cgroup, like /high which has a cpu quota 70%;
low priority service's pids to cpu cgroup, like /low which has a cpu quota 30%. ( all service bind to one single cpu core )

As you can see, I want to split one cpu core resource to two parts, through cpu.cfs_quota_us.
Like high priority services use up to 70% cpu time, low priority services use up to 30% cpu time.

Actual Behavior

Services which controlled by systemd.
First, cgrulesengd move service's pid to specified;
then, systemd will fresh service's cgroup in some time;
finally, service's pids cpu cgroup will be changed by systemd.

Question

Whether is a way to keep cgred's result from overriding by systemd when handle cpu controller?

Ref

README_systemd

In README_systemd, there is a DefaultControllers= can control whether systemd create control groups for services automatically. But this param was removed from systemd.

Environment

systemd-v219
libcgroup-0.41-21

BUG: ambiguous controller name matches by using "hasmntopt"

https://github.com/libcgroup/libcgroup/blob/v2.0.2/src/api.c#L1078

calling "hasmntopt" to determine if the controller name exists in "mntopt", may cause errors because of "hasmntopt" only match substring.

Found cgroup option rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd, count 0
found cpuset in rw,nosuid,nodev,noexec,relatime,cpuset
Found cgroup option rw,nosuid,nodev,noexec,relatime,cpuset, count 1
found cpu in rw,nosuid,nodev,noexec,relatime,cpuset
Found cgroup option rw,nosuid,nodev,noexec,relatime,cpuset, count 2
found devices in rw,nosuid,nodev,noexec,relatime,devices
Found cgroup option rw,nosuid,nodev,noexec,relatime,devices, count 3
found perf_event in rw,nosuid,nodev,noexec,relatime,perf_event
Found cgroup option rw,nosuid,nodev,noexec,relatime,perf_event, count 4
found net_cls in rw,nosuid,nodev,noexec,relatime,net_cls,net_prio
Found cgroup option rw,nosuid,nodev,noexec,relatime,net_cls,net_prio, count 5
found net_prio in rw,nosuid,nodev,noexec,relatime,net_cls,net_prio
Found cgroup option rw,nosuid,nodev,noexec,relatime,net_cls,net_prio, count 6
found pids in rw,nosuid,nodev,noexec,relatime,pids
Found cgroup option rw,nosuid,nodev,noexec,relatime,pids, count 7
found cpu in rw,nosuid,nodev,noexec,relatime,cpu,cpuacct
controller cpu,cpuacct is already mounted on /sys/fs/cgroup/cpuset
found cpuacct in rw,nosuid,nodev,noexec,relatime,cpu,cpuacct
Found cgroup option rw,nosuid,nodev,noexec,relatime,cpu,cpuacct, count 8
found blkio in rw,nosuid,nodev,noexec,relatime,blkio
Found cgroup option rw,nosuid,nodev,noexec,relatime,blkio, count 9
found freezer in rw,nosuid,nodev,noexec,relatime,freezer
Found cgroup option rw,nosuid,nodev,noexec,relatime,freezer, count 10
found memory in rw,nosuid,nodev,noexec,relatime,memory
Found cgroup option rw,nosuid,nodev,noexec,relatime,memory, count 11

cpu controller incorrectly matched to cpuset.
pull request: #174

subtree +memory block cgroup_attach_task_pid

Hi, thanks for the great work.

I am use libcgroup on ubuntu 22.10, catch this problem:

if I call +memory first then I can not make cgroup_attach_task_pid work:

cgroup/src/api.c:1837] cannot write tid 505206 to /sys/fs/cgroup/test/cgroup.procs:Resource busy

if I call cgroup_attach_task_pid first then I can not write +memory into cgroup.subtree_control:

/sys/fs/cgroup/test/cgroup.subtree_control -95, operation not supported on socket from 260
+memory errno 50016, Operation not supported

Is there a way to made this work to move myself into the new created cgroup, and keep the +memory into cgroup.subtree_control ?

RFE: Introduce coding style

Over time, there have been different coding styles used. Going forward let's follow Linux Kernel coding style for the C code.

  • Introduce coding style document.
  • Fix the existing C code to adhere to the Linux Kernel Coding style.
  • Introduce PEP-8 for Python?
  • Add vim mode line tags to Python sources.

BUG: Test failures on newer kernels

It looks like Ubuntu has picked up the latest PSI changes and now displays CPU full pressure. This affects test 009, 010, and 013.

Here's the output received. (Note the full avg line under cpu.pressure)

009cgget:
cpu.weight: 100
cpu.stat: usage_usec 0
	user_usec 0
	system_usec 0
	nr_periods 0
	nr_throttled 0
	throttled_usec 0
cpu.weight.nice: 0
cpu.pressure: some avg10=0.00 avg60=0.00 avg300=0.00 total=0
	full avg10=0.00 avg60=0.00 avg300=0.00 total=0
cpu.max: max 100000
cpu.uclamp.min: 0.00
cpu.uclamp.max: max

And here's what the tests are expecting

009cgget:
cpu.weight: 100
cpu.stat: usage_usec 0
        user_usec 0
        system_usec 0
        nr_periods 0
        nr_throttled 0
        throttled_usec 0
cpu.weight.nice: 0
cpu.pressure: some avg10=0.00 avg60=0.00 avg300=0.00 total=0
cpu.max: max 100000
cpu.uclamp.min: 0.00
cpu.uclamp.max: max

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.