Skip to content

Commit

Permalink
fix(libcgroup): set blkio weight
Browse files Browse the repository at this point in the history
Signed-off-by: Jian Zeng <anonymousknight96@gmail.com>
  • Loading branch information
knight42 committed Dec 16, 2021
1 parent 0be33bf commit b2eafb8
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 15 deletions.
34 changes: 33 additions & 1 deletion crates/libcgroups/src/v1/blkio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,12 @@ const BLKIO_THROTTLE_IO_SERVICE_BYTES: &str = "blkio.throttle.io_service_bytes";
// Proportional weight division policy
// ---------------------------------------
// Specifies the relative proportion of block I/O access available to the cgroup
// Format: weight (weight can range from 100 to 1000)
// Format: weight (weight can range from 10 to 1000)
const BLKIO_WEIGHT: &str = "blkio.weight";
// Similar to BLKIO_WEIGHT, but is only available in kernels starting with version 5.0
// with blk-mq and when using BFQ I/O scheduler
// Format: weight (weight can range from 1 to 10000)
const BLKIO_BFQ_WEIGHT: &str = "blkio.bfq.weight";
// Specifies the relative proportion of block I/O access for specific devices available
// to the cgroup. This overrides the the blkio.weight value for the specified device
// Format: Major:Minor weight (weight can range from 100 to 1000)
Expand Down Expand Up @@ -103,6 +107,19 @@ impl StatsProvider for Blkio {

impl Blkio {
fn apply(root_path: &Path, blkio: &LinuxBlockIo) -> Result<()> {
if let Some(blkio_weight) = blkio.weight() {
// be aligned with what runc does
// See also: https://github.com/opencontainers/runc/blob/81044ad7c902f3fc153cb8ffadaf4da62855193f/libcontainer/cgroups/fs/blkio.go#L28-L33
if blkio_weight != 0 {
let cgroup_file = root_path.join(BLKIO_WEIGHT);
if cgroup_file.exists() {
common::write_cgroup_file(&cgroup_file, blkio_weight)?;
} else {
common::write_cgroup_file(&root_path.join(BLKIO_BFQ_WEIGHT), blkio_weight)?;
}
}
}

if let Some(throttle_read_bps_device) = blkio.throttle_read_bps_device().as_ref() {
for trbd in throttle_read_bps_device {
common::write_cgroup_file_str(
Expand Down Expand Up @@ -226,6 +243,21 @@ mod tests {
use anyhow::Result;
use oci_spec::runtime::{LinuxBlockIoBuilder, LinuxThrottleDeviceBuilder};

#[test]
fn test_set_blkio_weight() {
for cgroup_file in &[BLKIO_WEIGHT, BLKIO_BFQ_WEIGHT] {
let (tmp, weight_file) = setup("test_set_blkio_weight", cgroup_file);
let blkio = LinuxBlockIoBuilder::default()
.weight(200_u16)
.build()
.unwrap();

Blkio::apply(&tmp, &blkio).expect("apply blkio");
let content = fs::read_to_string(weight_file).expect("read blkio weight");
assert_eq!("200", content);
}
}

#[test]
fn test_set_blkio_read_bps() {
let (tmp, throttle) = setup("test_set_blkio_read_bps", BLKIO_THROTTLE_READ_BPS);
Expand Down
62 changes: 48 additions & 14 deletions crates/libcgroups/src/v2/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,17 @@ impl StatsProvider for Io {
}

impl Io {
// Since the OCI spec is designed for cgroup v1, in some cases
// there is need to convert from the cgroup v1 configuration to cgroup v2
// the formula for BlkIOWeight to IOWeight is y = (1 + (x - 10) * 9999 / 990)
// convert linearly from [10-1000] to [1-10000]
fn convert_cfq_io_weight_to_bfq(v: u16) -> u16 {
if v == 0 {
return 0;
}
1 + (v - 10) * 9999 / 990
}

fn io_max_path(path: &Path) -> PathBuf {
path.join("io.max")
}
Expand All @@ -99,11 +110,18 @@ impl Io {
}
}
if let Some(io_weight) = blkio.weight() {
// be aligned with what runc does
// See also: https://github.com/opencontainers/runc/blob/81044ad7c902f3fc153cb8ffadaf4da62855193f/libcontainer/cgroups/fs2/io.go#L57-L69
if io_weight > 0 {
common::write_cgroup_file(
root_path.join(CGROUP_IO_WEIGHT),
format!("{}", io_weight),
)?;
let cgroup_file = root_path.join(CGROUP_BFQ_IO_WEIGHT);
if cgroup_file.exists() {
common::write_cgroup_file(cgroup_file, io_weight)?;
} else {
common::write_cgroup_file(
root_path.join(CGROUP_IO_WEIGHT),
Self::convert_cfq_io_weight_to_bfq(io_weight),
)?;
}
}
}

Expand Down Expand Up @@ -259,17 +277,33 @@ mod test {

#[test]
fn test_set_ioweight() {
let (tmp, throttle) = setup("test_set_io_weight", CGROUP_IO_WEIGHT);
let blkio = LinuxBlockIoBuilder::default()
.weight(100u16)
.build()
.unwrap();

Io::apply(&tmp, &blkio).expect("apply blkio");
let content =
fs::read_to_string(throttle).unwrap_or_else(|_| panic!("read bfq_io_weight content"));
struct TestCase {
cgroup_file: &'static str,
weight: u16,
expected_weight: String,
}
for case in &[
TestCase {
cgroup_file: CGROUP_BFQ_IO_WEIGHT,
weight: 100,
expected_weight: String::from("100"),
},
TestCase {
cgroup_file: CGROUP_IO_WEIGHT,
weight: 10,
expected_weight: String::from("1"),
},
] {
let (tmp, weight_file) = setup("test_set_io_weight", case.cgroup_file);
let blkio = LinuxBlockIoBuilder::default()
.weight(case.weight)
.build()
.unwrap();

assert_eq!("100", content);
Io::apply(&tmp, &blkio).expect("apply blkio");
let content = fs::read_to_string(weight_file).expect("read blkio weight");
assert_eq!(case.expected_weight, content);
}
}

#[test]
Expand Down

0 comments on commit b2eafb8

Please sign in to comment.