2021-11-27 15:55:20 +08:00
|
|
|
From f4486dde281016cda897f1564dcb8ca0303f2fbf Mon Sep 17 00:00:00 2001
|
|
|
|
|
From: yangjiaqi <yangjiaqi16@huawei.com>
|
|
|
|
|
Date: Thu, 25 Nov 2021 16:01:12 +0800
|
|
|
|
|
Subject: [PATCH 11/17] lxcfs-add-proc-partitions
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
src/bindings.h | 3 ++
|
|
|
|
|
src/proc_fuse.c | 131 +++++++++++++++++++++++++++++++++++++++++++++---
|
|
|
|
|
2 files changed, 126 insertions(+), 8 deletions(-)
|
|
|
|
|
|
2020-08-28 15:17:28 +08:00
|
|
|
diff --git a/src/bindings.h b/src/bindings.h
|
2021-11-27 15:55:20 +08:00
|
|
|
index cd7d466..91d44c7 100644
|
2020-08-28 15:17:28 +08:00
|
|
|
--- a/src/bindings.h
|
|
|
|
|
+++ b/src/bindings.h
|
2021-11-27 15:55:20 +08:00
|
|
|
@@ -55,6 +55,9 @@ enum lxcfs_virt_t {
|
2020-08-28 15:17:28 +08:00
|
|
|
LXC_TYPE_PROC_LOADAVG,
|
|
|
|
|
#define LXC_TYPE_PROC_LOADAVG_PATH "/proc/loadavg"
|
|
|
|
|
|
|
|
|
|
+ LXC_TYPE_PROC_PARTITIONS,
|
|
|
|
|
+#define LXC_TYPE_PROC_PARTITIONS_PATH "/proc/partitions"
|
|
|
|
|
+
|
|
|
|
|
LXC_TYPE_SYS_DEVICES,
|
|
|
|
|
LXC_TYPE_SYS_DEVICES_SYSTEM,
|
|
|
|
|
LXC_TYPE_SYS_DEVICES_SYSTEM_CPU,
|
|
|
|
|
diff --git a/src/proc_fuse.c b/src/proc_fuse.c
|
2021-11-27 15:55:20 +08:00
|
|
|
index a613688..72f6de6 100644
|
2020-08-28 15:17:28 +08:00
|
|
|
--- a/src/proc_fuse.c
|
|
|
|
|
+++ b/src/proc_fuse.c
|
2021-11-27 15:55:20 +08:00
|
|
|
@@ -118,13 +118,14 @@ __lxcfs_fuse_ops int proc_getattr(const char *path, struct stat *sb)
|
2020-08-28 15:17:28 +08:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- if (strcmp(path, "/proc/meminfo") == 0 ||
|
|
|
|
|
- strcmp(path, "/proc/cpuinfo") == 0 ||
|
|
|
|
|
- strcmp(path, "/proc/uptime") == 0 ||
|
|
|
|
|
- strcmp(path, "/proc/stat") == 0 ||
|
|
|
|
|
- strcmp(path, "/proc/diskstats") == 0 ||
|
|
|
|
|
- strcmp(path, "/proc/swaps") == 0 ||
|
|
|
|
|
- strcmp(path, "/proc/loadavg") == 0) {
|
|
|
|
|
+ if (strcmp(path, "/proc/meminfo") == 0 ||
|
|
|
|
|
+ strcmp(path, "/proc/cpuinfo") == 0 ||
|
|
|
|
|
+ strcmp(path, "/proc/uptime") == 0 ||
|
|
|
|
|
+ strcmp(path, "/proc/stat") == 0 ||
|
|
|
|
|
+ strcmp(path, "/proc/diskstats") == 0 ||
|
|
|
|
|
+ strcmp(path, "/proc/swaps") == 0 ||
|
|
|
|
|
+ strcmp(path, "/proc/loadavg") == 0 ||
|
2021-11-27 15:55:20 +08:00
|
|
|
+ strcmp(path, "/proc/partitions") == 0) {
|
|
|
|
|
sb->st_size = get_procfile_size(path);
|
2020-08-28 15:17:28 +08:00
|
|
|
sb->st_mode = S_IFREG | 00444;
|
|
|
|
|
sb->st_nlink = 1;
|
2021-11-27 15:55:20 +08:00
|
|
|
@@ -146,7 +147,8 @@ __lxcfs_fuse_ops int proc_readdir(const char *path, void *buf,
|
|
|
|
|
DIR_FILLER(filler, buf, "uptime", NULL, 0) != 0 ||
|
|
|
|
|
DIR_FILLER(filler, buf, "diskstats", NULL, 0) != 0 ||
|
|
|
|
|
DIR_FILLER(filler, buf, "swaps", NULL, 0) != 0 ||
|
|
|
|
|
- DIR_FILLER(filler, buf, "loadavg", NULL, 0) != 0)
|
|
|
|
|
+ DIR_FILLER(filler, buf, "loadavg", NULL, 0) != 0 ||
|
|
|
|
|
+ DIR_FILLER(filler, buf, "partitions", NULL, 0) != 0)
|
2020-08-28 15:17:28 +08:00
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
|
|
return 0;
|
2021-11-27 15:55:20 +08:00
|
|
|
@@ -171,6 +173,8 @@ __lxcfs_fuse_ops int proc_open(const char *path, struct fuse_file_info *fi)
|
2020-08-28 15:17:28 +08:00
|
|
|
type = LXC_TYPE_PROC_SWAPS;
|
|
|
|
|
else if (strcmp(path, "/proc/loadavg") == 0)
|
|
|
|
|
type = LXC_TYPE_PROC_LOADAVG;
|
|
|
|
|
+ else if (strcmp(path, "/proc/partitions") == 0)
|
|
|
|
|
+ type = LXC_TYPE_PROC_PARTITIONS;
|
|
|
|
|
if (type == -1)
|
|
|
|
|
return -ENOENT;
|
|
|
|
|
|
2021-11-27 15:55:20 +08:00
|
|
|
@@ -872,6 +876,111 @@ static int proc_diskstats_read(char *buf, size_t size, off_t offset,
|
2020-08-28 15:17:28 +08:00
|
|
|
return total_len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+static int proc_partitions_read(char *buf, size_t size, off_t offset,
|
|
|
|
|
+ struct fuse_file_info *fi)
|
|
|
|
|
+{
|
|
|
|
|
+ char dev_name[72] = {0};
|
|
|
|
|
+ struct fuse_context *fc = fuse_get_context();
|
|
|
|
|
+ struct file_info *d = (struct file_info *)fi->fh;
|
|
|
|
|
+ struct devinfo *container_devinfo = NULL, *ptr = NULL;
|
|
|
|
|
+ char *cg = NULL;
|
|
|
|
|
+ char *cache = d->buf;
|
|
|
|
|
+ size_t cache_size = d->buflen;
|
|
|
|
|
+ char *line = NULL;
|
|
|
|
|
+ size_t linelen = 0, total_len = 0;
|
|
|
|
|
+ int rv = 0;
|
|
|
|
|
+ unsigned int major = 0, minor = 0;
|
|
|
|
|
+ unsigned long long blocks = 0;
|
|
|
|
|
+ int i = 0, lines = 0;
|
|
|
|
|
+ bool found = false;
|
|
|
|
|
+ FILE *f = NULL;
|
|
|
|
|
+
|
|
|
|
|
+ if (offset > 0){
|
|
|
|
|
+ if (offset > d->size)
|
|
|
|
|
+ return -EINVAL;
|
|
|
|
|
+ if (d->cached == 0)
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ int left = d->size - offset;
|
|
|
|
|
+ total_len = left > size ? size: left;
|
|
|
|
|
+
|
|
|
|
|
+ memcpy(buf, cache + offset, total_len);
|
|
|
|
|
+ return total_len;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ pid_t initpid = lookup_initpid_in_store(fc->pid);
|
|
|
|
|
+ if (initpid <= 0)
|
|
|
|
|
+ initpid = fc->pid;
|
|
|
|
|
+ cg = get_pid_cgroup(initpid, "blkio");
|
|
|
|
|
+ if (cg == NULL)
|
|
|
|
|
+ return read_file_fuse("/proc/partitions", buf, size, d);
|
|
|
|
|
+ prune_init_slice(cg);
|
|
|
|
|
+
|
|
|
|
|
+ f = fopen("/proc/partitions", "r");
|
|
|
|
|
+ if (f == NULL)
|
|
|
|
|
+ goto err;
|
|
|
|
|
+
|
|
|
|
|
+ lock_mutex(&container_dev_mutex);
|
|
|
|
|
+ container_devinfo = container_dev_read(initpid);
|
|
|
|
|
+ unlock_mutex(&container_dev_mutex);
|
|
|
|
|
+
|
|
|
|
|
+ while (getline(&line, &linelen, f) != -1) {
|
|
|
|
|
+ ssize_t l;
|
|
|
|
|
+ char lbuf[256];
|
|
|
|
|
+
|
|
|
|
|
+ if (lines < 2) {
|
|
|
|
|
+ strncpy(lbuf, line, sizeof(lbuf)-1);
|
|
|
|
|
+ lines++;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ memset(dev_name, 0, sizeof(dev_name));
|
|
|
|
|
+
|
|
|
|
|
+ i = sscanf(line, "%u %u %llu %71s", &major, &minor, &blocks, dev_name);
|
|
|
|
|
+ if (i != 4)
|
|
|
|
|
+ continue;
|
|
|
|
|
+ found = false;
|
|
|
|
|
+ for (ptr = container_devinfo; ptr != NULL; ptr = ptr->next) {
|
|
|
|
|
+ if (major == ptr->major && minor == ptr->minor) {
|
|
|
|
|
+ snprintf(lbuf, 256, "%4u %7u %10llu %s\n", major, minor, blocks, ptr->name);
|
|
|
|
|
+ found = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!found)
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ l = snprintf(cache, cache_size, "%s", lbuf);
|
|
|
|
|
+ if (l < 0) {
|
|
|
|
|
+ perror("Error writing to fuse buf");
|
|
|
|
|
+ rv = 0;
|
|
|
|
|
+ goto err;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (l >= cache_size) {
|
|
|
|
|
+ lxcfs_error("%s\n", "Internal error: truncated write to cache.");
|
|
|
|
|
+ rv = 0;
|
|
|
|
|
+ goto err;
|
|
|
|
|
+ }
|
|
|
|
|
+ cache += l;
|
|
|
|
|
+ cache_size -= l;
|
|
|
|
|
+ total_len += l;
|
|
|
|
|
+ }
|
|
|
|
|
+ d->cached = 1;
|
|
|
|
|
+ d->size = total_len;
|
|
|
|
|
+ if (total_len > size )
|
|
|
|
|
+ total_len = size;
|
|
|
|
|
+
|
|
|
|
|
+ memcpy(buf, d->buf, total_len);
|
|
|
|
|
+
|
|
|
|
|
+ rv = total_len;
|
|
|
|
|
+err:
|
|
|
|
|
+ free(cg);
|
2021-11-27 15:55:20 +08:00
|
|
|
+ cg = NULL;
|
2020-08-28 15:17:28 +08:00
|
|
|
+ if (f != NULL)
|
|
|
|
|
+ fclose(f);
|
|
|
|
|
+ free(line);
|
|
|
|
|
+ line = NULL;
|
|
|
|
|
+ free_devinfo_list(container_devinfo);
|
|
|
|
|
+ return rv;
|
|
|
|
|
+}
|
|
|
|
|
+
|
2021-11-27 15:55:20 +08:00
|
|
|
#ifdef RELOADTEST
|
2020-08-28 15:17:28 +08:00
|
|
|
static inline void iwashere(void)
|
|
|
|
|
{
|
2021-11-27 15:55:20 +08:00
|
|
|
@@ -1676,6 +1785,12 @@ __lxcfs_fuse_ops int proc_read(const char *path, char *buf, size_t size,
|
2020-08-28 15:17:28 +08:00
|
|
|
|
|
|
|
|
return read_file_fuse_with_offset(LXC_TYPE_PROC_LOADAVG_PATH,
|
|
|
|
|
buf, size, offset, f);
|
|
|
|
|
+ case LXC_TYPE_PROC_PARTITIONS:
|
|
|
|
|
+ if(liblxcfs_functional())
|
|
|
|
|
+ return proc_partitions_read(buf, size, offset, fi);
|
|
|
|
|
+
|
|
|
|
|
+ return read_file_fuse_with_offset(LXC_TYPE_PROC_PARTITIONS_PATH,
|
|
|
|
|
+ buf, size, offset, f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return -EINVAL;
|
2021-11-27 15:55:20 +08:00
|
|
|
--
|
|
|
|
|
2.27.0
|
|
|
|
|
|