172 lines
4.4 KiB
Diff
172 lines
4.4 KiB
Diff
diff --git a/bindings.c b/bindings.c
|
|
index 6387012..91de9f9 100644
|
|
--- a/bindings.c
|
|
+++ b/bindings.c
|
|
@@ -3743,12 +3743,136 @@ static int proc_uptime_read(char *buf, size_t size, off_t offset,
|
|
return total_len;
|
|
}
|
|
|
|
+struct devinfo {
|
|
+ char name[100];
|
|
+ int major, minor;
|
|
+ struct devinfo *next;
|
|
+};
|
|
+
|
|
+int getns(pid_t pid, char *ns_type)
|
|
+{
|
|
+ char fpath[100];
|
|
+ memset(fpath, 0, sizeof(fpath));
|
|
+ snprintf(fpath, 99, "/proc/%d/ns/%s", pid, ns_type);
|
|
+ return open(fpath, O_RDONLY);
|
|
+}
|
|
+
|
|
+struct devinfo* container_dev_read(pid_t pid) {
|
|
+ int nsfd;
|
|
+ DIR *dir;
|
|
+ struct dirent *ptr;
|
|
+ struct stat dev_stat;
|
|
+ struct devinfo *head = NULL, *end;
|
|
+ char fpath[100], dev_name[100];
|
|
+ pid_t child_pid;
|
|
+ int mypipe[2];
|
|
+ int dev_num;
|
|
+ FILE *stream;
|
|
+
|
|
+ if (pipe(mypipe) < 0) {
|
|
+ perror("Error creating pipe");
|
|
+ return head;
|
|
+ }
|
|
+
|
|
+ child_pid = fork();
|
|
+ if (child_pid < 0) {
|
|
+ close(mypipe[0]);
|
|
+ close(mypipe[1]);
|
|
+ perror("Error forking child");
|
|
+ return head;
|
|
+ }
|
|
+ if (child_pid == 0) {
|
|
+ close(mypipe[0]);
|
|
+ stream = fdopen(mypipe[1], "w");
|
|
+ if (stream == NULL) {
|
|
+ lxcfs_error("Error opening pipe for writing: %s\n", strerror(errno));
|
|
+ goto child_out;
|
|
+ }
|
|
+ nsfd = getns(pid, "mnt");
|
|
+ if (nsfd < 0) {
|
|
+ lxcfs_error("Error getting mnt ns: %s\n", strerror(errno));
|
|
+ goto child_out;
|
|
+ }
|
|
+ if (setns(nsfd, 0) < 0) {
|
|
+ lxcfs_error("Error setting mnt ns: %s\n", strerror(errno));
|
|
+ goto child_out;
|
|
+ }
|
|
+ dir = opendir("/dev");
|
|
+ if (dir == NULL) {
|
|
+ lxcfs_error("Error opening dir /dev: %s\n", strerror(errno));
|
|
+ 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));
|
|
+ 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);
|
|
+ stat("/", &dev_stat);
|
|
+ dev_num = dev_stat.st_dev & (~0xf);
|
|
+ fprintf(stream, "sda %d end 0 ", dev_num);
|
|
+ fflush(stream);
|
|
+child_out:
|
|
+ fclose(stream);
|
|
+ exit(0);
|
|
+ }
|
|
+
|
|
+ close(mypipe[1]);
|
|
+ stream = fdopen(mypipe[0], "r");
|
|
+ if (stream == NULL) {
|
|
+ lxcfs_error("Error opening pipe for reading: %s\n", strerror(errno));
|
|
+ goto err;
|
|
+ }
|
|
+ while (fscanf(stream, "%s%d", dev_name, &dev_num) == 2) {
|
|
+ if (dev_num == 0) {
|
|
+ break;
|
|
+ }
|
|
+ if (head == NULL) {
|
|
+ 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);
|
|
+ end = end->next;
|
|
+ }
|
|
+ end->next = NULL;
|
|
+ strncpy(end->name, dev_name, 100);
|
|
+ end->major = (dev_num & 0xff00) >> 8;
|
|
+ end->minor = dev_num & 0x00ff;
|
|
+ }
|
|
+err:
|
|
+ if (stream)
|
|
+ fclose(stream);
|
|
+ if (child_pid > 0)
|
|
+ wait_for_pid(child_pid);
|
|
+ return head;
|
|
+}
|
|
+
|
|
+void free_devinfo_list(struct devinfo *ptr)
|
|
+{
|
|
+ struct devinfo *tmp;
|
|
+ while (ptr != NULL) {
|
|
+ tmp = ptr;
|
|
+ ptr = ptr->next;
|
|
+ free(tmp);
|
|
+ }
|
|
+}
|
|
+
|
|
static int proc_diskstats_read(char *buf, size_t size, off_t offset,
|
|
struct fuse_file_info *fi)
|
|
{
|
|
char dev_name[72];
|
|
struct fuse_context *fc = fuse_get_context();
|
|
struct file_info *d = (struct file_info *)fi->fh;
|
|
+ struct devinfo *container_devinfo = NULL, *ptr;
|
|
char *cg;
|
|
char *io_serviced_str = NULL, *io_merged_str = NULL, *io_service_bytes_str = NULL,
|
|
*io_wait_time_str = NULL, *io_service_time_str = NULL;
|
|
@@ -3801,13 +3925,21 @@ static int proc_diskstats_read(char *buf, size_t size, off_t offset,
|
|
if (!f)
|
|
goto err;
|
|
|
|
+ container_devinfo = container_dev_read(initpid);
|
|
+
|
|
while (getline(&line, &linelen, f) != -1) {
|
|
ssize_t l;
|
|
char lbuf[256];
|
|
|
|
+ memset(dev_name, 0, sizeof(dev_name));
|
|
i = sscanf(line, "%u %u %71s", &major, &minor, dev_name);
|
|
if (i != 3)
|
|
continue;
|
|
+ for (ptr = container_devinfo; ptr != NULL; ptr = ptr->next) {
|
|
+ if (major == ptr->major && minor == ptr->minor) {
|
|
+ strncpy(dev_name, ptr->name, 71);
|
|
+ }
|
|
+ }
|
|
|
|
get_blkio_io_value(io_serviced_str, major, minor, "Read", &read);
|
|
get_blkio_io_value(io_serviced_str, major, minor, "Write", &write);
|
|
@@ -3873,6 +4005,7 @@ err:
|
|
free(io_service_bytes_str);
|
|
free(io_wait_time_str);
|
|
free(io_service_time_str);
|
|
+ free_devinfo_list(container_devinfo);
|
|
return rv;
|
|
}
|
|
|