file_utils: introduce read_file_at()

Cc: stable-4.0 Signed-off-by: 's avatarChristian Brauner <christian.brauner@ubuntu.com>
parent b59bc011
......@@ -176,45 +176,6 @@ static struct hierarchy *get_hierarchy(struct cgroup_ops *ops, const char *contr
return ret_set_errno(NULL, ENOENT);
}
#define BATCH_SIZE 50
static void batch_realloc(char **mem, size_t oldlen, size_t newlen)
{
int newbatches = (newlen / BATCH_SIZE) + 1;
int oldbatches = (oldlen / BATCH_SIZE) + 1;
if (!*mem || newbatches > oldbatches)
*mem = must_realloc(*mem, newbatches * BATCH_SIZE);
}
static void append_line(char **dest, size_t oldlen, char *new, size_t newlen)
{
size_t full = oldlen + newlen;
batch_realloc(dest, oldlen, full + 1);
memcpy(*dest + oldlen, new, newlen + 1);
}
/* Slurp in a whole file */
static char *read_file(const char *fnam)
{
__do_free char *buf = NULL, *line = NULL;
__do_fclose FILE *f = NULL;
size_t len = 0, fulllen = 0;
int linelen;
f = fopen(fnam, "re");
if (!f)
return NULL;
while ((linelen = getline(&line, &len, f)) != -1) {
append_line(&buf, fulllen, line, linelen);
fulllen += linelen;
}
return move_ptr(buf);
}
/* Taken over modified from the kernel sources. */
#define NBITS 32 /* bits in uint32_t */
#define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d))
......@@ -350,7 +311,7 @@ static bool cg_legacy_filter_and_set_cpus(const char *parent_cgroup,
bool flipped_bit = false;
fpath = must_make_path(parent_cgroup, "cpuset.cpus", NULL);
posscpus = read_file(fpath);
posscpus = read_file_at(-EBADF, fpath);
if (!posscpus)
return log_error_errno(false, errno, "Failed to read file \"%s\"", fpath);
......@@ -360,7 +321,7 @@ static bool cg_legacy_filter_and_set_cpus(const char *parent_cgroup,
return false;
if (file_exists(__ISOL_CPUS)) {
isolcpus = read_file(__ISOL_CPUS);
isolcpus = read_file_at(-EBADF, __ISOL_CPUS);
if (!isolcpus)
return log_error_errno(false, errno, "Failed to read file \"%s\"", __ISOL_CPUS);
......@@ -379,7 +340,7 @@ static bool cg_legacy_filter_and_set_cpus(const char *parent_cgroup,
}
if (file_exists(__OFFLINE_CPUS)) {
offlinecpus = read_file(__OFFLINE_CPUS);
offlinecpus = read_file_at(-EBADF, __OFFLINE_CPUS);
if (!offlinecpus)
return log_error_errno(false, errno, "Failed to read file \"%s\"", __OFFLINE_CPUS);
......@@ -691,14 +652,14 @@ static char **cg_unified_make_empty_controller(void)
return move_ptr(aret);
}
static char **cg_unified_get_controllers(const char *file)
static char **cg_unified_get_controllers(int dfd, const char *file)
{
__do_free char *buf = NULL;
__do_free_string_list char **aret = NULL;
char *sep = " \t\n";
char *tok;
buf = read_file(file);
buf = read_file_at(dfd, file);
if (!buf)
return NULL;
......@@ -3148,7 +3109,7 @@ static void cg_unified_delegate(char ***delegate)
char *token;
int idx;
buf = read_file("/sys/kernel/cgroup/delegate");
buf = read_file_at(-EBADF, "/sys/kernel/cgroup/delegate");
if (!buf) {
for (char **p = standard; p && *p; p++) {
idx = append_null_to_list((void ***)delegate);
......@@ -3186,9 +3147,9 @@ static int cg_hybrid_init(struct cgroup_ops *ops, bool relative, bool unprivileg
* cgroups as our base in that case.
*/
if (!relative && (geteuid() == 0))
basecginfo = read_file("/proc/1/cgroup");
basecginfo = read_file_at(-EBADF, "/proc/1/cgroup");
else
basecginfo = read_file("/proc/self/cgroup");
basecginfo = read_file_at(-EBADF, "/proc/self/cgroup");
if (!basecginfo)
return ret_set_errno(-1, ENOMEM);
......@@ -3272,7 +3233,7 @@ static int cg_hybrid_init(struct cgroup_ops *ops, bool relative, bool unprivileg
"cgroup.controllers",
NULL);
controller_list = cg_unified_get_controllers(cgv2_ctrl_path);
controller_list = cg_unified_get_controllers(-EBADF, cgv2_ctrl_path);
free(cgv2_ctrl_path);
if (!controller_list) {
controller_list = cg_unified_make_empty_controller();
......@@ -3315,9 +3276,9 @@ static char *cg_unified_get_current_cgroup(bool relative)
char *base_cgroup;
if (!relative && (geteuid() == 0))
basecginfo = read_file("/proc/1/cgroup");
basecginfo = read_file_at(-EBADF, "/proc/1/cgroup");
else
basecginfo = read_file("/proc/self/cgroup");
basecginfo = read_file_at(-EBADF, "/proc/self/cgroup");
if (!basecginfo)
return NULL;
......
......@@ -592,3 +592,49 @@ int fd_make_nonblocking(int fd)
flags &= ~O_NONBLOCK;
return fcntl(fd, F_SETFL, flags);
}
#define BATCH_SIZE 50
static void batch_realloc(char **mem, size_t oldlen, size_t newlen)
{
int newbatches = (newlen / BATCH_SIZE) + 1;
int oldbatches = (oldlen / BATCH_SIZE) + 1;
if (!*mem || newbatches > oldbatches)
*mem = must_realloc(*mem, newbatches * BATCH_SIZE);
}
static void append_line(char **dest, size_t oldlen, char *new, size_t newlen)
{
size_t full = oldlen + newlen;
batch_realloc(dest, oldlen, full + 1);
memcpy(*dest + oldlen, new, newlen + 1);
}
/* Slurp in a whole file */
char *read_file_at(int dfd, const char *fnam)
{
__do_close int fd = -EBADF;
__do_free char *buf = NULL, *line = NULL;
__do_fclose FILE *f = NULL;
size_t len = 0, fulllen = 0;
int linelen;
fd = openat(dfd, fnam, O_NOCTTY | O_CLOEXEC | O_NOFOLLOW | O_RDONLY);
if (fd < 0)
return NULL;
f = fdopen(fd, "re");
if (!f)
return NULL;
/* Transfer ownership to fdopen(). */
move_fd(fd);
while ((linelen = getline(&line, &len, f)) != -1) {
append_line(&buf, fulllen, line, linelen);
fulllen += linelen;
}
return move_ptr(buf);
}
......@@ -81,5 +81,6 @@ __hidden extern bool exists_dir_at(int dir_fd, const char *path);
__hidden extern bool exists_file_at(int dir_fd, const char *path);
__hidden extern int open_beneath(int dir_fd, const char *path, unsigned int flags);
__hidden int fd_make_nonblocking(int fd);
__hidden extern char *read_file_at(int dfd, const char *fnam);
#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