Skip to content

feat(api): Add blkio cgroup tuning via --blkio flag#1595

Open
chrisgeo wants to merge 3 commits into
apple:mainfrom
full-chaos:feat/chaos-1380-blkio-flags
Open

feat(api): Add blkio cgroup tuning via --blkio flag#1595
chrisgeo wants to merge 3 commits into
apple:mainfrom
full-chaos:feat/chaos-1380-blkio-flags

Conversation

@chrisgeo
Copy link
Copy Markdown
Contributor

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Motivation and Context

Closes #1512.

Adds block I/O cgroup tuning to container run / container create so
compose translators (e.g. container-compose) can pass through Docker
Compose service.blkio_config instead of warn-skipping it.

The CLI shape follows the grouped, repeatable key=value form proposed in
#1512 (comment):

container run --blkio weight=500 ...
container run --blkio device=/dev/sda,weight=700,leaf-weight=300 ...
container run --blkio device=/dev/sda,read-bps=1048576,write-bps=1048576 ...
container run --blkio device=/dev/sda,read-iops=1000,write-iops=1000 ...

The device= value accepts either an absolute host path (resolved via
stat(2) for major/minor) or a literal <major>:<minor>. Keys allowed
on a per-device spec: weight, leaf-weight, read-bps, write-bps,
read-iops, write-iops. Keys allowed on a global spec (no device=):
weight, leaf-weight. Parser rejects unknown keys, conflicting
global weights, and global-only keys mixed onto device-less specs.

Runtime plumbing

Block I/O propagates as ContainerConfiguration.Resources.blockIO
(serialised as ContainerizationOCI.LinuxBlockIO) and is converted to
Containerization.LinuxBlockIO at the runtime boundary in
RuntimeService.configureContainer.

Dependency

Depends on apple/containerization#739, which introduces
Containerization.LinuxBlockIO (the Sendable wrapper around the OCI
type) and wires it into LinuxContainer.Configuration. While that PR is
unmerged this branch pins containerization to the PR branch
(full-chaos/containerization@feat/chaos-1380-blkio-runtime,
revision 3d009df). Before merge, the pin must be moved back to
apple/containerization at whatever revision lands #739.

Testing

  • Tested locally
  • Added/updated tests
  • Added/updated docs

swift build clean, swift test --filter ParserTest passes
(105 tests, 5 new):

  • testResourcesBlockIOFlags — combined global + per-device + throttle
  • testResourcesBlockIOAcceptsMajorMinorLiteraldevice=8:0 literal
  • testResourcesRejectsInvalidBlockIOWeight — weight outside 10..1000
  • testResourcesRejectsUnknownBlockIOKey — typo detection
  • testResourcesRejectsGlobalKeyOnDeviceSpecread-bps without device=

container run --help confirmed renders the new --blkio flag.

Comment thread Package.swift
],
dependencies: [
.package(url: "https://github.com/apple/containerization.git", exact: Version(stringLiteral: scVersion)),
.package(url: "https://github.com/full-chaos/containerization.git", branch: scVersion),
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will remove before merge.

Comment thread .gitignore Outdated
_serve/
.vscode/**
.worktrees/**
.worktress/**
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will remove before merge.

Comment thread Package.resolved Outdated
Comment on lines 2 to 20
@@ -13,10 +13,10 @@
{
"identity" : "containerization",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/containerization.git",
"location" : "https://github.com/full-chaos/containerization.git",
"state" : {
"revision" : "db5b5b98405d53543f69105087130ffd623a5b9a",
"version" : "0.32.2"
"branch" : "feat/chaos-1380-blkio-runtime",
"revision" : "3d009dfc2724fc924dd18ca2014b5e839d554163"
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will revert before merge.

chrisgeo added 2 commits May 27, 2026 11:38
Two changes addressing review feedback from
apple/containerization#739 and
apple#1512 (comment):

1. Adopt the new `Containerization.LinuxBlockIO` wrapper added in
   containerization PR apple#739 (pin advanced to 3d009df). The wire format in
   `ContainerConfiguration.Resources.blockIO` stays as the Codable
   `ContainerizationOCI.LinuxBlockIO`; `RuntimeService.configureContainer`
   converts to the wrapper at the boundary via the new
   `toContainerizationBlockIO` helper.

2. Replace the six separate `--blkio-*` / `--device-*` flags with a
   single repeatable `--blkio` flag using key=value[,key=value] syntax,
   per apple#1512 (comment):

       --blkio weight=500
       --blkio device=/dev/sda,weight=700,leaf-weight=300
       --blkio device=/dev/sda,read-bps=1048576,write-bps=1048576
       --blkio device=/dev/sda,read-iops=1000,write-iops=1000

   Device values accept either an absolute host path (resolved via stat(2))
   or a literal `<major>:<minor>`. Parser rejects unknown keys, conflicting
   global weights, and global-only keys appearing on device-less specs.

Tests cover the combined spec, major:minor literal, invalid-weight,
unknown-key, and global-only-on-device-spec error paths.
@chrisgeo chrisgeo force-pushed the feat/chaos-1380-blkio-flags branch from 2921cd9 to 8265a51 Compare May 27, 2026 18:41
/// Memory in bytes allocated.
public var memoryInBytes: UInt64 = 1024.mib()
/// Block I/O resource limits.
public var blockIO: LinuxBlockIO?
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This definitely moves it in the desired direction. Since this is a Linux-specific option, it'd be better that this become a field in LinuxRuntimeData and then if LinuxBlockIO needs to be present, you populate it there, encode the LinuxRuntimeData as runtimeData for the RuntimeConfiguration type, and then the RuntimeService can decode the runtime config, check for the presence of runtimeData, decode out LinuxRuntimeData, and do as it pleases with the result.

We don't want to have things that are overtly OS-specific in the ContainerConfiguration.

public var memory: String?

@Option(
name: .customLong("blkio"),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't really have a good mechanism for providing OS-specific options on the CLI (it's going to require some non-trivial rework on our command line processing), so I think the best thing here is just to have this be options like we do for non-generic volume options (I'm aiming to do this networks as well).

I wouldn't document the option list here as it'll turn the help output into a text wall. Better to update the command reference under docs where we can have a huge list, table, whatever.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it would be options this should go under Flags.Management instead of Flags.Resource.

…imeData

Addresses jglogan review feedback on PR apple#1595:

1. Move `blockIO` field out of the cross-platform
   `ContainerConfiguration.Resources` and into the Linux-specific
   `LinuxRuntimeData`. The CLI now encodes `LinuxRuntimeData(blockIO: …)`
   into the opaque `RuntimeConfiguration.runtimeData` field, and the
   Linux runtime decodes it inside `configureContainer` before applying
   the OCI `LinuxBlockIO` to `czConfig.blockIO`. Keeps OS-specific
   options out of the generic container config type.

2. Move the `--blkio` flag from `Flags.Resource` to `Flags.Management`
   and simplify its help to a single line pointing at the command
   reference, in the spirit of the existing generic options pattern.
   The structured key=value parsing/validation in `Parser.blockIO` is
   unchanged.

3. `Parser.resources` no longer takes `blkio`; `Parser.blockIO` stays
   public and is now invoked by `ContainerRun` / `ContainerCreate`
   directly. Tests rewritten to exercise `Parser.blockIO` directly.

`swift build` clean; `swift test --filter ParserTest` 105 tests pass,
`RuntimeConfiguration` tests pass, `container run --help` shows
`--blkio` under MANAGEMENT OPTIONS.

Deferred (per PR body): Package.swift / Package.resolved still pin
containerization to apple/containerization#739's branch because that
upstream PR is still open. Those will revert to apple/containerization
at merge time, once apple#739 lands.
@chrisgeo
Copy link
Copy Markdown
Contributor Author

Pushed 5d11a29 addressing review feedback.

1. blockIO no longer lives on ContainerConfiguration

Per the suggestion on ContainerConfiguration.swift, the field is now on LinuxRuntimeData and is carried opaquely through RuntimeConfiguration.runtimeData:

  • CLI (ContainerRun / ContainerCreate) calls Parser.blockIO(specs:), wraps the result in LinuxRuntimeData(blockIO:), JSON-encodes it, and passes it as runtimeData to ContainerClient.create.
  • RuntimeService.bootstrap reads RuntimeConfiguration.runtimeData from disk and threads it into configureContainer, which decodes LinuxRuntimeData and applies czConfig.blockIO.
  • ContainerConfiguration.Resources.blockIO is removed; Parser.resources no longer takes blkio.

This keeps OS-specific options out of the generic container config type, as you described.

2. --blkio reshaped as options under Flags.Management

  • The flag moved from Flags.Resource to Flags.Management (it shows up under MANAGEMENT OPTIONS in container run --help now).
  • Help text collapsed to a single line: Block I/O cgroup tuning options (Linux only; see command reference for the supported keys). The detailed key/value schema will live in the command reference doc rather than the help wall.
  • The structured key=value parsing in Parser.blockIO is unchanged, so existing behavior is preserved.

3. Tests

swift test --filter ParserTest — 105 tests pass, including the 5 blkio cases (now rewired to call Parser.blockIO directly since the field is gone from Resources). RuntimeConfigurationTests also still pass.

Deferred cleanup

The three self-review notes on Package.swift, Package.resolved, and .gitignore are intentionally left for now:

  • Package.swift / Package.resolved still pin to the containerization#739 branch because that upstream PR is still open. They will revert to apple/containerization at whatever revision lands [container-run-create]: add support for --network none #739, as the PR description notes.
  • .gitignore shows no diff against main on the current branch, so there is nothing to revert there — flagging in case I'm missing something on your end.

@chrisgeo chrisgeo marked this pull request as ready for review May 27, 2026 23:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Request] Add blkio/cgroup BFQ tuning flags to container run/create

2 participants