Skip to content

feat(vmm): add experimental systemd process manager - #1022

Open
kvinwang wants to merge 1 commit into
masterfrom
codex/experimental-systemd-vm-processes
Open

feat(vmm): add experimental systemd process manager#1022
kvinwang wants to merge 1 commit into
masterfrom
codex/experimental-systemd-vm-processes

Conversation

@kvinwang

@kvinwang kvinwang commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add an opt-in systemd VMM process-manager backend that bypasses the standalone supervisor
  • launch each VM as a transient systemd service with a dedicated cgroup
  • persist the original process metadata so VMM restart/reconciliation keeps working after transient units are collected
  • preserve the existing supervisor backend as the default
  • document configuration, runtime behavior, inspection commands, and current experimental limitations

Lifecycle

The transient service uses:

  • Type=exec
  • ExitType=cgroup
  • KillMode=mixed
  • KillSignal=SIGTERM
  • SendSIGKILL=yes
  • TimeoutStopSec=infinity

For swtpm VMs, the existing vm-launcher still handles swtpm readiness and graceful QEMU/swtpm shutdown. systemd owns the enclosing cgroup and keeps the unit in deactivating while processes remain during long kernel-side teardown.

Enable with:

[supervisor]
backend = "systemd"
systemd_unit_prefix = "dstack-vm"
systemd_state_dir = "/run/dstack-vmm/systemd-processes"

Experiment

On systemd 255, started a transient service with the same lifecycle properties and submitted an asynchronous stop. Immediately after stop, systemd reported:

ActiveState=deactivating
SubState=stop-sigterm
ControlGroup=/system.slice/dstack-vm-experiment-....service

After the child shutdown completed, it reported:

ActiveState=inactive
SubState=dead
Result=success

Tests

  • cargo test --manifest-path dstack/Cargo.toml -p dstack-vmm (106 passed)
  • cargo clippy --manifest-path dstack/Cargo.toml -p dstack-vmm --all-targets -- -D warnings
  • git diff --check

Copilot AI lite review requested due to automatic review settings August 6, 2026 13:28

Copilot AI left a comment

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.

Pull request overview

Adds an experimental, opt-in systemd-based process manager for dstack-vmm so VMs can be launched as transient systemd services (dedicated cgroups) while preserving existing supervisor-backed behavior as the default.

Changes:

  • Introduces a ProcessManager abstraction with a new SystemdProcessManager backend driven by systemd-run/systemctl, persisting process metadata for restart reconciliation.
  • Extends VMM configuration to select the backend and configure systemd unit naming/state storage.
  • Adds documentation describing the runtime model, inspection commands, and current limitations.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
dstack/vmm/vmm.toml Adds config knobs to select the process-manager backend and configure systemd unit/state settings.
dstack/vmm/src/process_manager.rs Implements the new systemd process-manager backend and shared abstraction over supervisor vs systemd.
dstack/vmm/src/main.rs Wires backend selection to instantiate either the existing supervisor client or the new systemd manager.
dstack/vmm/src/config.rs Adds ProcessManagerBackend and systemd-specific configuration defaults.
dstack/vmm/src/app.rs Switches the app’s process control dependency from SupervisorClient to the new ProcessManager.
docs/experimental-systemd-vm-processes.md Documents configuration and operational behavior for the experimental systemd backend.
Suppressed comments (1)

dstack/vmm/src/process_manager.rs:235

  • Error message capitalization is inconsistent with the repo convention (errors should start lowercase).
            bail!("Process is running");
        }
        let record = self.read_record(id)?;
        if record.started {
            bail!("Process is started");

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

.await?
.is_some_and(|info| info.state.status.is_running())
{
bail!("Process is already running");
Comment on lines +275 to +279
let output = command
.output()
.await
.context("failed to execute systemctl show")?;
let properties = String::from_utf8_lossy(&output.stdout);
Comment thread dstack/vmm/src/main.rs
)
.await
.context("Failed to connect to supervisor")?
.context("Failed to connect to supervisor")?;
Comment on lines +327 to +328
let manager =
SystemdProcessManager::new(PathBuf::from("/tmp/test"), "dstack-vm".into()).unwrap();
Comment thread dstack/vmm/src/config.rs
Comment on lines +483 to +485
fn default_systemd_state_dir() -> PathBuf {
"./run/systemd-processes".into()
}
Comment thread dstack/vmm/vmm.toml
Comment on lines +169 to +170
# Process metadata used to reconcile transient services after a VMM restart.
systemd_state_dir = "./run/systemd-processes"
Comment on lines +17 to +18
The section retains its historical name so existing configurations remain
compatible. The default backend is `supervisor`.
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.

2 participants