2023-07-27 09:31:08 +00:00
|
|
|
From 79d335011ffccfee542ee5068fda6257a9ac1e59 Mon Sep 17 00:00:00 2001
|
2023-07-14 03:16:39 +00:00
|
|
|
From: vegbir <yangjiaqi16@huawei.com>
|
2023-07-27 09:31:08 +00:00
|
|
|
Date: Thu, 27 Jul 2023 06:40:47 +0000
|
|
|
|
|
Subject: [PATCH 02/15] show dev name in container
|
2021-11-27 15:55:20 +08:00
|
|
|
|
2023-07-14 03:16:39 +00:00
|
|
|
append: fix hang
|
|
|
|
|
append: limit-stat-by-quota-period-setting
|
|
|
|
|
append: fix-proc-diskstats-show-in-container
|
|
|
|
|
append: proc_fuse fix wait child process hang
|
|
|
|
|
append: fix deadlock problem when subprocess exit
|
|
|
|
|
append: fix dev read memory leak in container
|
|
|
|
|
|
|
|
|
|
Signed-off-by: vegbir <yangjiaqi16@huawei.com>
|
2021-11-27 15:55:20 +08:00
|
|
|
---
|
2023-07-14 03:16:39 +00:00
|
|
|
src/proc_fuse.c | 183 +++++++++++++++++++++++++++++++++++++++++++++++-
|
|
|
|
|
1 file changed, 181 insertions(+), 2 deletions(-)
|
2021-11-27 15:55:20 +08:00
|
|
|
|
2020-08-28 15:17:28 +08:00
|
|
|
diff --git a/src/proc_fuse.c b/src/proc_fuse.c
|
2023-07-27 09:31:08 +00:00
|
|
|
index 25af10a..cde48ca 100644
|
2020-08-28 15:17:28 +08:00
|
|
|
--- a/src/proc_fuse.c
|
|
|
|
|
+++ b/src/proc_fuse.c
|
2023-07-14 03:16:39 +00:00
|
|
|
@@ -28,6 +28,7 @@
|
2020-08-28 15:17:28 +08:00
|
|
|
#include <sys/socket.h>
|
|
|
|
|
#include <sys/syscall.h>
|
|
|
|
|
#include <sys/sysinfo.h>
|
|
|
|
|
+#include <sys/sysmacros.h>
|
|
|
|
|
#include <sys/vfs.h>
|
|
|
|
|
|
2021-11-27 15:55:20 +08:00
|
|
|
#include "proc_fuse.h"
|
2023-07-14 03:16:39 +00:00
|
|
|
@@ -43,6 +44,26 @@
|
|
|
|
|
#include "proc_cpuview.h"
|
|
|
|
|
#include "utils.h"
|
|
|
|
|
|
|
|
|
|
+static pthread_mutex_t container_dev_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
|
+
|
|
|
|
|
+static void lock_mutex(pthread_mutex_t *l)
|
|
|
|
|
+{
|
|
|
|
|
+ int ret;
|
|
|
|
|
+
|
|
|
|
|
+ ret = pthread_mutex_lock(l);
|
|
|
|
|
+ if (ret)
|
|
|
|
|
+ log_exit("%s - returned %d\n", strerror(ret), ret);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static void unlock_mutex(pthread_mutex_t *l)
|
|
|
|
|
+{
|
|
|
|
|
+ int ret;
|
|
|
|
|
+
|
|
|
|
|
+ ret = pthread_mutex_unlock(l);
|
|
|
|
|
+ if (ret)
|
|
|
|
|
+ log_exit("%s - returned %d\n", strerror(ret), ret);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
struct memory_stat {
|
|
|
|
|
uint64_t hierarchical_memory_limit;
|
|
|
|
|
uint64_t hierarchical_memsw_limit;
|
|
|
|
|
@@ -473,6 +494,146 @@ static void get_blkio_io_value(char *str, unsigned major, unsigned minor,
|
2020-08-28 15:17:28 +08:00
|
|
|
}
|
2019-11-06 19:42:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+struct devinfo {
|
2020-08-28 15:17:28 +08:00
|
|
|
+ char *name;
|
2023-07-14 03:16:39 +00:00
|
|
|
+ unsigned int major, minor;
|
2019-11-06 19:42:23 +08:00
|
|
|
+ struct devinfo *next;
|
|
|
|
|
+};
|
|
|
|
|
+
|
2020-08-28 15:17:28 +08:00
|
|
|
+int getns(pid_t pid, const char *ns_type)
|
2019-11-06 19:42:23 +08:00
|
|
|
+{
|
|
|
|
|
+ char fpath[100];
|
2020-08-28 15:17:28 +08:00
|
|
|
+ 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;
|
2023-07-27 09:31:08 +00:00
|
|
|
+ char fpath[261], dev_name[101];
|
2019-11-06 19:42:23 +08:00
|
|
|
+ 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) {
|
2023-07-14 03:16:39 +00:00
|
|
|
+ /* Disallow signal reception in child process */
|
|
|
|
|
+ sigset_t oldset;
|
|
|
|
|
+ sigset_t newset;
|
|
|
|
|
+ sigemptyset(&newset);
|
|
|
|
|
+ sigaddset(&newset, SIGTERM);
|
|
|
|
|
+ sigaddset(&newset, SIGINT);
|
|
|
|
|
+ sigaddset(&newset, SIGHUP);
|
|
|
|
|
+ sigaddset(&newset, SIGQUIT);
|
|
|
|
|
+ sigprocmask(SIG_BLOCK,&newset,&oldset);
|
|
|
|
|
+
|
2019-11-06 19:42:23 +08:00
|
|
|
+ close(mypipe[0]);
|
|
|
|
|
+ stream = fdopen(mypipe[1], "w");
|
|
|
|
|
+ if (stream == NULL) {
|
|
|
|
|
+ lxcfs_error("Error opening pipe for writing: %s\n", strerror(errno));
|
2020-08-28 15:17:28 +08:00
|
|
|
+ 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));
|
2020-08-28 15:17:28 +08:00
|
|
|
+ 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));
|
2020-08-28 15:17:28 +08:00
|
|
|
+ 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));
|
2020-08-28 15:17:28 +08:00
|
|
|
+ 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;
|
|
|
|
|
+ }
|
2020-08-28 15:17:28 +08:00
|
|
|
+ memset(fpath, 0, sizeof(fpath));
|
2023-07-14 03:16:39 +00:00
|
|
|
+ snprintf(fpath, 261, "/dev/%s", ptr->d_name);
|
2019-11-06 19:42:23 +08:00
|
|
|
+ stat(fpath, &dev_stat);
|
2023-07-14 03:16:39 +00:00
|
|
|
+ fprintf(stream, "%s %ld ", ptr->d_name, dev_stat.st_rdev);
|
2019-11-06 19:42:23 +08:00
|
|
|
+ fflush(stream);
|
|
|
|
|
+ }
|
2020-08-28 15:17:28 +08:00
|
|
|
+ closedir(dir);
|
2019-11-06 19:42:23 +08:00
|
|
|
+ stat("/", &dev_stat);
|
2023-07-14 03:16:39 +00:00
|
|
|
+ dev_num = dev_stat.st_dev;
|
2019-11-06 19:42:23 +08:00
|
|
|
+ fprintf(stream, "sda %d end 0 ", dev_num);
|
|
|
|
|
+ fflush(stream);
|
2023-07-14 03:16:39 +00:00
|
|
|
+child_out:
|
2020-08-28 15:17:28 +08:00
|
|
|
+ fclose(stream);
|
2023-07-14 03:16:39 +00:00
|
|
|
+ _exit(EXIT_SUCCESS);
|
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;
|
|
|
|
|
+ }
|
2023-07-14 03:16:39 +00:00
|
|
|
+ wait_for_pid(child_pid);
|
|
|
|
|
+ child_pid = 0;
|
|
|
|
|
+ memset(dev_name, 0, sizeof(dev_name));
|
2023-07-27 09:31:08 +00: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) {
|
2020-08-28 15:17:28 +08:00
|
|
|
+ do {
|
|
|
|
|
+ head = (struct devinfo*)malloc(sizeof(struct devinfo));
|
|
|
|
|
+ } while (!head);
|
2019-11-06 19:42:23 +08:00
|
|
|
+ end = head;
|
|
|
|
|
+ } else {
|
2020-08-28 15:17:28 +08:00
|
|
|
+ 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;
|
2020-08-28 15:17:28 +08:00
|
|
|
+ end->name = must_copy_string(dev_name);
|
|
|
|
|
+ end->major = major(dev_num);
|
|
|
|
|
+ end->minor = minor(dev_num);
|
2023-07-14 03:16:39 +00:00
|
|
|
+ memset(dev_name, 0, sizeof(dev_name));
|
2019-11-06 19:42:23 +08:00
|
|
|
+ }
|
|
|
|
|
+err:
|
2021-11-27 15:55:20 +08:00
|
|
|
+ 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;
|
2020-08-28 15:17:28 +08:00
|
|
|
+ free(tmp->name);
|
|
|
|
|
+ tmp->name = NULL;
|
2019-11-06 19:42:23 +08:00
|
|
|
+ free(tmp);
|
2020-08-28 15:17:28 +08:00
|
|
|
+ tmp = NULL;
|
2019-11-06 19:42:23 +08:00
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
2021-11-27 15:55:20 +08:00
|
|
|
struct lxcfs_diskstats {
|
|
|
|
|
unsigned int major; /* 1 - major number */
|
|
|
|
|
unsigned int minor; /* 2 - minor mumber */
|
2023-07-14 03:16:39 +00:00
|
|
|
@@ -505,6 +666,7 @@ static int proc_diskstats_read(char *buf, size_t size, off_t offset,
|
2020-08-28 15:17:28 +08:00
|
|
|
__do_fclose FILE *f = NULL;
|
2019-11-06 19:42:23 +08:00
|
|
|
struct fuse_context *fc = fuse_get_context();
|
2020-08-28 15:17:28 +08:00
|
|
|
struct file_info *d = INTTYPE_TO_PTR(fi->fh);
|
|
|
|
|
+ struct devinfo *container_devinfo = NULL, *ptr = NULL;
|
2021-11-27 15:55:20 +08:00
|
|
|
struct lxcfs_diskstats stats = {};
|
|
|
|
|
/* helper fields */
|
|
|
|
|
uint64_t read_service_time, write_service_time, discard_service_time, read_wait_time,
|
2023-07-14 03:16:39 +00:00
|
|
|
@@ -574,14 +736,26 @@ static int proc_diskstats_read(char *buf, size_t size, off_t offset,
|
2019-11-06 19:42:23 +08:00
|
|
|
if (!f)
|
2020-08-28 15:17:28 +08:00
|
|
|
return 0;
|
2019-11-06 19:42:23 +08:00
|
|
|
|
2023-07-14 03:16:39 +00:00
|
|
|
+ lock_mutex(&container_dev_mutex);
|
2019-11-06 19:42:23 +08:00
|
|
|
+ container_devinfo = container_dev_read(initpid);
|
2023-07-14 03:16:39 +00:00
|
|
|
+ unlock_mutex(&container_dev_mutex);
|
2019-11-06 19:42:23 +08:00
|
|
|
+
|
|
|
|
|
while (getline(&line, &linelen, f) != -1) {
|
|
|
|
|
ssize_t l;
|
|
|
|
|
char lbuf[256];
|
|
|
|
|
|
2021-11-27 15:55:20 +08:00
|
|
|
+ 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;
|
2023-07-14 03:16:39 +00:00
|
|
|
|
2019-11-06 19:42:23 +08:00
|
|
|
+ for (ptr = container_devinfo; ptr != NULL; ptr = ptr->next) {
|
2021-11-27 15:55:20 +08:00
|
|
|
+ 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
|
|
|
+ }
|
|
|
|
|
+ }
|
2023-07-14 03:16:39 +00:00
|
|
|
+
|
2021-11-27 15:55:20 +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);
|
2023-07-14 03:16:39 +00:00
|
|
|
get_blkio_io_value(io_serviced_str, stats.major, stats.minor, "Discard", &stats.discard);
|
2023-07-27 09:31:08 +00:00
|
|
|
@@ -672,10 +846,14 @@ static int proc_diskstats_read(char *buf, size_t size, off_t offset,
|
|
|
|
|
}
|
2020-08-28 15:17:28 +08:00
|
|
|
|
|
|
|
|
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");
|
2021-11-27 15:55:20 +08:00
|
|
|
- if ((size_t)l >= cache_size)
|
2020-08-28 15:17:28 +08:00
|
|
|
+ }
|
2021-11-27 15:55:20 +08:00
|
|
|
+ if ((size_t)l >= cache_size) {
|
2020-08-28 15:17:28 +08:00
|
|
|
+ free_devinfo_list(container_devinfo);
|
|
|
|
|
return log_error(0, "Write to cache was truncated");
|
|
|
|
|
+ }
|
2019-11-06 19:42:23 +08:00
|
|
|
|
2020-08-28 15:17:28 +08:00
|
|
|
cache += l;
|
|
|
|
|
cache_size -= l;
|
2023-07-27 09:31:08 +00:00
|
|
|
@@ -687,6 +865,7 @@ static int proc_diskstats_read(char *buf, size_t size, off_t offset,
|
2023-07-14 03:16:39 +00:00
|
|
|
if (total_len > size)
|
|
|
|
|
total_len = size;
|
|
|
|
|
memcpy(buf, d->buf, total_len);
|
|
|
|
|
+ free_devinfo_list(container_devinfo);
|
|
|
|
|
|
|
|
|
|
return total_len;
|
|
|
|
|
}
|
2021-11-27 15:55:20 +08:00
|
|
|
--
|
2023-07-14 03:16:39 +00:00
|
|
|
2.41.0
|
2021-11-27 15:55:20 +08:00
|
|
|
|