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