found 803013 241-7~deb10u1 thanks
Now updating my machines to buster, I see this issue is still present, now in systemd version 241-7~deb10u1. The same steps can reproduce: - Set up cgroups e.g. adding TaskIDs to /sys/fs/cgroup/cpu/DIR/tasks files. (I use cgrulesengd from package cgroup-tools, but any other use of cgroups is equally affected.) - Then when you use systemd commands: systemctl daemon-reload systemctl start anacron you will see your cgroups (your tasks files) becoming empty. Command daemon-reload seems to happen within "apt-get dist-upgrade" sequences, and "start anacron" happens nightly. (Some other systemd commands may also affect.) and the "same" fix applies: new patch file below, for changed sources. (Funny how this bug is not getting fixed, in four years...) Thanks, Paul -- Paul Szabo p...@maths.usyd.edu.au http://www.maths.usyd.edu.au/u/psz/ School of Mathematics and Statistics University of Sydney Australia I support NTEU members taking a stand for workplace rights in the face of poorly-run change management. Visit www.nteu.org.au/sydney to learn more.
diff -r -U18 a-241/src/basic/cgroup-util.c b-241/src/basic/cgroup-util.c --- a-241/src/basic/cgroup-util.c 2019-02-14 21:11:58.000000000 +1100 +++ b-241/src/basic/cgroup-util.c 2019-09-12 08:53:43.900643247 +1000 @@ -368,36 +368,52 @@ int cg_migrate( const char *cfrom, const char *pfrom, const char *cto, const char *pto, CGroupFlags flags) { bool done = false; _cleanup_set_free_ Set *s = NULL; int r, ret = 0; pid_t my_pid; assert(cfrom); assert(pfrom); assert(cto); assert(pto); + /* + * PSz 25 Oct 2015 + * An empty "to" path is surely wrong + * (do not annoy cgroups that are not ours). + * PSz 23 Jul 2017 + * Cannot(?) happen anymore, see: + * cg_migrate_recursive_fallback() + * cg_migrate_everywhere() + * below... log if it does! + */ + if (!strlen(pto)) { + log_warning("PSz debug: cg_migrate skip from (%s)%s to (%s)%s", cfrom, pfrom, cto, pto); + return ret; + } + /* log_warning("PSz debug: cg_migrate do from (%s)%s to (%s)%s", cfrom, pfrom, cto, pto); */ + s = set_new(NULL); if (!s) return -ENOMEM; my_pid = getpid_cached(); do { _cleanup_fclose_ FILE *f = NULL; pid_t pid = 0; done = true; r = cg_enumerate_processes(cfrom, pfrom, &f); if (r < 0) { if (ret >= 0 && r != -ENOENT) return r; return ret; } @@ -509,36 +525,52 @@ CGroupFlags flags) { int r; assert(cfrom); assert(pfrom); assert(cto); assert(pto); r = cg_migrate_recursive(cfrom, pfrom, cto, pto, flags); if (r < 0) { char prefix[strlen(pto) + 1]; /* This didn't work? Then let's try all prefixes of the destination */ PATH_FOREACH_PREFIX(prefix, pto) { int q; + /* + * PSz 23 Jul 2017 + * Skip an empty ("") prefix path: surely wrong, + * do not annoy cgroups that are not ours. + * Other comments: + * - Why this "did not work so try something else"? + * - Maybe should have used PATH_FOREACH_PREFIX_MORE + * for cleaner, more compact code. + * - Should check cg_attach_fallback() also, and maybe + * review all other uses of PATH_FOREACH_PREFIX. + */ + if (!strlen(prefix)) { + /* log_warning("PSz debug: cg_migrate_recursive_fallback skip from (%s)%s to (%s)[EMPTY prefix of %s]", cfrom, pfrom, cto, pto); */ + continue; + } + q = cg_migrate_recursive(cfrom, pfrom, cto, prefix, flags); if (q >= 0) return q; } } return r; } static const char *controller_to_dirname(const char *controller) { const char *e; assert(controller); /* Converts a controller name to the directory name below * /sys/fs/cgroup/ we want to mount it to. Effectively, this * just cuts off the name= prefixed used for named * hierarchies, if it is specified. */ @@ -2233,38 +2265,46 @@ if (q > 0) return r; supported &= CGROUP_MASK_V1; done = 0; for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) { CGroupMask bit = CGROUP_CONTROLLER_TO_MASK(c); const char *p = NULL; if (!FLAGS_SET(supported, bit)) continue; if (FLAGS_SET(done, bit)) continue; if (to_callback) p = to_callback(bit, userdata); - if (!p) + if (!p) { p = to; + } else if (!strlen(p)) { + /* + * PSz 12 Sep 2019 + * Skip an empty path returned by to_callback + */ + /* log_warning("PSz debug: to_callback in cg_migrate_everywhere returned empty, skipping (%s)%s to (%s)%s", SYSTEMD_CGROUP_CONTROLLER, to, cgroup_controller_to_string(c), p); */ + continue; + } (void) cg_migrate_recursive_fallback(SYSTEMD_CGROUP_CONTROLLER, to, cgroup_controller_to_string(c), p, 0); done |= CGROUP_MASK_EXTEND_JOINED(bit); } return r; } int cg_trim_everywhere(CGroupMask supported, const char *path, bool delete_root) { CGroupController c; CGroupMask done; int r, q; r = cg_trim(SYSTEMD_CGROUP_CONTROLLER, path, delete_root); if (r < 0) return r; q = cg_all_unified();