66//! translated from an original Go implementation.
77
88use anyhow:: { bail, Context , Result } ;
9- use fs_err as fs;
109use log:: debug;
1110use scale:: Decode ;
12- use std:: os:: unix:: fs:: FileTypeExt ;
13- use std:: path:: PathBuf ;
14- use std:: process:: { Child , Command , Stdio } ;
15- use std:: sync:: atomic:: { AtomicU64 , Ordering } ;
16- use std:: thread;
17- use std:: time:: Duration ;
11+ use std:: process:: Command ;
1812
1913use crate :: Machine ;
2014
2115const LDR_LENGTH : usize = 4096 ;
2216const FIXED_STRING_LEN : usize = 56 ;
23- static SWTPM_ID : AtomicU64 = AtomicU64 :: new ( 0 ) ;
24-
25- struct SwtpmGuard {
26- child : Child ,
27- state_dir : PathBuf ,
28- socket : PathBuf ,
29- }
30-
31- impl Drop for SwtpmGuard {
32- fn drop ( & mut self ) {
33- let _ = self . child . kill ( ) ;
34- let _ = self . child . wait ( ) ;
35- let _ = fs:: remove_dir_all ( & self . state_dir ) ;
36- }
37- }
38-
39- fn start_measurement_swtpm ( ) -> Result < SwtpmGuard > {
40- let id = SWTPM_ID . fetch_add ( 1 , Ordering :: Relaxed ) ;
41- let state_dir =
42- std:: env:: temp_dir ( ) . join ( format ! ( "dstack-mr-swtpm-{}-{id}" , std:: process:: id( ) ) ) ;
43- fs:: create_dir_all ( & state_dir) . context ( "failed to create measurement swtpm state directory" ) ?;
44- let socket = state_dir. join ( "swtpm.sock" ) ;
45- let child = Command :: new ( "swtpm" )
46- . args ( [ "socket" , "--tpm2" , "--tpmstate" ] )
47- . arg ( format ! ( "dir={}" , state_dir. display( ) ) )
48- . arg ( "--ctrl" )
49- . arg ( format ! ( "type=unixio,path={}" , socket. display( ) ) )
50- . args ( [ "--flags" , "startup-clear" ] )
51- . stdin ( Stdio :: null ( ) )
52- . stdout ( Stdio :: null ( ) )
53- . stderr ( Stdio :: null ( ) )
54- . spawn ( )
55- . inspect_err ( |_| {
56- let _ = fs:: remove_dir_all ( & state_dir) ;
57- } )
58- . context ( "failed to start swtpm for ACPI measurement" ) ?;
59- let mut guard = SwtpmGuard {
60- child,
61- state_dir,
62- socket,
63- } ;
64-
65- for _ in 0 ..100 {
66- if fs:: metadata ( & guard. socket ) . is_ok_and ( |metadata| metadata. file_type ( ) . is_socket ( ) ) {
67- return Ok ( guard) ;
68- }
69- if guard. child . try_wait ( ) ?. is_some ( ) {
70- bail ! ( "measurement swtpm exited before its socket was ready" ) ;
71- }
72- thread:: sleep ( Duration :: from_millis ( 10 ) ) ;
73- }
74- bail ! ( "timed out waiting for measurement swtpm socket" )
75- }
76-
7717#[ derive( Debug , Clone ) ]
7818pub struct Tables {
7919 pub tables : Vec < u8 > ,
@@ -83,6 +23,9 @@ pub struct Tables {
8323
8424impl Machine < ' _ > {
8525 fn create_tables ( & self ) -> Result < Vec < u8 > > {
26+ if self . swtpm {
27+ bail ! ( "swtpm measurement is not supported" ) ;
28+ }
8629 if self . cpu_count == 0 {
8730 bail ! ( "cpuCount must be greater than 0" ) ;
8831 }
@@ -136,18 +79,6 @@ impl Machine<'_> {
13679 . arg ( format ! ( "virtio-net-pci,netdev=net{i}" ) ) ;
13780 }
13881
139- let swtpm = self . qemu_swtpm . then ( start_measurement_swtpm) . transpose ( ) ?;
140- if let Some ( swtpm) = & swtpm {
141- cmd. arg ( "-chardev" )
142- . arg ( format ! ( "socket,id=chrtpm,path={}" , swtpm. socket. display( ) ) )
143- . args ( [
144- "-tpmdev" ,
145- "emulator,id=tpm0,chardev=chrtpm" ,
146- "-device" ,
147- "tpm-tis,tpmdev=tpm0" ,
148- ] ) ;
149- }
150-
15182 cmd. args ( [
15283 "-object" ,
15384 "tdx-guest,id=tdx" ,
0 commit comments