@@ -62,52 +62,45 @@ impl PropolisServer {
62
62
let ( server_stdout, server_stderr) =
63
63
log_mode. get_handles ( & data_dir, vm_name) ?;
64
64
65
- // In the normal course of events, dropping a `TestVm` will spawn a task
66
- // that takes ownership of its `PropolisServer` and then sends Propolis
67
- // client calls to gracefully stop the VM running in that server (if
68
- // there is one). This ensures (modulo any bugs in Propolis itself) that
69
- // any Propolis servers hosting a running VM will have a chance to
70
- // destroy their kernel VMMs before the servers themselves go away.
65
+ let mut server_cmd = std:: process:: Command :: new ( "pfexec" ) ;
66
+ server_cmd
67
+ . args ( [
68
+ server_path. as_str ( ) ,
69
+ "run" ,
70
+ config_toml_path. as_str ( ) ,
71
+ server_addr. to_string ( ) . as_str ( ) ,
72
+ vnc_addr. to_string ( ) . as_str ( ) ,
73
+ ] )
74
+ . stdout ( server_stdout)
75
+ . stderr ( server_stderr) ;
76
+
77
+ // Gracefully shutting down a Propolis server requires PHD to send an
78
+ // instance stop request to the server before it is actually terminated.
79
+ // This ensures that the server has a chance to clean up kernel VMM
80
+ // resources. It's desirable for the server to do this and not PHD
81
+ // because a failure to clean up VMMs on stop is a Propolis bug.
71
82
//
72
- // The PHD runner tries to give VMs a chance to tear down gracefully on
73
- // Ctrl-C by installing a custom SIGINT handler and using it to tell
74
- // running test tasks to shut down instead of completing their tests.
75
- // This allows the tests' VMs to be dropped gracefully. The trouble is
76
- // that with no additional intervention, pressing Ctrl-C to interrupt a
77
- // PHD runner process will typically cause SIGINTs to be delivered to
78
- // every process in the foreground process group, including both the
79
- // runner and all its Propolis server children. This breaks the `TestVm`
80
- // cleanup logic: by the time the VM is cleaned up, its server process
81
- // is already gone (due to the signal), so its VMM can't be cleaned up.
83
+ // The PHD runner sets up a SIGINT handler that tries to give the
84
+ // framework an opportunity to issue these requests before the runner
85
+ // exits. However, pressing Ctrl-C in a shell will typically broadcast
86
+ // SIGINT to all of the processes in the foreground process's group, not
87
+ // just to the foreground process itself. This means that a Ctrl-C press
88
+ // will usually kill all of PHD's Propolis servers before the cleanup
89
+ // logic can run.
82
90
//
83
- // To get around this, spawn Propolis server processes with a pre-`exec`
84
- // hook that directs them to ignore SIGINT. They will still be killed
85
- // during `TestVm` cleanup, assuming that executes normally; if the
86
- // runner is rudely terminated after that, the server process is still
87
- // preserved for investigation (and can still be cleaned up by other
88
- // means, e.g. SIGKILL).
89
- //
90
- // Note that it's undesirable for PHD to try to clean up leaked kernel
91
- // VMMs itself: leaking a kernel VMM after gracefully stopping a
92
- // Propolis server VM indicates a Propolis server bug.
91
+ // To avoid this problem, add a pre-`exec` hook that directs Propolis
92
+ // servers to ignore SIGINT. On Ctrl-C, the runner will drop all active
93
+ // `TestVm`s, and this drop path (if allowed to complete) will kill all
94
+ // these processes.
95
+ unsafe {
96
+ server_cmd. pre_exec ( move || {
97
+ libc:: signal ( libc:: SIGINT , libc:: SIG_IGN ) ;
98
+ Ok ( ( ) )
99
+ } ) ;
100
+ }
101
+
93
102
let server = PropolisServer {
94
- server : unsafe {
95
- std:: process:: Command :: new ( "pfexec" )
96
- . args ( [
97
- server_path. as_str ( ) ,
98
- "run" ,
99
- config_toml_path. as_str ( ) ,
100
- server_addr. to_string ( ) . as_str ( ) ,
101
- vnc_addr. to_string ( ) . as_str ( ) ,
102
- ] )
103
- . stdout ( server_stdout)
104
- . stderr ( server_stderr)
105
- . pre_exec ( move || {
106
- libc:: signal ( libc:: SIGINT , libc:: SIG_IGN ) ;
107
- Ok ( ( ) )
108
- } )
109
- . spawn ( ) ?
110
- } ,
103
+ server : server_cmd. spawn ( ) ?,
111
104
address : server_addr,
112
105
} ;
113
106
0 commit comments