chiark
/
gitweb
/
~ianmdlvl
/
elogind.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
cgroup: honour sticky bit when trimming cgroup trees
[elogind.git]
/
src
/
cgroup-util.c
diff --git
a/src/cgroup-util.c
b/src/cgroup-util.c
index bbadc789a1651a30a2d995c85f807c704dc41b84..ec48ea63b4d0db188c7ba247953d64f0cfa20b88 100644
(file)
--- a/
src/cgroup-util.c
+++ b/
src/cgroup-util.c
@@
-153,17
+153,38
@@
int cg_read_subgroup(DIR *d, char **fn) {
return 0;
}
return 0;
}
-int cg_rmdir(const char *controller, const char *path) {
+int cg_rmdir(const char *controller, const char *path
, bool honour_sticky
) {
char *p;
int r;
char *p;
int r;
- if ((r = cg_get_path(controller, path, NULL, &p)) < 0)
+ r = cg_get_path(controller, path, NULL, &p);
+ if (r < 0)
return r;
return r;
+ if (honour_sticky) {
+ char *tasks;
+
+ /* If the sticky bit is set don't remove the directory */
+
+ tasks = strappend(p, "/tasks");
+ if (!tasks) {
+ free(p);
+ return -ENOMEM;
+ }
+
+ r = file_is_sticky(tasks);
+ free(tasks);
+
+ if (r > 0) {
+ free(p);
+ return 0;
+ }
+ }
+
r = rmdir(p);
free(p);
r = rmdir(p);
free(p);
- return
r < 0
? -errno : 0;
+ return
(r < 0 && errno != ENOENT)
? -errno : 0;
}
int cg_kill(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, Set *s) {
}
int cg_kill(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, Set *s) {
@@
-302,7
+323,7
@@
int cg_kill_recursive(const char *controller, const char *path, int sig, bool si
ret = r;
if (rem)
ret = r;
if (rem)
- if ((r = cg_rmdir(controller, path)) < 0) {
+ if ((r = cg_rmdir(controller, path
, true
)) < 0) {
if (ret >= 0 &&
r != -ENOENT &&
r != -EBUSY)
if (ret >= 0 &&
r != -ENOENT &&
r != -EBUSY)
@@
-466,7
+487,7
@@
int cg_migrate_recursive(const char *controller, const char *from, const char *t
ret = r;
if (rem)
ret = r;
if (rem)
- if ((r = cg_rmdir(controller, from)) < 0) {
+ if ((r = cg_rmdir(controller, from
, true
)) < 0) {
if (ret >= 0 &&
r != -ENOENT &&
r != -EBUSY)
if (ret >= 0 &&
r != -ENOENT &&
r != -EBUSY)
@@
-482,12
+503,26
@@
finish:
int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs) {
const char *p;
int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs) {
const char *p;
- char *
mp
;
-
int r
;
+ char *
t
;
+
static __thread bool good = false
;
assert(controller);
assert(fs);
assert(controller);
assert(fs);
+ if (_unlikely_(!good)) {
+ int r;
+
+ r = path_is_mount_point("/sys/fs/cgroup");
+ if (r <= 0)
+ return r < 0 ? r : -ENOENT;
+
+ /* Cache this to save a few stat()s */
+ good = true;
+ }
+
+ if (isempty(controller))
+ return -EINVAL;
+
/* This is a very minimal lookup from controller names to
* paths. Since we have mounted most hierarchies ourselves
* should be kinda safe, but eventually we might want to
/* This is a very minimal lookup from controller names to
* paths. Since we have mounted most hierarchies ourselves
* should be kinda safe, but eventually we might want to
@@
-501,29
+536,22
@@
int cg_get_path(const char *controller, const char *path, const char *suffix, ch
else
p = controller;
else
p = controller;
- if (asprintf(&mp, "/sys/fs/cgroup/%s", p) < 0)
- return -ENOMEM;
-
- if ((r = path_is_mount_point(mp)) <= 0) {
- free(mp);
- return r < 0 ? r : -ENOENT;
- }
-
if (path && suffix)
if (path && suffix)
-
r = asprintf(fs, "%s/%s/%s", mp, path, suffix
);
+
t = join("/sys/fs/cgroup/", p, "/", path, "/", suffix, NULL
);
else if (path)
else if (path)
-
r = asprintf(fs, "%s/%s", mp, path
);
+
t = join("/sys/fs/cgroup/", p, "/", path, NULL
);
else if (suffix)
else if (suffix)
- r = asprintf(fs, "%s/%s", mp, suffix);
- else {
- path_kill_slashes(mp);
- *fs = mp;
- return 0;
- }
+ t = join("/sys/fs/cgroup/", p, "/", suffix, NULL);
+ else
+ t = join("/sys/fs/cgroup/", p, NULL);
- free(mp);
- path_kill_slashes(*fs);
- return r < 0 ? -ENOMEM : 0;
+ if (!t)
+ return -ENOMEM;
+
+ path_kill_slashes(t);
+
+ *fs = t;
+ return 0;
}
int cg_trim(const char *controller, const char *path, bool delete_root) {
}
int cg_trim(const char *controller, const char *path, bool delete_root) {
@@
-536,7
+564,7
@@
int cg_trim(const char *controller, const char *path, bool delete_root) {
if ((r = cg_get_path(controller, path, NULL, &fs)) < 0)
return r;
if ((r = cg_get_path(controller, path, NULL, &fs)) < 0)
return r;
- r = rm_rf(fs, true, delete_root);
+ r = rm_rf(fs, true, delete_root
, true
);
free(fs);
return r == -ENOENT ? 0 : r;
free(fs);
return r == -ENOENT ? 0 : r;