246 lines
8.2 KiB
Diff
246 lines
8.2 KiB
Diff
diff --git a/bindings.c b/bindings.c
|
|
index c04993c..9b9f180 100644
|
|
--- a/bindings.c
|
|
+++ b/bindings.c
|
|
@@ -110,6 +110,7 @@ struct pidns_init_store {
|
|
|
|
static struct pidns_init_store *pidns_hash_table[PIDNS_HASH_SIZE];
|
|
static pthread_mutex_t pidns_store_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
+static pthread_mutex_t slurp_file_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
static void lock_mutex(pthread_mutex_t *l)
|
|
{
|
|
int ret;
|
|
@@ -330,28 +331,31 @@ static inline void drop_trailing_newlines(char *s)
|
|
}
|
|
|
|
#define BATCH_SIZE 50
|
|
-static void dorealloc(char **mem, size_t oldlen, size_t newlen)
|
|
+char * dorealloc(char *mem, size_t oldlen, size_t newlen)
|
|
{
|
|
int newbatches = (newlen / BATCH_SIZE) + 1;
|
|
int oldbatches = (oldlen / BATCH_SIZE) + 1;
|
|
|
|
- if (!*mem || newbatches > oldbatches) {
|
|
+ if (!mem || newbatches > oldbatches) {
|
|
char *tmp;
|
|
do {
|
|
- tmp = realloc(*mem, newbatches * BATCH_SIZE);
|
|
+ tmp = realloc(mem, newbatches * BATCH_SIZE);
|
|
} while (!tmp);
|
|
- *mem = tmp;
|
|
+ return tmp;
|
|
}
|
|
+ return mem;
|
|
}
|
|
-static void append_line(char **contents, size_t *len, char *line, ssize_t linelen)
|
|
+char * append_line(char *contents, size_t *len, char *line, ssize_t linelen)
|
|
{
|
|
+ char *tmp;
|
|
size_t newlen = *len + linelen;
|
|
- dorealloc(contents, *len, newlen + 1);
|
|
- memcpy(*contents + *len, line, linelen+1);
|
|
+ tmp = dorealloc(contents, *len, newlen + 1);
|
|
+ memcpy(tmp + *len, line, linelen+1);
|
|
*len = newlen;
|
|
+ return tmp;
|
|
}
|
|
|
|
-static char *slurp_file(int fd)
|
|
+char *slurp_file(int fd)
|
|
{
|
|
char *line = NULL;
|
|
char *contents = NULL;
|
|
@@ -363,7 +367,7 @@ static char *slurp_file(int fd)
|
|
return NULL;
|
|
|
|
while ((linelen = getline(&line, &len, f)) != -1) {
|
|
- append_line(&contents, &fulllen, line, linelen);
|
|
+ contents = append_line(contents, &fulllen, line, linelen);
|
|
}
|
|
fclose(f);
|
|
|
|
@@ -870,15 +874,15 @@ void free_keys(struct cgfs_files **keys)
|
|
free(keys);
|
|
}
|
|
|
|
-bool cgfs_get_value(const char *controller, const char *cgroup, const char *file, char **value)
|
|
+char * cgfs_get_value(const char *controller, const char *cgroup, const char *file)
|
|
{
|
|
int ret, fd, cfd;
|
|
size_t len;
|
|
- char *fnam, *tmpc;
|
|
+ char *fnam, *tmpc, *value;
|
|
|
|
tmpc = find_mounted_controller(controller, &cfd);
|
|
if (!tmpc)
|
|
- return false;
|
|
+ return NULL;
|
|
|
|
/* Make sure we pass a relative path to *at() family of functions.
|
|
* . + /cgroup + / + file + \0
|
|
@@ -886,25 +890,25 @@ bool cgfs_get_value(const char *controller, const char *cgroup, const char *file
|
|
len = strlen(cgroup) + strlen(file) + 3;
|
|
fnam = malloc(len);
|
|
if (!fnam) {
|
|
- return false;
|
|
+ return NULL;
|
|
}
|
|
ret = snprintf(fnam, len, "%s%s/%s", *cgroup == '/' ? "." : "", cgroup, file);
|
|
if (ret < 0 || (size_t)ret >= len) {
|
|
free(fnam);
|
|
- return false;
|
|
+ return NULL;
|
|
}
|
|
|
|
fd = openat(cfd, fnam, O_RDONLY);
|
|
if (fd < 0) {
|
|
free(fnam);
|
|
- return false;
|
|
+ return NULL;
|
|
}
|
|
|
|
free(fnam);
|
|
- store_lock();
|
|
- *value = slurp_file(fd);
|
|
- store_unlock();
|
|
- return *value != NULL;
|
|
+ lock_mutex(&slurp_file_mutex);
|
|
+ value = slurp_file(fd);
|
|
+ unlock_mutex(&slurp_file_mutex);
|
|
+ return value;
|
|
}
|
|
|
|
struct cgfs_files *cgfs_get_key(const char *controller, const char *cgroup, const char *file)
|
|
@@ -2288,7 +2292,7 @@ bool do_read_pids(pid_t tpid, const char *contrl, const char *cg, const char *fi
|
|
struct ucred cred;
|
|
size_t sz = 0, asz = 0;
|
|
|
|
- if (!cgfs_get_value(contrl, cg, file, &tmpdata))
|
|
+ if (!(tmpdata = cgfs_get_value(contrl, cg, file)))
|
|
return false;
|
|
|
|
/*
|
|
@@ -2401,8 +2405,10 @@ int cg_read(const char *path, char *buf, size_t size, off_t offset,
|
|
strcmp(f->file, "cgroup.procs") == 0)
|
|
// special case - we have to translate the pids
|
|
r = do_read_pids(fc->pid, f->controller, f->cgroup, f->file, &data);
|
|
- else
|
|
- r = cgfs_get_value(f->controller, f->cgroup, f->file, &data);
|
|
+ else {
|
|
+ data = cgfs_get_value(f->controller, f->cgroup, f->file);
|
|
+ r = !data;
|
|
+ }
|
|
|
|
if (!r) {
|
|
ret = -EINVAL;
|
|
@@ -3089,7 +3095,7 @@ static unsigned long get_memlimit(const char *cgroup, const char *file)
|
|
char *memlimit_str = NULL;
|
|
unsigned long memlimit = 0;
|
|
|
|
- if (cgfs_get_value("memory", cgroup, file, &memlimit_str))
|
|
+ if ((memlimit_str = cgfs_get_value("memory", cgroup, file)))
|
|
memlimit = strtoul(memlimit_str, NULL, 10);
|
|
|
|
free(memlimit_str);
|
|
@@ -3099,8 +3105,7 @@ static unsigned long get_memlimit(const char *cgroup, const char *file)
|
|
|
|
static unsigned long get_min_memlimit(const char *cgroup, const char *file)
|
|
{
|
|
- char copy[MAXPATHLEN];
|
|
- strcpy(copy, cgroup);
|
|
+ char *copy = strdupa(cgroup);
|
|
unsigned long memlimit = 0, retlimit;
|
|
|
|
retlimit = get_memlimit(copy, file);
|
|
@@ -3109,7 +3114,7 @@ static unsigned long get_min_memlimit(const char *cgroup, const char *file)
|
|
}
|
|
|
|
while (strcmp(copy, "/") != 0) {
|
|
- dirname(copy);
|
|
+ copy = dirname(copy);
|
|
memlimit = get_memlimit(copy, file);
|
|
if (memlimit != 0 && memlimit < retlimit)
|
|
retlimit = memlimit;
|
|
@@ -3157,14 +3162,14 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
|
|
memlimit = get_min_memlimit(cg, "memory.limit_in_bytes");
|
|
if (memlimit == 0)
|
|
goto err;
|
|
- if (!cgfs_get_value("memory", cg, "memory.usage_in_bytes", &memusage_str))
|
|
+ if (!(memusage_str = cgfs_get_value("memory", cg, "memory.usage_in_bytes")))
|
|
goto err;
|
|
- if (!cgfs_get_value("memory", cg, "memory.stat", &memstat_str))
|
|
+ if (!(memstat_str = cgfs_get_value("memory", cg, "memory.stat")))
|
|
goto err;
|
|
|
|
// Following values are allowed to fail, because swapaccount might be turned
|
|
// off for current kernel
|
|
- if (cgfs_get_value("memory", cg, "memory.memsw.usage_in_bytes", &memswusage_str))
|
|
+ if (memswusage_str = cgfs_get_value("memory", cg, "memory.memsw.usage_in_bytes"))
|
|
{
|
|
memswlimit = get_min_memlimit(cg, "memory.memsw.limit_in_bytes");
|
|
memswusage = strtoul(memswusage_str, NULL, 10);
|
|
@@ -3310,7 +3315,7 @@ static char *get_cpuset(const char *cg)
|
|
{
|
|
char *answer = NULL;
|
|
|
|
- if (!cgfs_get_value("cpuset", cg, "cpuset.cpus", &answer))
|
|
+ if (!(answer = cgfs_get_value("cpuset", cg, "cpuset.cpus")))
|
|
return NULL;
|
|
return answer;
|
|
}
|
|
@@ -3835,7 +3840,7 @@ static unsigned long get_reaper_busy(pid_t task)
|
|
if (!cgroup)
|
|
goto out;
|
|
prune_init_slice(cgroup);
|
|
- if (!cgfs_get_value("cpuacct", cgroup, "cpuacct.usage", &usage_str))
|
|
+ if (!(usage_str = cgfs_get_value("cpuacct", cgroup, "cpuacct.usage")))
|
|
goto out;
|
|
usage = strtoul(usage_str, NULL, 10);
|
|
usage /= 1000000000;
|
|
@@ -4077,15 +4082,15 @@ static int proc_diskstats_read(char *buf, size_t size, off_t offset,
|
|
return read_file("/proc/diskstats", buf, size, d);
|
|
prune_init_slice(cg);
|
|
|
|
- if (!cgfs_get_value("blkio", cg, "blkio.io_serviced_recursive", &io_serviced_str))
|
|
+ if (!(io_serviced_str = cgfs_get_value("blkio", cg, "blkio.io_serviced_recursive")))
|
|
goto err;
|
|
- if (!cgfs_get_value("blkio", cg, "blkio.io_merged_recursive", &io_merged_str))
|
|
+ if (!(io_merged_str = cgfs_get_value("blkio", cg, "blkio.io_merged_recursive")))
|
|
goto err;
|
|
- if (!cgfs_get_value("blkio", cg, "blkio.io_service_bytes_recursive", &io_service_bytes_str))
|
|
+ if (!(io_service_bytes_str = cgfs_get_value("blkio", cg, "blkio.io_service_bytes_recursive")))
|
|
goto err;
|
|
- if (!cgfs_get_value("blkio", cg, "blkio.io_wait_time_recursive", &io_wait_time_str))
|
|
+ if (!(io_wait_time_str = cgfs_get_value("blkio", cg, "blkio.io_wait_time_recursive")))
|
|
goto err;
|
|
- if (!cgfs_get_value("blkio", cg, "blkio.io_service_time_recursive", &io_service_time_str))
|
|
+ if (!(io_service_time_str = cgfs_get_value("blkio", cg, "blkio.io_service_time_recursive")))
|
|
goto err;
|
|
|
|
|
|
@@ -4213,12 +4218,12 @@ static int proc_swaps_read(char *buf, size_t size, off_t offset,
|
|
if (memlimit == 0)
|
|
goto err;
|
|
|
|
- if (!cgfs_get_value("memory", cg, "memory.usage_in_bytes", &memusage_str))
|
|
+ if (!(memusage_str = cgfs_get_value("memory", cg, "memory.usage_in_bytes")))
|
|
goto err;
|
|
|
|
memusage = strtoul(memusage_str, NULL, 10);
|
|
|
|
- if (cgfs_get_value("memory", cg, "memory.memsw.usage_in_bytes", &memswusage_str)) {
|
|
+ if (memswusage_str = cgfs_get_value("memory", cg, "memory.memsw.usage_in_bytes")) {
|
|
|
|
memswlimit = get_min_memlimit(cg, "memory.memsw.limit_in_bytes");
|
|
memswusage = strtoul(memswusage_str, NULL, 10);
|
|
@@ -4403,6 +4408,9 @@ int proc_read(const char *path, char *buf, size_t size, off_t offset,
|
|
{
|
|
struct file_info *f = (struct file_info *) fi->fh;
|
|
|
|
+ if (!f->buf)
|
|
+ return -EINVAL;
|
|
+
|
|
switch (f->type) {
|
|
case LXC_TYPE_PROC_MEMINFO:
|
|
return proc_meminfo_read(buf, size, offset, fi);
|