lxcfs/0003-show-dev-name-in-container.patch

206 lines
5.4 KiB
Diff
Raw Normal View History

From d6234626d7240952da42902b7ef513d56d5a18a7 Mon Sep 17 00:00:00 2001
From: yangjiaqi <yangjiaqi16@huawei.com>
Date: Thu, 25 Nov 2021 11:32:37 +0800
Subject: [PATCH 03/17] show-dev-name-in-container
---
src/proc_fuse.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 143 insertions(+), 2 deletions(-)
diff --git a/src/proc_fuse.c b/src/proc_fuse.c
index 94168c9..7372a36 100644
--- a/src/proc_fuse.c
+++ b/src/proc_fuse.c
@@ -27,6 +27,7 @@
#include <sys/socket.h>
#include <sys/syscall.h>
#include <sys/sysinfo.h>
+#include <sys/sysmacros.h>
#include <sys/vfs.h>
#include "proc_fuse.h"
@@ -448,6 +449,132 @@ static void get_blkio_io_value(char *str, unsigned major, unsigned minor,
}
2019-11-06 19:42:23 +08:00
}
+struct devinfo {
+ char *name;
2019-11-06 19:42:23 +08:00
+ int major, minor;
+ struct devinfo *next;
+};
+
+int getns(pid_t pid, const char *ns_type)
2019-11-06 19:42:23 +08:00
+{
+ char fpath[100];
+ memset(fpath, 0, sizeof(fpath));
2019-11-06 19:42:23 +08:00
+ 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;
2019-11-06 19:42:23 +08:00
+ }
+ nsfd = getns(pid, "mnt");
+ if (nsfd < 0) {
+ lxcfs_error("Error getting mnt ns: %s\n", strerror(errno));
+ goto child_out;
2019-11-06 19:42:23 +08:00
+ }
+ if (setns(nsfd, 0) < 0) {
+ lxcfs_error("Error setting mnt ns: %s\n", strerror(errno));
+ goto child_out;
2019-11-06 19:42:23 +08:00
+ }
+ dir = opendir("/dev");
+ if (dir == NULL) {
+ lxcfs_error("Error opening dir /dev: %s\n", strerror(errno));
+ goto child_out;
2019-11-06 19:42:23 +08:00
+ }
+ while ((ptr = readdir(dir)) != NULL) {
+ if (ptr->d_type != DT_BLK && ptr->d_type != DT_CHR) {
+ continue;
+ }
+ memset(fpath, 0, sizeof(fpath));
2019-11-06 19:42:23 +08:00
+ 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);
2019-11-06 19:42:23 +08:00
+ stat("/", &dev_stat);
+ dev_num = dev_stat.st_dev & (~0xf);
+ fprintf(stream, "sda %d end 0 ", dev_num);
+ fflush(stream);
+ fclose(stream);
2019-11-06 19:42:23 +08:00
+ exit(0);
+ }
+
+child_out:
2019-11-06 19:42:23 +08:00
+ close(mypipe[1]);
+ stream = fdopen(mypipe[0], "r");
+ if (stream == NULL) {
+ lxcfs_error("Error opening pipe for reading: %s\n", strerror(errno));
+ goto err;
+ }
2019-12-13 15:46:40 +08:00
+ while (fscanf(stream, "%100s%d", dev_name, &dev_num) == 2) {
2019-11-06 19:42:23 +08:00
+ if (dev_num == 0) {
+ break;
+ }
+ if (head == NULL) {
+ do {
+ head = (struct devinfo*)malloc(sizeof(struct devinfo));
+ } while (!head);
2019-11-06 19:42:23 +08:00
+ end = head;
+ } else {
+ do {
+ end->next = (struct devinfo*)malloc(sizeof(struct devinfo));
+ } while (!end->next);
2019-11-06 19:42:23 +08:00
+ end = end->next;
+ }
+ end->next = NULL;
+ end->name = must_copy_string(dev_name);
+ end->major = major(dev_num);
+ end->minor = minor(dev_num);
2019-11-06 19:42:23 +08:00
+ }
+err:
+ if (stream)
+ fclose(stream);
2019-11-06 19:42:23 +08:00
+ 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->name);
+ tmp->name = NULL;
2019-11-06 19:42:23 +08:00
+ free(tmp);
+ tmp = NULL;
2019-11-06 19:42:23 +08:00
+ }
+}
+
struct lxcfs_diskstats {
unsigned int major; /* 1 - major number */
unsigned int minor; /* 2 - minor mumber */
@@ -480,6 +607,7 @@ static int proc_diskstats_read(char *buf, size_t size, off_t offset,
__do_fclose FILE *f = NULL;
2019-11-06 19:42:23 +08:00
struct fuse_context *fc = fuse_get_context();
struct file_info *d = INTTYPE_TO_PTR(fi->fh);
+ struct devinfo *container_devinfo = NULL, *ptr = NULL;
struct lxcfs_diskstats stats = {};
/* helper fields */
uint64_t read_service_time, write_service_time, discard_service_time, read_wait_time,
@@ -549,13 +677,22 @@ static int proc_diskstats_read(char *buf, size_t size, off_t offset,
2019-11-06 19:42:23 +08:00
if (!f)
return 0;
2019-11-06 19:42:23 +08:00
+ container_devinfo = container_dev_read(initpid);
+
while (getline(&line, &linelen, f) != -1) {
ssize_t l;
char lbuf[256];
+ memset(stats.dev_name, 0, sizeof(stats.dev_name));
i = sscanf(line, "%u %u %71s", &stats.major, &stats.minor, stats.dev_name);
2019-11-06 19:42:23 +08:00
if (i != 3)
continue;
+ for (ptr = container_devinfo; ptr != NULL; ptr = ptr->next) {
+ if (stats.major == ptr->major && stats.minor == ptr->minor) {
+ snprintf(stats.dev_name, sizeof(stats.dev_name), "%s", ptr->name);
+ stats.dev_name[71] = '\0';
2019-11-06 19:42:23 +08:00
+ }
+ }
get_blkio_io_value(io_serviced_str, stats.major, stats.minor, "Read", &stats.read);
get_blkio_io_value(io_serviced_str, stats.major, stats.minor, "Write", &stats.write);
@@ -620,10 +757,14 @@ static int proc_diskstats_read(char *buf, size_t size, off_t offset,
continue;
l = snprintf(cache, cache_size, "%s", lbuf);
- if (l < 0)
+ if (l < 0) {
+ free_devinfo_list(container_devinfo);
return log_error(0, "Failed to write cache");
- if ((size_t)l >= cache_size)
+ }
+ if ((size_t)l >= cache_size) {
+ free_devinfo_list(container_devinfo);
return log_error(0, "Write to cache was truncated");
+ }
2019-11-06 19:42:23 +08:00
cache += l;
cache_size -= l;
--
2.27.0