lxcfs/0008-fix-concurrency-problem.patch
2019-11-06 19:42:23 +08:00

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);