From 70c949a42b2b0d0c9a2a567890483940cdc5f72c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 15 Aug 2014 11:55:43 +0200 Subject: cgroup: never try to create files in cgroupfs, only open them for writing This should have the benefit that cg_set_attribute() returns ENOENT instead of EACCESS when we use it for non-existing attributes. --- src/shared/cgroup-util.c | 12 ++++++------ src/shared/fileio.c | 22 ++++++++++++++++++++++ src/shared/fileio.h | 1 + 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index f683ae990e..e8cb9c73ac 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -643,7 +643,7 @@ int cg_attach(const char *controller, const char *path, pid_t pid) { snprintf(c, sizeof(c), PID_FMT"\n", pid); - return write_string_file(fs, c); + return write_string_file_no_create(fs, c); } int cg_attach_fallback(const char *controller, const char *path, pid_t pid) { @@ -817,7 +817,7 @@ int cg_install_release_agent(const char *controller, const char *agent) { sc = strstrip(contents); if (sc[0] == 0) { - r = write_string_file(fs, agent); + r = write_string_file_no_create(fs, agent); if (r < 0) return r; } else if (!streq(sc, agent)) @@ -837,7 +837,7 @@ int cg_install_release_agent(const char *controller, const char *agent) { sc = strstrip(contents); if (streq(sc, "0")) { - r = write_string_file(fs, "1"); + r = write_string_file_no_create(fs, "1"); if (r < 0) return r; @@ -858,7 +858,7 @@ int cg_uninstall_release_agent(const char *controller) { if (r < 0) return r; - r = write_string_file(fs, "0"); + r = write_string_file_no_create(fs, "0"); if (r < 0) return r; @@ -869,7 +869,7 @@ int cg_uninstall_release_agent(const char *controller) { if (r < 0) return r; - r = write_string_file(fs, ""); + r = write_string_file_no_create(fs, ""); if (r < 0) return r; @@ -1591,7 +1591,7 @@ int cg_set_attribute(const char *controller, const char *path, const char *attri if (r < 0) return r; - return write_string_file(p, value); + return write_string_file_no_create(p, value); } static const char mask_names[] = diff --git a/src/shared/fileio.c b/src/shared/fileio.c index cbb40c2379..18960abf02 100644 --- a/src/shared/fileio.c +++ b/src/shared/fileio.c @@ -58,6 +58,28 @@ int write_string_file(const char *fn, const char *line) { return write_string_stream(f, line); } +int write_string_file_no_create(const char *fn, const char *line) { + _cleanup_fclose_ FILE *f = NULL; + int fd; + + assert(fn); + assert(line); + + /* We manually build our own version of fopen(..., "we") that + * without O_CREAT */ + fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) + return -errno; + + f = fdopen(fd, "we"); + if (!f) { + safe_close(fd); + return -errno; + } + + return write_string_stream(f, line); +} + int write_string_file_atomic(const char *fn, const char *line) { _cleanup_fclose_ FILE *f = NULL; _cleanup_free_ char *p = NULL; diff --git a/src/shared/fileio.h b/src/shared/fileio.h index 5122a9a4de..c256915799 100644 --- a/src/shared/fileio.h +++ b/src/shared/fileio.h @@ -27,6 +27,7 @@ int write_string_stream(FILE *f, const char *line); int write_string_file(const char *fn, const char *line); +int write_string_file_no_create(const char *fn, const char *line); int write_string_file_atomic(const char *fn, const char *line); int read_one_line_file(const char *fn, char **line); -- cgit v1.2.3-54-g00ecf