cgroups/cgfsng: replace lxc_write_file()

parent b805280e
...@@ -500,13 +500,11 @@ static bool cg_legacy_filter_and_set_cpus(char *path, bool am_initialized) ...@@ -500,13 +500,11 @@ static bool cg_legacy_filter_and_set_cpus(char *path, bool am_initialized)
copy_parent: copy_parent:
if (!am_initialized) { if (!am_initialized) {
fpath = must_make_path(path, "cpuset.cpus", NULL); ret = lxc_write_openat(path, "cpuset.cpus", cpulist, strlen(cpulist));
ret = lxc_write_to_file(fpath, cpulist, strlen(cpulist), false, if (ret < 0)
0666); return log_error_errno(false,
if (ret < 0) { errno, "Failed to write cpu list to \"%s/cpuset.cpus\"",
SYSERROR("Failed to write cpu list to \"%s\"", fpath); path);
return false;
}
TRACE("Copied cpu settings of parent cgroup"); TRACE("Copied cpu settings of parent cgroup");
} }
...@@ -517,7 +515,7 @@ copy_parent: ...@@ -517,7 +515,7 @@ copy_parent:
/* Copy contents of parent(@path)/@file to @path/@file */ /* Copy contents of parent(@path)/@file to @path/@file */
static bool copy_parent_file(char *path, char *file) static bool copy_parent_file(char *path, char *file)
{ {
__do_free char *child_path = NULL, *parent_path = NULL, *value = NULL; __do_free char *parent_path = NULL, *value = NULL;
int ret; int ret;
char oldv; char oldv;
int len = 0; int len = 0;
...@@ -545,13 +543,17 @@ static bool copy_parent_file(char *path, char *file) ...@@ -545,13 +543,17 @@ static bool copy_parent_file(char *path, char *file)
} }
*lastslash = oldv; *lastslash = oldv;
child_path = must_make_path(path, file, NULL); ret = lxc_write_openat(path, file, value, len);
ret = lxc_write_to_file(child_path, value, len, false, 0666);
if (ret < 0) if (ret < 0)
SYSERROR("Failed to write \"%s\" to file \"%s\"", value, child_path); SYSERROR("Failed to write \"%s\" to file \"%s/%s\"", value, path, file);
return ret >= 0; return ret >= 0;
} }
static bool is_unified_hierarchy(const struct hierarchy *h)
{
return h->version == CGROUP2_SUPER_MAGIC;
}
/* Initialize the cpuset hierarchy in first directory of @gname and set /* Initialize the cpuset hierarchy in first directory of @gname and set
* cgroup.clone_children so that children inherit settings. Since the * cgroup.clone_children so that children inherit settings. Since the
* h->base_path is populated by init or ourselves, we know it is already * h->base_path is populated by init or ourselves, we know it is already
...@@ -559,11 +561,15 @@ static bool copy_parent_file(char *path, char *file) ...@@ -559,11 +561,15 @@ static bool copy_parent_file(char *path, char *file)
*/ */
static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname) static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname)
{ {
__do_free char *cgpath = NULL, *clonechildrenpath = NULL; __do_free char *cgpath = NULL;
__do_close_prot_errno int cgroup_fd = -EBADF;
int ret; int ret;
char v; char v;
char *slash; char *slash;
if (is_unified_hierarchy(h))
return true;
if (!string_in_list(h->controllers, "cpuset")) if (!string_in_list(h->controllers, "cpuset"))
return true; return true;
...@@ -585,14 +591,13 @@ static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname) ...@@ -585,14 +591,13 @@ static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname)
} }
} }
clonechildrenpath = must_make_path(cgpath, "cgroup.clone_children", NULL); cgroup_fd = lxc_open_dirfd(cgpath);
/* unified hierarchy doesn't have clone_children */ if (cgroup_fd < 0)
if (!file_exists(clonechildrenpath)) return false;
return true;
ret = lxc_read_from_file(clonechildrenpath, &v, 1); ret = lxc_readat(cgroup_fd, "cgroup.clone_children", &v, 1);
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to read file \"%s\"", clonechildrenpath); SYSERROR("Failed to read file \"%s/cgroup.clone_children\"", cgpath);
return false; return false;
} }
...@@ -612,10 +617,10 @@ static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname) ...@@ -612,10 +617,10 @@ static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname)
return false; return false;
} }
ret = lxc_write_to_file(clonechildrenpath, "1", 1, false, 0666); ret = lxc_writeat(cgroup_fd, "cgroup.clone_children", "1", 1);
if (ret < 0) { if (ret < 0) {
/* Set clone_children so children inherit our settings */ /* Set clone_children so children inherit our settings */
SYSERROR("Failed to write 1 to \"%s\"", clonechildrenpath); SYSERROR("Failed to write 1 to \"%s/cgroup.clone_children\"", cgpath);
return false; return false;
} }
...@@ -2016,15 +2021,14 @@ __cgfsng_ops static bool cgfsng_get_hierarchies(struct cgroup_ops *ops, int n, ...@@ -2016,15 +2021,14 @@ __cgfsng_ops static bool cgfsng_get_hierarchies(struct cgroup_ops *ops, int n,
static bool cg_legacy_freeze(struct cgroup_ops *ops) static bool cg_legacy_freeze(struct cgroup_ops *ops)
{ {
__do_free char *path = NULL;
struct hierarchy *h; struct hierarchy *h;
h = get_hierarchy(ops, "freezer"); h = get_hierarchy(ops, "freezer");
if (!h) if (!h)
return ret_set_errno(-1, ENOENT); return ret_set_errno(-1, ENOENT);
path = must_make_path(h->container_full_path, "freezer.state", NULL); return lxc_write_openat(h->container_full_path, "freezer.state",
return lxc_write_to_file(path, "FROZEN", STRLITERALLEN("FROZEN"), false, 0666); "FROZEN", STRLITERALLEN("FROZEN"));
} }
static int freezer_cgroup_events_cb(int fd, uint32_t events, void *cbdata, static int freezer_cgroup_events_cb(int fd, uint32_t events, void *cbdata,
...@@ -2064,7 +2068,6 @@ static int freezer_cgroup_events_cb(int fd, uint32_t events, void *cbdata, ...@@ -2064,7 +2068,6 @@ static int freezer_cgroup_events_cb(int fd, uint32_t events, void *cbdata,
static int cg_unified_freeze(struct cgroup_ops *ops, int timeout) static int cg_unified_freeze(struct cgroup_ops *ops, int timeout)
{ {
__do_close_prot_errno int fd = -EBADF; __do_close_prot_errno int fd = -EBADF;
__do_free char *path = NULL;
__do_lxc_mainloop_close struct lxc_epoll_descr *descr_ptr = NULL; __do_lxc_mainloop_close struct lxc_epoll_descr *descr_ptr = NULL;
int ret; int ret;
struct lxc_epoll_descr descr; struct lxc_epoll_descr descr;
...@@ -2097,8 +2100,7 @@ static int cg_unified_freeze(struct cgroup_ops *ops, int timeout) ...@@ -2097,8 +2100,7 @@ static int cg_unified_freeze(struct cgroup_ops *ops, int timeout)
return log_error_errno(-1, errno, "Failed to add cgroup.events fd handler to mainloop"); return log_error_errno(-1, errno, "Failed to add cgroup.events fd handler to mainloop");
} }
path = must_make_path(h->container_full_path, "cgroup.freeze", NULL); ret = lxc_write_openat(h->container_full_path, "cgroup.freeze", "1", 1);
ret = lxc_write_to_file(path, "1", 1, false, 0666);
if (ret < 0) if (ret < 0)
return log_error_errno(-1, errno, "Failed to open cgroup.freeze file"); return log_error_errno(-1, errno, "Failed to open cgroup.freeze file");
...@@ -2121,21 +2123,19 @@ __cgfsng_ops static int cgfsng_freeze(struct cgroup_ops *ops, int timeout) ...@@ -2121,21 +2123,19 @@ __cgfsng_ops static int cgfsng_freeze(struct cgroup_ops *ops, int timeout)
static int cg_legacy_unfreeze(struct cgroup_ops *ops) static int cg_legacy_unfreeze(struct cgroup_ops *ops)
{ {
__do_free char *path = NULL;
struct hierarchy *h; struct hierarchy *h;
h = get_hierarchy(ops, "freezer"); h = get_hierarchy(ops, "freezer");
if (!h) if (!h)
return ret_set_errno(-1, ENOENT); return ret_set_errno(-1, ENOENT);
path = must_make_path(h->container_full_path, "freezer.state", NULL); return lxc_write_openat(h->container_full_path, "freezer.state",
return lxc_write_to_file(path, "THAWED", STRLITERALLEN("THAWED"), false, 0666); "THAWED", STRLITERALLEN("THAWED"));
} }
static int cg_unified_unfreeze(struct cgroup_ops *ops, int timeout) static int cg_unified_unfreeze(struct cgroup_ops *ops, int timeout)
{ {
__do_close_prot_errno int fd = -EBADF; __do_close_prot_errno int fd = -EBADF;
__do_free char *path = NULL;
__do_lxc_mainloop_close struct lxc_epoll_descr *descr_ptr = NULL; __do_lxc_mainloop_close struct lxc_epoll_descr *descr_ptr = NULL;
int ret; int ret;
struct lxc_epoll_descr descr; struct lxc_epoll_descr descr;
...@@ -2168,8 +2168,7 @@ static int cg_unified_unfreeze(struct cgroup_ops *ops, int timeout) ...@@ -2168,8 +2168,7 @@ static int cg_unified_unfreeze(struct cgroup_ops *ops, int timeout)
return log_error_errno(-1, errno, "Failed to add cgroup.events fd handler to mainloop"); return log_error_errno(-1, errno, "Failed to add cgroup.events fd handler to mainloop");
} }
path = must_make_path(h->container_full_path, "cgroup.freeze", NULL); ret = lxc_write_openat(h->container_full_path, "cgroup.freeze", "0", 1);
ret = lxc_write_to_file(path, "0", 1, false, 0666);
if (ret < 0) if (ret < 0)
return log_error_errno(-1, errno, "Failed to open cgroup.freeze file"); return log_error_errno(-1, errno, "Failed to open cgroup.freeze file");
...@@ -2638,12 +2637,10 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, ...@@ -2638,12 +2637,10 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename,
const char *value) const char *value)
{ {
__do_free char *controller = NULL; __do_free char *controller = NULL;
__do_free char *fullpath = NULL;
char *p; char *p;
/* "b|c <2^64-1>:<2^64-1> r|w|m" = 47 chars max */ /* "b|c <2^64-1>:<2^64-1> r|w|m" = 47 chars max */
char converted_value[50]; char converted_value[50];
struct hierarchy *h; struct hierarchy *h;
int ret = 0;
controller = must_copy_string(filename); controller = must_copy_string(filename);
p = strchr(controller, '.'); p = strchr(controller, '.');
...@@ -2651,6 +2648,8 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, ...@@ -2651,6 +2648,8 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename,
*p = '\0'; *p = '\0';
if (strcmp("devices.allow", filename) == 0 && value[0] == '/') { if (strcmp("devices.allow", filename) == 0 && value[0] == '/') {
int ret;
ret = convert_devpath(value, converted_value); ret = convert_devpath(value, converted_value);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -2667,9 +2666,7 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, ...@@ -2667,9 +2666,7 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename,
return -ENOENT; return -ENOENT;
} }
fullpath = must_make_path(h->container_full_path, filename, NULL); return lxc_write_openat(h->container_full_path, filename, value, strlen(value));
ret = lxc_write_to_file(fullpath, value, strlen(value), false, 0666);
return ret;
} }
__cgfsng_ops static bool cgfsng_setup_limits_legacy(struct cgroup_ops *ops, __cgfsng_ops static bool cgfsng_setup_limits_legacy(struct cgroup_ops *ops,
...@@ -2782,18 +2779,16 @@ __cgfsng_ops static bool cgfsng_setup_limits(struct cgroup_ops *ops, ...@@ -2782,18 +2779,16 @@ __cgfsng_ops static bool cgfsng_setup_limits(struct cgroup_ops *ops,
h = ops->unified; h = ops->unified;
lxc_list_for_each (iterator, cgroup_settings) { lxc_list_for_each (iterator, cgroup_settings) {
__do_free char *fullpath = NULL;
int ret;
struct lxc_cgroup *cg = iterator->elem; struct lxc_cgroup *cg = iterator->elem;
int ret;
if (strncmp("devices", cg->subsystem, 7) == 0) { if (strncmp("devices", cg->subsystem, 7) == 0) {
ret = bpf_device_cgroup_prepare(ops, conf, cg->subsystem, ret = bpf_device_cgroup_prepare(ops, conf, cg->subsystem,
cg->value); cg->value);
} else { } else {
fullpath = must_make_path(h->container_full_path, ret = lxc_write_openat(h->container_full_path,
cg->subsystem, NULL); cg->subsystem, cg->value,
ret = lxc_write_to_file(fullpath, cg->value, strlen(cg->value));
strlen(cg->value), false, 0666);
if (ret < 0) if (ret < 0)
return log_error_errno(false, return log_error_errno(false,
errno, "Failed to set \"%s\" to \"%s\"", errno, "Failed to set \"%s\" to \"%s\"",
......
...@@ -18,6 +18,27 @@ ...@@ -18,6 +18,27 @@
#include "string_utils.h" #include "string_utils.h"
#include "utils.h" #include "utils.h"
int lxc_open_dirfd(const char *dir)
{
return open(dir, O_DIRECTORY | O_RDONLY | O_CLOEXEC);
}
int lxc_readat(int dirfd, const char *filename, void *buf, size_t count)
{
__do_close_prot_errno int fd = -EBADF;
ssize_t ret;
fd = openat(dirfd, filename, O_RDONLY | O_CLOEXEC);
if (fd < 0)
return -1;
ret = lxc_read_nointr(fd, buf, count);
if (ret < 0 || (size_t)ret != count)
return -1;
return 0;
}
int lxc_writeat(int dirfd, const char *filename, const void *buf, size_t count) int lxc_writeat(int dirfd, const char *filename, const void *buf, size_t count)
{ {
__do_close_prot_errno int fd = -EBADF; __do_close_prot_errno int fd = -EBADF;
...@@ -34,6 +55,18 @@ int lxc_writeat(int dirfd, const char *filename, const void *buf, size_t count) ...@@ -34,6 +55,18 @@ int lxc_writeat(int dirfd, const char *filename, const void *buf, size_t count)
return 0; return 0;
} }
int lxc_write_openat(const char *dir, const char *filename, const void *buf,
size_t count)
{
__do_close_prot_errno int dirfd = -EBADF;
dirfd = open(dir, O_DIRECTORY | O_RDONLY | O_CLOEXEC);
if (dirfd < 0)
return -1;
return lxc_writeat(dirfd, filename, buf, count);
}
int lxc_write_to_file(const char *filename, const void *buf, size_t count, int lxc_write_to_file(const char *filename, const void *buf, size_t count,
bool add_newline, mode_t mode) bool add_newline, mode_t mode)
{ {
......
...@@ -14,8 +14,11 @@ ...@@ -14,8 +14,11 @@
/* read and write whole files */ /* read and write whole files */
extern int lxc_write_to_file(const char *filename, const void *buf, extern int lxc_write_to_file(const char *filename, const void *buf,
size_t count, bool add_newline, mode_t mode); size_t count, bool add_newline, mode_t mode);
extern int lxc_readat(int dirfd, const char *filename, void *buf, size_t count);
extern int lxc_writeat(int dirfd, const char *filename, const void *buf, extern int lxc_writeat(int dirfd, const char *filename, const void *buf,
size_t count); size_t count);
extern int lxc_write_openat(const char *dir, const char *filename,
const void *buf, size_t count);
extern int lxc_read_from_file(const char *filename, void *buf, size_t count); extern int lxc_read_from_file(const char *filename, void *buf, size_t count);
/* send and receive buffers completely */ /* send and receive buffers completely */
...@@ -42,5 +45,6 @@ extern ssize_t lxc_sendfile_nointr(int out_fd, int in_fd, off_t *offset, ...@@ -42,5 +45,6 @@ extern ssize_t lxc_sendfile_nointr(int out_fd, int in_fd, off_t *offset,
size_t count); size_t count);
extern char *file_to_buf(char *path, size_t *length); extern char *file_to_buf(char *path, size_t *length);
extern int fd_to_fd(int from, int to); extern int fd_to_fd(int from, int to);
extern int lxc_open_dirfd(const char *dir);
#endif /* __LXC_FILE_UTILS_H */ #endif /* __LXC_FILE_UTILS_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment