commit:     1b90e65cba6bee606f946b413b6df83fd1256ac9
Author:     Daniel Hodges <hodges.daniel.scott <AT> gmail <DOT> com>
AuthorDate: Thu Nov 11 03:52:46 2021 +0000
Commit:     Florian Schmaus <flow <AT> gentoo <DOT> org>
CommitDate: Thu Nov 11 07:20:11 2021 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=1b90e65c

sys-process/below: add patches to fix cgroup parsing

Signed-off-by: Daniel Hodges <hodges.daniel.scott <AT> gmail.com>
Closes: https://github.com/gentoo/gentoo/pull/22894
Signed-off-by: Florian Schmaus <flow <AT> gentoo.org>

 .../{below-0.3.0.ebuild => below-0.3.0-r1.ebuild}  |  5 +-
 .../files/below-0.3.0-cgroup-parse-fixes-01.patch  | 86 ++++++++++++++++++++
 .../files/below-0.3.0-cgroup-parse-fixes-02.patch  | 92 ++++++++++++++++++++++
 3 files changed, 182 insertions(+), 1 deletion(-)

diff --git a/sys-process/below/below-0.3.0.ebuild 
b/sys-process/below/below-0.3.0-r1.ebuild
similarity index 97%
rename from sys-process/below/below-0.3.0.ebuild
rename to sys-process/below/below-0.3.0-r1.ebuild
index 30bcee725ec..6c632cb8499 100644
--- a/sys-process/below/below-0.3.0.ebuild
+++ b/sys-process/below/below-0.3.0-r1.ebuild
@@ -207,7 +207,10 @@ DEPEND="
 "
 
 QA_FLAGS_IGNORED="usr/bin/below"
-
+PATCHES=(
+       "${FILESDIR}"/${P}-cgroup-parse-fixes-01.patch
+       "${FILESDIR}"/${P}-cgroup-parse-fixes-02.patch
+)
 src_install() {
        cargo_src_install --path below
 

diff --git a/sys-process/below/files/below-0.3.0-cgroup-parse-fixes-01.patch 
b/sys-process/below/files/below-0.3.0-cgroup-parse-fixes-01.patch
new file mode 100644
index 00000000000..0a30a2df715
--- /dev/null
+++ b/sys-process/below/files/below-0.3.0-cgroup-parse-fixes-01.patch
@@ -0,0 +1,86 @@
+From c3af8c1f8b0da050a7c4c8fb5083ff44885fa959 Mon Sep 17 00:00:00 2001
+From: Brian Chen <[email protected]>
+Date: Mon, 23 Aug 2021 11:45:01 -0700
+Subject: [PATCH] Fix procfs when reading cgroup membership (#8106)
+
+Summary:
+When reading cgroup membership, we currently assume that the cgroup v2
+line will be first in /proc/[pid]/cgroup. This is not necessarily the
+case. Instead let's take the first line that starts with "0::".
+
+Tested on ubuntu where
+
+```
+$ cat /proc/1/cgroup
+12:blkio:/init.scope
+11:pids:/init.scope
+8:memory:/init.scope
+7:freezer:/
+4:devices:/init.scope
+2:cpu,cpuacct:/init.scope
+1:name=systemd:/init.scope
+0::/init.scope
+```
+
+This should fix https://github.com/facebookincubator/below/issues/8105.
+
+Pull Request resolved: https://github.com/facebookincubator/below/pull/8106
+
+Test Plan: Existing procfs tests should pass
+
+Reviewed By: lnyng
+
+Differential Revision: D30476031
+
+Pulled By: brianc118
+
+fbshipit-source-id: e0352fb039bebf44a0d5584120ea0a0a82c0cd01
+---
+ below/procfs/src/lib.rs | 33 ++++++++++++++++++---------------
+ 1 file changed, 18 insertions(+), 15 deletions(-)
+
+--- a/below/procfs/src/lib.rs
++++ b/below/procfs/src/lib.rs
+@@ -556,24 +556,27 @@ impl ProcReader {
+         let path = path.as_ref().join("cgroup");
+         let file = File::open(&path).map_err(|e| Error::IoError(path.clone(), 
e))?;
+         let buf_reader = BufReader::new(file);
+-        let pid_line = buf_reader.lines().next().map_or_else(
+-            || Err(Error::InvalidFileFormat(path.clone())),
+-            |line| line.map_err(|e| Error::IoError(path.clone(), e)),
+-        )?;
+-
+-        // cgroup V2
+-        if pid_line.len() > 3 && pid_line.starts_with("0::") {
+-            return Ok(pid_line[3..].to_string());
+-        }
+ 
+-        // legacy cgroup will have multiple lines with the first line of 
[0-9]+:pids:PATH
+-        if let Some(pid_idx) = pid_line.find(":pids:") {
+-            if pid_idx + 6 < pid_line.len() {
+-                return Ok(pid_line[pid_idx + 6..].to_string());
++        let mut cgroup_path = None;
++        for line in buf_reader.lines() {
++            let line = line.map_err(|e| Error::IoError(path.clone(), e))?;
++            // Lines contain three colon separated fields:
++            //   hierarchy-ID:controller-list:cgroup-path
++            // A line starting with "0::" would be an entry for cgroup v2.
++            // Otherwise, the line containing "pids" controller is what we 
want
++            // for cgroup v1.
++            let parts: Vec<_> = line.split(':').collect();
++            if parts.len() == 3 {
++                if parts[0] == "0" && parts[1] == "" {
++                    cgroup_path = Some(parts[2].to_owned());
++                    // cgroup v2 takes precedence
++                    break;
++                } else if parts[1].split(',').any(|c| c == "pids") {
++                    cgroup_path = Some(parts[2].to_owned());
++                }
+             }
+         }
+-
+-        Err(Error::InvalidFileFormat(path))
++        cgroup_path.ok_or_else(|| Error::InvalidFileFormat(path))
+     }
+ 
+     pub fn read_pid_cgroup(&self, pid: u32) -> Result<String> {

diff --git a/sys-process/below/files/below-0.3.0-cgroup-parse-fixes-02.patch 
b/sys-process/below/files/below-0.3.0-cgroup-parse-fixes-02.patch
new file mode 100644
index 00000000000..f8c15b6d49e
--- /dev/null
+++ b/sys-process/below/files/below-0.3.0-cgroup-parse-fixes-02.patch
@@ -0,0 +1,92 @@
+From 80fb95e06ddc5f311e0c9dc20b19d00058ca39af Mon Sep 17 00:00:00 2001
+From: Brian Chen <[email protected]>
+Date: Tue, 31 Aug 2021 14:59:57 -0700
+Subject: [PATCH] Fix procfs reading cgroups with colon in name
+
+Summary:
+When reading cgroup membership, we split by ':' and expect there to
+be 3 parts. This is not always the case since cgroup name can
+contain ':'.
+
+Reviewed By: lnyng
+
+Differential Revision: D30681159
+
+fbshipit-source-id: 895e1b26965ae33454a19c2ec1bc5478a5f95635
+---
+ below/procfs/src/lib.rs  |  2 +-
+ below/procfs/src/test.rs | 34 ++++++++++++++++++++++++++++++----
+ 2 files changed, 31 insertions(+), 5 deletions(-)
+
+--- a/below/procfs/src/lib.rs
++++ b/below/procfs/src/lib.rs
+@@ -565,7 +565,7 @@ impl ProcReader {
+             // A line starting with "0::" would be an entry for cgroup v2.
+             // Otherwise, the line containing "pids" controller is what we 
want
+             // for cgroup v1.
+-            let parts: Vec<_> = line.split(':').collect();
++            let parts: Vec<_> = line.splitn(3, ':').collect();
+             if parts.len() == 3 {
+                 if parts[0] == "0" && parts[1] == "" {
+                     cgroup_path = Some(parts[2].to_owned());
+--- a/below/procfs/src/test.rs
++++ b/below/procfs/src/test.rs
+@@ -804,7 +804,7 @@ cancelled_write_bytes: 5431947264
+
+ #[test]
+ fn test_pid_cgroupv2() {
+-    let cgroup = b"0::/user.slice/user-119756.slice/session-3.scope
++    let cgroup = b"0::/user.slice/user:with:colon.slice/session-3.scope
+ ";
+
+     let procfs = TestProcfs::new();
+@@ -814,12 +814,12 @@ fn test_pid_cgroupv2() {
+         .read_pid_cgroup(1024)
+         .expect("Failed to read pid cgroup file");
+
+-    assert_eq!(cgroup, "/user.slice/user-119756.slice/session-3.scope");
++    assert_eq!(cgroup, "/user.slice/user:with:colon.slice/session-3.scope");
+ }
+
+ #[test]
+ fn test_pid_cgroupv1() {
+-    let cgroup = b"11:pids:/init.scope
++    let cgroup = b"11:pids:/cgroup-path:colon
+ 10:perf_event:/
+ 9:hugetlb:/
+ 8:cpu,cpuacct:/init.scope
+@@ -838,7 +838,33 @@ fn test_pid_cgroupv1() {
+         .read_pid_cgroup(1024)
+         .expect("Failed to read pid cgroup file");
+
+-    assert_eq!(cgroup, "/init.scope");
++    assert_eq!(cgroup, "/cgroup-path:colon");
++}
++
++#[test]
++fn test_pid_cgroupv1and2() {
++    let cgroup = b"11:pids:/cgroup-path:colon
++10:perf_event:/
++9:hugetlb:/
++8:cpu,cpuacct:/init.scope
++7:blkio:/init.scope
++6:freezer:/
++5:cpuset:/
++4:memory:/init.scope
++3:devices:/init.scope
++2:net_cls,net_prio:/
++1:name=systemd:/init.scope
++0::/user.slice/user:with:colon.slice/session-3.scope";
++
++    let procfs = TestProcfs::new();
++    procfs.create_pid_file_with_content(1024, "cgroup", cgroup);
++    let reader = procfs.get_reader();
++    let cgroup = reader
++        .read_pid_cgroup(1024)
++        .expect("Failed to read pid cgroup file");
++
++    // When we see both cgroup v1 and v2, v2 takes precedence
++    assert_eq!(cgroup, "/user.slice/user:with:colon.slice/session-3.scope");
+ }
+
+ #[test]

Reply via email to