125 lines
4.0 KiB
Diff
125 lines
4.0 KiB
Diff
From c818931d9e6f64bcac77c4c4d21a1ec34078bce3 Mon Sep 17 00:00:00 2001
|
||
From: licunlong <licunlong1@huawei.com>
|
||
Date: Mon, 19 Jun 2023 15:29:13 +0800
|
||
Subject: [PATCH] fix: make test_cgroup really work.
|
||
|
||
1. we used to attach our test tasks to system.slice, this is not safe.
|
||
Because system.slice is a common name, and there are many system
|
||
process attched in this directory, we can't just kill all processes
|
||
in this directory.
|
||
|
||
2. remove_dir used to return Ok(()) even if there is really a error.
|
||
|
||
3. use fs::remove_dir instead of fs::remove_all_dir because /sys/fs/cgroup
|
||
is a pseudo file system, we can't really remove files here.
|
||
---
|
||
libs/cgroup/src/cgroup.rs | 74 ++++++++++++++++++++++++++++++---------
|
||
1 file changed, 58 insertions(+), 16 deletions(-)
|
||
|
||
diff --git a/libs/cgroup/src/cgroup.rs b/libs/cgroup/src/cgroup.rs
|
||
index 83fe8ca..18513c2 100644
|
||
--- a/libs/cgroup/src/cgroup.rs
|
||
+++ b/libs/cgroup/src/cgroup.rs
|
||
@@ -188,20 +188,64 @@ pub fn cg_get_pids(cg_path: &PathBuf) -> Vec<Pid> {
|
||
}
|
||
|
||
fn remove_dir(cg_path: &PathBuf) -> Result<()> {
|
||
- let abs_cg_path: PathBuf = cg_abs_path(cg_path, &PathBuf::from(""))?;
|
||
-
|
||
- match fs::remove_dir_all(abs_cg_path.clone()) {
|
||
- Ok(_) => {}
|
||
+ if !cg_path.is_absolute() {
|
||
+ log::error!("We only support remove absolute directory.");
|
||
+ return Err(Error::NotSupported);
|
||
+ }
|
||
+ /* Note: We can't just call fs::remove_all_dir here. This is because /sys/fs/cgroup
|
||
+ * is a pseudo file system, we can only remove directory, but can't remove regular
|
||
+ * file. */
|
||
+ let read_dir = match cg_path.read_dir() {
|
||
Err(e) => {
|
||
- log::debug!(
|
||
- "remove dir failed:{:?}, err: {}",
|
||
- abs_cg_path,
|
||
- e.to_string()
|
||
- );
|
||
+ log::error!("Failed to read dir: {:?}", cg_path);
|
||
+ return Err(Error::Io { source: e });
|
||
+ }
|
||
+ Ok(v) => v,
|
||
+ };
|
||
+
|
||
+ for entry in read_dir {
|
||
+ let entry = match entry {
|
||
+ Err(e) => {
|
||
+ log::error!("Failed to get directory entry: {e}");
|
||
+ return Err(Error::Io { source: e });
|
||
+ }
|
||
+ Ok(v) => v,
|
||
+ };
|
||
+ let entry_file_type = match entry.file_type() {
|
||
+ Err(e) => {
|
||
+ log::error!(
|
||
+ "Failed to geth the file type of {:?}: {e}",
|
||
+ entry.file_name()
|
||
+ );
|
||
+ return Err(Error::Io { source: e });
|
||
+ }
|
||
+ Ok(v) => v,
|
||
+ };
|
||
+ if !entry_file_type.is_dir() {
|
||
+ continue;
|
||
}
|
||
+ remove_dir(&entry.path())?;
|
||
}
|
||
|
||
- Ok(())
|
||
+ /* Sometimes there are still tasks in cg_path, and rmdir will return EBUSY,
|
||
+ * we wait 10 us for 10 times. */
|
||
+ let mut try_times = 0;
|
||
+ loop {
|
||
+ let e = match fs::remove_dir(cg_path) {
|
||
+ Ok(()) => return Ok(()),
|
||
+ Err(e) => e,
|
||
+ };
|
||
+ let os_errno = match e.raw_os_error() {
|
||
+ None => return Err(Error::Io { source: e }),
|
||
+ Some(v) => v,
|
||
+ };
|
||
+ if os_errno == nix::libc::EBUSY && try_times < 10 {
|
||
+ std::thread::sleep(std::time::Duration::from_micros(10));
|
||
+ try_times += 1;
|
||
+ continue;
|
||
+ }
|
||
+ return Err(Error::Io { source: e });
|
||
+ }
|
||
}
|
||
|
||
fn cg_kill_process(
|
||
@@ -291,11 +335,9 @@ pub fn cg_kill_recursive(
|
||
cg_kill(cg_path, signal, flags, pids)?;
|
||
|
||
if flags.contains(CgFlags::REMOVE) {
|
||
- match remove_dir(cg_path) {
|
||
- Ok(_) => {}
|
||
- Err(e) => {
|
||
- return Err(e);
|
||
- }
|
||
+ let abs_cg_path = cg_abs_path(cg_path, &PathBuf::from(""))?;
|
||
+ if let Err(e) = remove_dir(&abs_cg_path) {
|
||
+ return Err(e);
|
||
}
|
||
}
|
||
|
||
@@ -645,7 +687,7 @@ mod tests {
|
||
return;
|
||
};
|
||
|
||
- let cg_path = PathBuf::from("system.slice");
|
||
+ let cg_path = PathBuf::from("sysmaster-test.slice");
|
||
let ret = super::cg_create(&cg_path);
|
||
assert!(ret.is_ok());
|
||
|
||
--
|
||
2.33.0
|
||
|