Skip to content

Commit 717cc3a

Browse files
committed
fix(simulator): gate startup on host config
Signed-off-by: Kevin Wang <wy721@qq.com>
1 parent f6c6465 commit 717cc3a

5 files changed

Lines changed: 76 additions & 20 deletions

File tree

docs/development-without-tee.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ collateral_base_url = "http://10.0.2.2:18088"
9999
exe = "/home/USER/.local/bin/supervisor"
100100
```
101101

102+
The VMM writes these settings to the guest's development-only
103+
`.tee-simulator.json`. The guest starts the simulator only when that file is
104+
present in the host share.
105+
102106
Start the VMM from a stable working directory because its default API socket is
103107
relative to that directory:
104108

dstack/dstack-util/src/host_shared.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use anyhow::{Context, Result};
88
use clap::{Parser, Subcommand};
99
use dstack_types::shared_filenames::HOST_SHARED_DISK_LABEL;
1010
use fs_err as fs;
11+
use tracing::{info, warn};
1112

1213
#[derive(Parser)]
1314
pub struct HostSharedArgs {
@@ -64,15 +65,24 @@ pub fn mount_host_shared(mount_point: &Path) -> Result<()> {
6465
.with_context(|| format!("failed to create {}", mount_point.display()))?;
6566

6667
if let Some(device) = find_disk_by_label(HOST_SHARED_DISK_LABEL) {
68+
info!(device = %device.display(), "found host-shared disk");
6769
let status = Command::new("mount")
6870
.args(["-o", "ro"])
6971
.arg(&device)
7072
.arg(mount_point)
7173
.status()
7274
.with_context(|| format!("failed to run mount for {}", device.display()))?;
7375
if status.success() {
76+
info!(mount_point = %mount_point.display(), "mounted host-shared disk");
7477
return Ok(());
7578
}
79+
warn!(
80+
device = %device.display(),
81+
status = %status,
82+
"failed to mount host-shared disk, falling back to 9p"
83+
);
84+
} else {
85+
info!("host-shared disk not found, trying 9p");
7686
}
7787

7888
let status = Command::new("mount")
@@ -91,6 +101,7 @@ pub fn mount_host_shared(mount_point: &Path) -> Result<()> {
91101
"failed to mount host-shared at {}",
92102
mount_point.display()
93103
);
104+
info!(mount_point = %mount_point.display(), "mounted host-shared via 9p");
94105
Ok(())
95106
}
96107

dstack/tee-simulator/src/main.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ struct Args {
2626
#[arg(long)]
2727
platform: Option<TeeVariant>,
2828

29-
/// Development-only simulator config.
29+
/// Development-only simulator config. The systemd unit overrides this
30+
/// standalone default with its early-mounted runtime path.
3031
#[arg(long, default_value = "/dstack/.host-shared/.tee-simulator.json")]
3132
config: PathBuf,
3233

@@ -220,9 +221,7 @@ mod tests {
220221
fs_err::write(
221222
&path,
222223
serde_json::json!({
223-
"kms_urls": [], "gateway_urls": [], "pccs_url": null,
224-
"docker_registry": null, "host_api_url": null, "vm_config": "{}",
225-
"platform": name
224+
"platform": name
226225
})
227226
.to_string(),
228227
)

dstack/vmm/src/app.rs

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,16 +1108,7 @@ impl App {
11081108
)?;
11091109
fs::write(shared_dir.join(SYS_CONFIG), &sys_config_str)
11101110
.context("Failed to write vm config")?;
1111-
if let Some(mut simulator_config) = cfg.cvm.tee_simulator.clone() {
1112-
let sys_config: dstack_types::SysConfig = serde_json::from_str(&sys_config_str)?;
1113-
simulator_config.mr_config = sys_config.mr_config;
1114-
simulator_config.vm_config = Some(sys_config.vm_config);
1115-
fs::write(
1116-
shared_dir.join(TEE_SIMULATOR_CONFIG),
1117-
serde_json::to_vec(&simulator_config)?,
1118-
)
1119-
.context("Failed to write TEE simulator config")?;
1120-
}
1111+
sync_tee_simulator_config(&shared_dir, cfg.cvm.tee_simulator.as_ref(), &sys_config_str)?;
11211112
Ok(())
11221113
}
11231114

@@ -1253,6 +1244,27 @@ fn rotate_serial_log(work_dir: &VmWorkDir, max_bytes: u64) {
12531244
}
12541245
}
12551246

1247+
fn sync_tee_simulator_config(
1248+
shared_dir: &Path,
1249+
simulator_config: Option<&dstack_types::TeeSimulatorConfig>,
1250+
sys_config: &str,
1251+
) -> Result<()> {
1252+
let path = shared_dir.join(TEE_SIMULATOR_CONFIG);
1253+
let Some(simulator_config) = simulator_config else {
1254+
if path.exists() {
1255+
fs::remove_file(&path).context("failed to remove stale TEE simulator config")?;
1256+
}
1257+
return Ok(());
1258+
};
1259+
1260+
let sys_config: dstack_types::SysConfig = serde_json::from_str(sys_config)?;
1261+
let mut simulator_config = simulator_config.clone();
1262+
simulator_config.mr_config = sys_config.mr_config;
1263+
simulator_config.vm_config = Some(sys_config.vm_config);
1264+
fs::write(path, serde_json::to_vec(&simulator_config)?)
1265+
.context("failed to write TEE simulator config")
1266+
}
1267+
12561268
pub(crate) fn make_sys_config(
12571269
cfg: &Config,
12581270
manifest: &Manifest,
@@ -1474,6 +1486,40 @@ mod tests {
14741486
hex::encode(vec![byte; len])
14751487
}
14761488

1489+
#[test]
1490+
fn simulator_config_is_written_separately_with_measurement_inputs() -> Result<()> {
1491+
let dir = tempfile::tempdir()?;
1492+
let config = dstack_types::TeeSimulatorConfig {
1493+
platform: dstack_types::TeeVariant::DstackAmdSevSnp,
1494+
mock_attestation_seed: Some("11".repeat(32)),
1495+
collateral_base_url: Some("http://127.0.0.1:18088".into()),
1496+
..Default::default()
1497+
};
1498+
let mr_config = r#"{"version":3}"#;
1499+
let vm_config = r#"{"image":"dev"}"#;
1500+
let sys_config = serde_json::json!({
1501+
"kms_urls": [],
1502+
"gateway_urls": [],
1503+
"vm_config": vm_config,
1504+
"mr_config": mr_config,
1505+
})
1506+
.to_string();
1507+
1508+
sync_tee_simulator_config(dir.path(), Some(&config), &sys_config)?;
1509+
1510+
let written: dstack_types::TeeSimulatorConfig =
1511+
serde_json::from_slice(&fs::read(dir.path().join(TEE_SIMULATOR_CONFIG))?)?;
1512+
assert_eq!(written.platform, config.platform);
1513+
assert_eq!(written.mock_attestation_seed, config.mock_attestation_seed);
1514+
assert_eq!(written.collateral_base_url, config.collateral_base_url);
1515+
assert_eq!(written.mr_config.as_deref(), Some(mr_config));
1516+
assert_eq!(written.vm_config.as_deref(), Some(vm_config));
1517+
1518+
sync_tee_simulator_config(dir.path(), None, &sys_config)?;
1519+
assert!(!dir.path().join(TEE_SIMULATOR_CONFIG).exists());
1520+
Ok(())
1521+
}
1522+
14771523
#[test]
14781524
fn gpu_config_has_gpus_only_when_resolved_gpu_list_is_non_empty() {
14791525
assert!(!GpuConfig::default().has_gpus());

os/yocto/layers/meta-dstack/recipes-core/dstack-tee-simulator/files/dstack-tee-simulator.service

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
[Unit]
2-
Description=dstack development TEE ABI simulator (TDX backend)
2+
Description=dstack development TEE ABI simulator
33
Documentation=https://github.com/Dstack-TEE/dstack/blob/master/CONTRIBUTING.md
44
Before=dstack-prepare.service
5-
ConditionPathExists=!/dev/tdx_guest
6-
ConditionPathExists=!/dev/sev-guest
75

86
[Service]
97
Type=notify
10-
ExecCondition=/bin/sh -c '! grep -qE "^(tdx_guest|sev_guest)" /sys/kernel/config/tsm/report/*/provider 2>/dev/null'
11-
ExecStartPre=/bin/mkdir -p /run/dstack/tee-simulator-host-shared
12-
ExecStartPre=/usr/bin/dstack-util host-shared mount --mount-point /run/dstack/tee-simulator-host-shared
8+
ExecCondition=/bin/sh -c '/usr/bin/dstack-util host-shared mount --mount-point /run/dstack/tee-simulator-host-shared && { test -f /run/dstack/tee-simulator-host-shared/.tee-simulator.json || { /usr/bin/dstack-util host-shared unmount --mount-point /run/dstack/tee-simulator-host-shared; exit 1; }; }'
139
ExecStart=/usr/bin/dstack-tee-simulator --config /run/dstack/tee-simulator-host-shared/.tee-simulator.json
1410
ExecStartPost=/bin/systemctl set-environment DCAP_TDX_RTMR_SYSFS_PATH=/sys/kernel/config/tsm/report/com.intel.dcap/measurements DSTACK_CCEL_FILE=/sys/kernel/config/tsm/report/com.intel.dcap/ccel
1511
ExecStartPost=-/usr/bin/dstack-util host-shared unmount --mount-point /run/dstack/tee-simulator-host-shared

0 commit comments

Comments
 (0)