[lxc-devel] [lxcfs/master] bindings: port blkio to new cgroup getters

brauner on Github lxc-bot at linuxcontainers.org
Mon Feb 24 10:34:43 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 434 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200224/cb71e8d4/attachment.bin>
-------------- next part --------------
From 9a9484ab68c67f2afe6bf84dc8fceb47efb61045 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 24 Feb 2020 11:32:47 +0100
Subject: [PATCH] bindings: port blkio to new cgroup getters

cgroup2's io controller does not support most of the blkio files.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 bindings.c       | 83 +++++++++++++++++++++++++++---------------------
 cgroups/cgfsng.c | 65 +++++++++++++++++++++++++++++++++++++
 cgroups/cgroup.h | 12 +++++++
 3 files changed, 124 insertions(+), 36 deletions(-)

diff --git a/bindings.c b/bindings.c
index f612d44..7ac3ff1 100644
--- a/bindings.c
+++ b/bindings.c
@@ -5139,14 +5139,15 @@ static int proc_uptime_read(char *buf, size_t size, off_t offset,
 }
 
 static int proc_diskstats_read(char *buf, size_t size, off_t offset,
-		struct fuse_file_info *fi)
+			       struct fuse_file_info *fi)
 {
-	char dev_name[72];
+	__do_free char *cg = NULL, *io_serviced_str = NULL,
+		       *io_merged_str = NULL, *io_service_bytes_str = NULL,
+		       *io_wait_time_str = NULL, *io_service_time_str = NULL,
+		       *line = NULL;
+	__do_fclose FILE *f = NULL;
 	struct fuse_context *fc = fuse_get_context();
 	struct file_info *d = (struct file_info *)fi->fh;
-	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;
 	unsigned long read = 0, write = 0;
 	unsigned long read_merged = 0, write_merged = 0;
 	unsigned long read_sectors = 0, write_sectors = 0;
@@ -5155,20 +5156,25 @@ static int proc_diskstats_read(char *buf, size_t size, off_t offset,
 	unsigned long rd_svctm = 0, wr_svctm = 0, rd_wait = 0, wr_wait = 0;
 	char *cache = d->buf;
 	size_t cache_size = d->buflen;
-	char *line = NULL;
-	size_t linelen = 0, total_len = 0, rv = 0;
+	size_t linelen = 0, total_len = 0;
 	unsigned int major = 0, minor = 0;
 	int i = 0;
-	FILE *f = NULL;
+	int ret;
+	char dev_name[72];
 
 	if (offset){
+		int left;
+
 		if (offset > d->size)
 			return -EINVAL;
+
 		if (!d->cached)
 			return 0;
-		int left = d->size - offset;
+
+		left = d->size - offset;
 		total_len = left > size ? size: left;
 		memcpy(buf, cache + offset, total_len);
+
 		return total_len;
 	}
 
@@ -5180,21 +5186,39 @@ static int proc_diskstats_read(char *buf, size_t size, off_t offset,
 		return read_file_fuse("/proc/diskstats", buf, size, d);
 	prune_init_slice(cg);
 
-	if (!cgroup_ops->get(cgroup_ops, "blkio", cg, "blkio.io_serviced_recursive", &io_serviced_str))
-		goto err;
-	if (!cgroup_ops->get(cgroup_ops, "blkio", cg, "blkio.io_merged_recursive", &io_merged_str))
-		goto err;
-	if (!cgroup_ops->get(cgroup_ops, "blkio", cg, "blkio.io_service_bytes_recursive", &io_service_bytes_str))
-		goto err;
-	if (!cgroup_ops->get(cgroup_ops, "blkio", cg, "blkio.io_wait_time_recursive", &io_wait_time_str))
-		goto err;
-	if (!cgroup_ops->get(cgroup_ops, "blkio", cg, "blkio.io_service_time_recursive", &io_service_time_str))
-		goto err;
+	ret = cgroup_ops->get_io_serviced(cgroup_ops, cg, &io_serviced_str);
+	if (ret < 0) {
+		if (ret == -EOPNOTSUPP)
+			return read_file_fuse("/proc/diskstats", buf, size, d);
+	}
 
+	ret = cgroup_ops->get_io_merged(cgroup_ops, cg, &io_merged_str);
+	if (ret < 0) {
+		if (ret == -EOPNOTSUPP)
+			return read_file_fuse("/proc/diskstats", buf, size, d);
+	}
+
+	ret = cgroup_ops->get_io_service_bytes(cgroup_ops, cg, &io_service_bytes_str);
+	if (ret < 0) {
+		if (ret == -EOPNOTSUPP)
+			return read_file_fuse("/proc/diskstats", buf, size, d);
+	}
+
+	ret = cgroup_ops->get_io_wait_time(cgroup_ops, cg, &io_wait_time_str);
+	if (ret < 0) {
+		if (ret == -EOPNOTSUPP)
+			return read_file_fuse("/proc/diskstats", buf, size, d);
+	}
+
+	ret = cgroup_ops->get_io_service_time(cgroup_ops, cg, &io_service_time_str);
+	if (ret < 0) {
+		if (ret == -EOPNOTSUPP)
+			return read_file_fuse("/proc/diskstats", buf, size, d);
+	}
 
 	f = fopen("/proc/diskstats", "r");
 	if (!f)
-		goto err;
+		return 0;
 
 	while (getline(&line, &linelen, f) != -1) {
 		ssize_t l;
@@ -5239,13 +5263,11 @@ static int proc_diskstats_read(char *buf, size_t size, off_t offset,
 		l = snprintf(cache, cache_size, "%s", lbuf);
 		if (l < 0) {
 			perror("Error writing to fuse buf");
-			rv = 0;
-			goto err;
+			return 0;
 		}
 		if (l >= cache_size) {
 			lxcfs_error("%s\n", "Internal error: truncated write to cache.");
-			rv = 0;
-			goto err;
+			return 0;
 		}
 		cache += l;
 		cache_size -= l;
@@ -5257,18 +5279,7 @@ static int proc_diskstats_read(char *buf, size_t size, off_t offset,
 	if (total_len > size ) total_len = size;
 	memcpy(buf, d->buf, total_len);
 
-	rv = total_len;
-err:
-	free(cg);
-	if (f)
-		fclose(f);
-	free(line);
-	free(io_serviced_str);
-	free(io_merged_str);
-	free(io_service_bytes_str);
-	free(io_wait_time_str);
-	free(io_service_time_str);
-	return rv;
+	return total_len;
 }
 
 static int proc_swaps_read(char *buf, size_t size, off_t offset,
diff --git a/cgroups/cgfsng.c b/cgroups/cgfsng.c
index 793176a..60ac136 100644
--- a/cgroups/cgfsng.c
+++ b/cgroups/cgfsng.c
@@ -737,6 +737,63 @@ static int cgfsng_get_cpuset_cpus(struct cgroup_ops *ops, const char *cgroup,
 	return -1;
 }
 
+static int cgfsng_get_io(struct cgroup_ops *ops, const char *cgroup,
+			 const char *file, char **value)
+{
+	__do_free char *path = NULL;
+	struct hierarchy *h;
+	int ret;
+
+	h = ops->get_hierarchy(ops, "blkio");
+	if (!h)
+		return -1;
+
+	if (!is_unified_hierarchy(h))
+		ret = CGROUP_SUPER_MAGIC;
+	else
+		ret = CGROUP2_SUPER_MAGIC;
+
+	path = must_make_path(dot_or_empty(cgroup), cgroup, file, NULL);
+	*value = readat_file(h->fd, path);
+	if (!*value) {
+		if (errno == ENOENT)
+			errno = EOPNOTSUPP;
+		return ret_errno(errno);
+	}
+
+	return ret;
+}
+
+static int cgfsng_get_io_service_bytes(struct cgroup_ops *ops,
+				       const char *cgroup, char **value)
+{
+	return cgfsng_get_io(ops, cgroup, "blkio.io_service_bytes_recursive", value);
+}
+
+static int cgfsng_get_io_service_time(struct cgroup_ops *ops,
+				      const char *cgroup, char **value)
+{
+	return cgfsng_get_io(ops, cgroup, "blkio.io_service_time_recursive", value);
+}
+
+static int cgfsng_get_io_serviced(struct cgroup_ops *ops, const char *cgroup,
+				  char **value)
+{
+	return cgfsng_get_io(ops, cgroup, "blkio.io_serviced_recursive", value);
+}
+
+static int cgfsng_get_io_merged(struct cgroup_ops *ops, const char *cgroup,
+				char **value)
+{
+	return cgfsng_get_io(ops, cgroup, "blkio.io_merged_recursive", value);
+}
+
+static int cgfsng_get_io_wait_time(struct cgroup_ops *ops, const char *cgroup,
+				   char **value)
+{
+	return cgfsng_get_io(ops, cgroup, "blkio.io_wait_time_recursive", value);
+}
+
 /* At startup, parse_hierarchies finds all the info we need about cgroup
  * mountpoints and current cgroups, and stores it in @d.
  */
@@ -943,5 +1000,13 @@ struct cgroup_ops *cgfsng_ops_init(void)
 	/* cpuset */
 	cgfsng_ops->get_cpuset_cpus = cgfsng_get_cpuset_cpus;
 
+	/* blkio */
+	cgfsng_ops->get_io_service_bytes	= cgfsng_get_io_service_bytes;
+	cgfsng_ops->get_io_service_time		= cgfsng_get_io_service_time;
+	cgfsng_ops->get_io_serviced		= cgfsng_get_io_serviced;
+	cgfsng_ops->get_io_merged		= cgfsng_get_io_merged;
+	cgfsng_ops->get_io_wait_time		= cgfsng_get_io_wait_time;
+
+
 	return move_ptr(cgfsng_ops);
 }
diff --git a/cgroups/cgroup.h b/cgroups/cgroup.h
index 29fe5ba..4221221 100644
--- a/cgroups/cgroup.h
+++ b/cgroups/cgroup.h
@@ -138,6 +138,18 @@ struct cgroup_ops {
 	/* cpuset */
 	int (*get_cpuset_cpus)(struct cgroup_ops *ops, const char *cgroup,
 			       char **value);
+
+	/* io */
+	int (*get_io_service_bytes)(struct cgroup_ops *ops, const char *cgroup,
+				    char **value);
+	int (*get_io_service_time)(struct cgroup_ops *ops, const char *cgroup,
+				   char **value);
+	int (*get_io_serviced)(struct cgroup_ops *ops, const char *cgroup,
+			       char **value);
+	int (*get_io_merged)(struct cgroup_ops *ops, const char *cgroup,
+			     char **value);
+	int (*get_io_wait_time)(struct cgroup_ops *ops, const char *cgroup,
+				char **value);
 };
 
 extern struct cgroup_ops *cgroup_init(void);


More information about the lxc-devel mailing list