339 lines
10 KiB
Diff
339 lines
10 KiB
Diff
|
|
diff --git a/../lxcfs-3.0.2/bindings.c b/bindings.c
|
||
|
|
index 713b7ea..c04993c 100644
|
||
|
|
--- a/../lxcfs-3.0.2/bindings.c
|
||
|
|
+++ b/bindings.c
|
||
|
|
@@ -351,7 +351,7 @@ static void append_line(char **contents, size_t *len, char *line, ssize_t linele
|
||
|
|
*len = newlen;
|
||
|
|
}
|
||
|
|
|
||
|
|
-static char *slurp_file(const char *from, int fd)
|
||
|
|
+static char *slurp_file(int fd)
|
||
|
|
{
|
||
|
|
char *line = NULL;
|
||
|
|
char *contents = NULL;
|
||
|
|
@@ -484,6 +484,7 @@ bool cgfs_set_value(const char *controller, const char *cgroup, const char *file
|
||
|
|
const char *value)
|
||
|
|
{
|
||
|
|
int ret, fd, cfd;
|
||
|
|
+ bool ret_bool;
|
||
|
|
size_t len;
|
||
|
|
char *fnam, *tmpc;
|
||
|
|
|
||
|
|
@@ -495,16 +496,25 @@ bool cgfs_set_value(const char *controller, const char *cgroup, const char *file
|
||
|
|
* . + /cgroup + / + file + \0
|
||
|
|
*/
|
||
|
|
len = strlen(cgroup) + strlen(file) + 3;
|
||
|
|
- fnam = alloca(len);
|
||
|
|
+ fnam = malloc(len);
|
||
|
|
+ if (!fnam) {
|
||
|
|
+ return false;
|
||
|
|
+ }
|
||
|
|
ret = snprintf(fnam, len, "%s%s/%s", *cgroup == '/' ? "." : "", cgroup, file);
|
||
|
|
- if (ret < 0 || (size_t)ret >= len)
|
||
|
|
+ if (ret < 0 || (size_t)ret >= len) {
|
||
|
|
+ free(fnam);
|
||
|
|
return false;
|
||
|
|
+ }
|
||
|
|
|
||
|
|
fd = openat(cfd, fnam, O_WRONLY);
|
||
|
|
- if (fd < 0)
|
||
|
|
+ if (fd < 0) {
|
||
|
|
+ free(fnam);
|
||
|
|
return false;
|
||
|
|
+ }
|
||
|
|
|
||
|
|
- return write_string(fnam, value, fd);
|
||
|
|
+ ret_bool = write_string(fnam, value, fd);
|
||
|
|
+ free(fnam);
|
||
|
|
+ return ret_bool;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Chown all the files in the cgroup directory. We do this when we create
|
||
|
|
@@ -874,16 +884,26 @@ bool cgfs_get_value(const char *controller, const char *cgroup, const char *file
|
||
|
|
* . + /cgroup + / + file + \0
|
||
|
|
*/
|
||
|
|
len = strlen(cgroup) + strlen(file) + 3;
|
||
|
|
- fnam = alloca(len);
|
||
|
|
+ fnam = malloc(len);
|
||
|
|
+ if (!fnam) {
|
||
|
|
+ return false;
|
||
|
|
+ }
|
||
|
|
ret = snprintf(fnam, len, "%s%s/%s", *cgroup == '/' ? "." : "", cgroup, file);
|
||
|
|
- if (ret < 0 || (size_t)ret >= len)
|
||
|
|
+ if (ret < 0 || (size_t)ret >= len) {
|
||
|
|
+ free(fnam);
|
||
|
|
return false;
|
||
|
|
+ }
|
||
|
|
|
||
|
|
fd = openat(cfd, fnam, O_RDONLY);
|
||
|
|
- if (fd < 0)
|
||
|
|
+ if (fd < 0) {
|
||
|
|
+ free(fnam);
|
||
|
|
return false;
|
||
|
|
+ }
|
||
|
|
|
||
|
|
- *value = slurp_file(fnam, fd);
|
||
|
|
+ free(fnam);
|
||
|
|
+ store_lock();
|
||
|
|
+ *value = slurp_file(fd);
|
||
|
|
+ store_unlock();
|
||
|
|
return *value != NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -3067,7 +3087,7 @@ static int read_file(const char *path, char *buf, size_t size,
|
||
|
|
static unsigned long get_memlimit(const char *cgroup, const char *file)
|
||
|
|
{
|
||
|
|
char *memlimit_str = NULL;
|
||
|
|
- unsigned long memlimit = -1;
|
||
|
|
+ unsigned long memlimit = 0;
|
||
|
|
|
||
|
|
if (cgfs_get_value("memory", cgroup, file, &memlimit_str))
|
||
|
|
memlimit = strtoul(memlimit_str, NULL, 10);
|
||
|
|
@@ -3079,15 +3099,19 @@ 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 = strdupa(cgroup);
|
||
|
|
+ char copy[MAXPATHLEN];
|
||
|
|
+ strcpy(copy, cgroup);
|
||
|
|
unsigned long memlimit = 0, retlimit;
|
||
|
|
|
||
|
|
retlimit = get_memlimit(copy, file);
|
||
|
|
+ if (retlimit == 0) {
|
||
|
|
+ return retlimit;
|
||
|
|
+ }
|
||
|
|
|
||
|
|
while (strcmp(copy, "/") != 0) {
|
||
|
|
- copy = dirname(copy);
|
||
|
|
+ dirname(copy);
|
||
|
|
memlimit = get_memlimit(copy, file);
|
||
|
|
- if (memlimit != -1 && memlimit < retlimit)
|
||
|
|
+ if (memlimit != 0 && memlimit < retlimit)
|
||
|
|
retlimit = memlimit;
|
||
|
|
};
|
||
|
|
|
||
|
|
@@ -3100,8 +3124,7 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
|
||
|
|
struct fuse_context *fc = fuse_get_context();
|
||
|
|
struct file_info *d = (struct file_info *)fi->fh;
|
||
|
|
char *cg;
|
||
|
|
- char *memusage_str = NULL, *memstat_str = NULL,
|
||
|
|
- *memswlimit_str = NULL, *memswusage_str = NULL;
|
||
|
|
+ char *memusage_str = NULL, *memstat_str = NULL, *memswusage_str = NULL;
|
||
|
|
unsigned long memlimit = 0, memusage = 0, memswlimit = 0, memswusage = 0,
|
||
|
|
cached = 0, hosttotal = 0, active_anon = 0, inactive_anon = 0,
|
||
|
|
active_file = 0, inactive_file = 0, unevictable = 0, shmem = 0,
|
||
|
|
@@ -3132,6 +3155,8 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
|
||
|
|
prune_init_slice(cg);
|
||
|
|
|
||
|
|
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))
|
||
|
|
goto err;
|
||
|
|
if (!cgfs_get_value("memory", cg, "memory.stat", &memstat_str))
|
||
|
|
@@ -3139,8 +3164,7 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
|
||
|
|
|
||
|
|
// Following values are allowed to fail, because swapaccount might be turned
|
||
|
|
// off for current kernel
|
||
|
|
- if(cgfs_get_value("memory", cg, "memory.memsw.limit_in_bytes", &memswlimit_str) &&
|
||
|
|
- cgfs_get_value("memory", cg, "memory.memsw.usage_in_bytes", &memswusage_str))
|
||
|
|
+ if (cgfs_get_value("memory", cg, "memory.memsw.usage_in_bytes", &memswusage_str))
|
||
|
|
{
|
||
|
|
memswlimit = get_min_memlimit(cg, "memory.memsw.limit_in_bytes");
|
||
|
|
memswusage = strtoul(memswusage_str, NULL, 10);
|
||
|
|
@@ -3161,9 +3185,9 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
|
||
|
|
if (!f)
|
||
|
|
goto err;
|
||
|
|
|
||
|
|
+ char *printme, lbuf[100];
|
||
|
|
while (getline(&line, &linelen, f) != -1) {
|
||
|
|
ssize_t l;
|
||
|
|
- char *printme, lbuf[100];
|
||
|
|
|
||
|
|
memset(lbuf, 0, 100);
|
||
|
|
if (startswith(line, "MemTotal:")) {
|
||
|
|
@@ -3273,7 +3297,6 @@ err:
|
||
|
|
free(line);
|
||
|
|
free(cg);
|
||
|
|
free(memusage_str);
|
||
|
|
- free(memswlimit_str);
|
||
|
|
free(memswusage_str);
|
||
|
|
free(memstat_str);
|
||
|
|
return rv;
|
||
|
|
@@ -3285,7 +3308,7 @@ err:
|
||
|
|
*/
|
||
|
|
static char *get_cpuset(const char *cg)
|
||
|
|
{
|
||
|
|
- char *answer;
|
||
|
|
+ char *answer = NULL;
|
||
|
|
|
||
|
|
if (!cgfs_get_value("cpuset", cg, "cpuset.cpus", &answer))
|
||
|
|
return NULL;
|
||
|
|
@@ -3888,7 +3911,7 @@ static int proc_uptime_read(char *buf, size_t size, off_t offset,
|
||
|
|
}
|
||
|
|
|
||
|
|
struct devinfo {
|
||
|
|
- char name[100];
|
||
|
|
+ char *name;
|
||
|
|
int major, minor;
|
||
|
|
struct devinfo *next;
|
||
|
|
};
|
||
|
|
@@ -3896,7 +3919,7 @@ struct devinfo {
|
||
|
|
int getns(pid_t pid, char *ns_type)
|
||
|
|
{
|
||
|
|
char fpath[100];
|
||
|
|
- memset(fpath, 0, sizeof(fpath));
|
||
|
|
+ memset(fpath, 0, sizeof(fpath));
|
||
|
|
snprintf(fpath, 99, "/proc/%d/ns/%s", pid, ns_type);
|
||
|
|
return open(fpath, O_RDONLY);
|
||
|
|
}
|
||
|
|
@@ -3930,42 +3953,42 @@ struct devinfo* container_dev_read(pid_t pid) {
|
||
|
|
stream = fdopen(mypipe[1], "w");
|
||
|
|
if (stream == NULL) {
|
||
|
|
lxcfs_error("Error opening pipe for writing: %s\n", strerror(errno));
|
||
|
|
- goto child_out;
|
||
|
|
+ goto child_out;
|
||
|
|
}
|
||
|
|
nsfd = getns(pid, "mnt");
|
||
|
|
if (nsfd < 0) {
|
||
|
|
lxcfs_error("Error getting mnt ns: %s\n", strerror(errno));
|
||
|
|
- goto child_out;
|
||
|
|
+ goto child_out;
|
||
|
|
}
|
||
|
|
if (setns(nsfd, 0) < 0) {
|
||
|
|
lxcfs_error("Error setting mnt ns: %s\n", strerror(errno));
|
||
|
|
- goto child_out;
|
||
|
|
+ goto child_out;
|
||
|
|
}
|
||
|
|
dir = opendir("/dev");
|
||
|
|
if (dir == NULL) {
|
||
|
|
lxcfs_error("Error opening dir /dev: %s\n", strerror(errno));
|
||
|
|
- goto child_out;
|
||
|
|
+ goto child_out;
|
||
|
|
}
|
||
|
|
while ((ptr = readdir(dir)) != NULL) {
|
||
|
|
if (ptr->d_type != DT_BLK && ptr->d_type != DT_CHR) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
- memset(fpath, 0, sizeof(fpath));
|
||
|
|
+ memset(fpath, 0, sizeof(fpath));
|
||
|
|
snprintf(fpath, 99, "/dev/%s", ptr->d_name);
|
||
|
|
stat(fpath, &dev_stat);
|
||
|
|
fprintf(stream, "%s %d ", ptr->d_name, dev_stat.st_rdev);
|
||
|
|
fflush(stream);
|
||
|
|
}
|
||
|
|
- closedir(dir);
|
||
|
|
+ closedir(dir);
|
||
|
|
stat("/", &dev_stat);
|
||
|
|
dev_num = dev_stat.st_dev & (~0xf);
|
||
|
|
fprintf(stream, "sda %d end 0 ", dev_num);
|
||
|
|
fflush(stream);
|
||
|
|
-child_out:
|
||
|
|
- fclose(stream);
|
||
|
|
+ fclose(stream);
|
||
|
|
exit(0);
|
||
|
|
}
|
||
|
|
|
||
|
|
+child_out:
|
||
|
|
close(mypipe[1]);
|
||
|
|
stream = fdopen(mypipe[0], "r");
|
||
|
|
if (stream == NULL) {
|
||
|
|
@@ -3977,24 +4000,24 @@ child_out:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
if (head == NULL) {
|
||
|
|
- do {
|
||
|
|
- head = (struct devinfo*)malloc(sizeof(struct devinfo));
|
||
|
|
- } while (!head);
|
||
|
|
+ do {
|
||
|
|
+ head = (struct devinfo*)malloc(sizeof(struct devinfo));
|
||
|
|
+ } while (!head);
|
||
|
|
end = head;
|
||
|
|
} else {
|
||
|
|
- do {
|
||
|
|
- end->next = (struct devinfo*)malloc(sizeof(struct devinfo));
|
||
|
|
- } while (!end->next);
|
||
|
|
+ do {
|
||
|
|
+ end->next = (struct devinfo*)malloc(sizeof(struct devinfo));
|
||
|
|
+ } while (!end->next);
|
||
|
|
end = end->next;
|
||
|
|
}
|
||
|
|
end->next = NULL;
|
||
|
|
- strncpy(end->name, dev_name, 100);
|
||
|
|
+ end->name = must_copy_string(dev_name);
|
||
|
|
end->major = (dev_num & 0xff00) >> 8;
|
||
|
|
end->minor = dev_num & 0x00ff;
|
||
|
|
}
|
||
|
|
err:
|
||
|
|
- if (stream)
|
||
|
|
- fclose(stream);
|
||
|
|
+ if (stream)
|
||
|
|
+ fclose(stream);
|
||
|
|
if (child_pid > 0)
|
||
|
|
wait_for_pid(child_pid);
|
||
|
|
return head;
|
||
|
|
@@ -4006,6 +4029,7 @@ void free_devinfo_list(struct devinfo *ptr)
|
||
|
|
while (ptr != NULL) {
|
||
|
|
tmp = ptr;
|
||
|
|
ptr = ptr->next;
|
||
|
|
+ free(tmp->name);
|
||
|
|
free(tmp);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
@@ -4082,6 +4106,7 @@ static int proc_diskstats_read(char *buf, size_t size, off_t offset,
|
||
|
|
for (ptr = container_devinfo; ptr != NULL; ptr = ptr->next) {
|
||
|
|
if (major == ptr->major && minor == ptr->minor) {
|
||
|
|
strncpy(dev_name, ptr->name, 71);
|
||
|
|
+ dev_name[71] = '\0';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -4159,7 +4184,7 @@ static int proc_swaps_read(char *buf, size_t size, off_t offset,
|
||
|
|
struct fuse_context *fc = fuse_get_context();
|
||
|
|
struct file_info *d = (struct file_info *)fi->fh;
|
||
|
|
char *cg = NULL;
|
||
|
|
- char *memswlimit_str = NULL, *memlimit_str = NULL, *memusage_str = NULL, *memswusage_str = NULL;
|
||
|
|
+ char *memusage_str = NULL, *memswusage_str = NULL;
|
||
|
|
unsigned long memswlimit = 0, memlimit = 0, memusage = 0, memswusage = 0, swap_total = 0, swap_free = 0;
|
||
|
|
ssize_t total_len = 0, rv = 0;
|
||
|
|
ssize_t l = 0;
|
||
|
|
@@ -4185,20 +4210,25 @@ static int proc_swaps_read(char *buf, size_t size, off_t offset,
|
||
|
|
prune_init_slice(cg);
|
||
|
|
|
||
|
|
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))
|
||
|
|
goto err;
|
||
|
|
|
||
|
|
memusage = strtoul(memusage_str, NULL, 10);
|
||
|
|
|
||
|
|
- if (cgfs_get_value("memory", cg, "memory.memsw.usage_in_bytes", &memswusage_str) &&
|
||
|
|
- cgfs_get_value("memory", cg, "memory.memsw.limit_in_bytes", &memswlimit_str)) {
|
||
|
|
+ if (cgfs_get_value("memory", cg, "memory.memsw.usage_in_bytes", &memswusage_str)) {
|
||
|
|
|
||
|
|
memswlimit = get_min_memlimit(cg, "memory.memsw.limit_in_bytes");
|
||
|
|
memswusage = strtoul(memswusage_str, NULL, 10);
|
||
|
|
|
||
|
|
- swap_total = (memswlimit - memlimit) / 1024;
|
||
|
|
- swap_free = (memswusage - memusage) / 1024;
|
||
|
|
+ if (memswlimit > memlimit) {
|
||
|
|
+ swap_total = (memswlimit - memlimit) / 1024;
|
||
|
|
+ }
|
||
|
|
+ if (memswusage > memusage) {
|
||
|
|
+ swap_free = (memswusage - memusage) / 1024;
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
|
||
|
|
total_len = snprintf(d->buf, d->size, "Filename\t\t\t\tType\t\tSize\tUsed\tPriority\n");
|
||
|
|
@@ -4246,8 +4276,6 @@ static int proc_swaps_read(char *buf, size_t size, off_t offset,
|
||
|
|
|
||
|
|
err:
|
||
|
|
free(cg);
|
||
|
|
- free(memswlimit_str);
|
||
|
|
- free(memlimit_str);
|
||
|
|
free(memusage_str);
|
||
|
|
free(memswusage_str);
|
||
|
|
return rv;
|