diff options
author | Arthur Gautier <baloo@superbaloo.net> | 2023-08-01 07:05:58 +0000 |
---|---|---|
committer | Raito Bezarius <masterancpp@gmail.com> | 2023-10-23 01:02:24 +0200 |
commit | 08f4fe20874ea19c55849138fb3af734cb72a5a1 (patch) | |
tree | 9a907d164cda443b1ff24eb7c935f2fdc4ed0474 | |
parent | 83b131bb55bde0511a17d3beb52145d778dd4105 (diff) | |
download | nixpkgs-08f4fe20874ea19c55849138fb3af734cb72a5a1.tar nixpkgs-08f4fe20874ea19c55849138fb3af734cb72a5a1.tar.gz nixpkgs-08f4fe20874ea19c55849138fb3af734cb72a5a1.tar.bz2 nixpkgs-08f4fe20874ea19c55849138fb3af734cb72a5a1.tar.lz nixpkgs-08f4fe20874ea19c55849138fb3af734cb72a5a1.tar.xz nixpkgs-08f4fe20874ea19c55849138fb3af734cb72a5a1.tar.zst nixpkgs-08f4fe20874ea19c55849138fb3af734cb72a5a1.zip |
qemu-vm: stop the swtpm once qemu stops
The idea is to run an async process waiting for swtpm and we have to ensure that `FD_CLOEXEC` is cleared on this process' stdin file descriptor, we use `fdflags` for this, a loadable builtin in Bash ≥ 5. The async process when exited will terminate `swtpm`, we bind the termination of the async process to the termination of QEMU by virtue of having `qemu` exec in that Bash script. Signed-off-by: Arthur Gautier <baloo@superbaloo.net> Co-authored-by: Raito Bezarius <masterancpp@gmail.com>
-rw-r--r-- | nixos/modules/virtualisation/qemu-vm.nix | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/nixos/modules/virtualisation/qemu-vm.nix b/nixos/modules/virtualisation/qemu-vm.nix index a1606839b6c..3bf8bbd9dab 100644 --- a/nixos/modules/virtualisation/qemu-vm.nix +++ b/nixos/modules/virtualisation/qemu-vm.nix @@ -204,8 +204,31 @@ let ${lib.getExe cfg.tpm.package} \ socket \ --tpmstate dir="$NIX_SWTPM_DIR" \ - --ctrl type=unixio,path="$NIX_SWTPM_DIR"/socket \ - "--tpm2" 1>"$NIX_SWTPM_DIR"/stdout 2>"$NIX_SWTPM_DIR"/stderr & + --ctrl type=unixio,path="$NIX_SWTPM_DIR"/socket,terminate \ + --pid file="$NIX_SWTPM_DIR"/pid --daemon \ + --tpm2 \ + --log file="$NIX_SWTPM_DIR"/stdout,level=6 + + # Enable `fdflags` builtin in Bash + # We will need it to perform surgical modification of the file descriptor + # passed in the coprocess to remove `FD_CLOEXEC`, i.e. close the file descriptor + # on exec. + # If let alone, it will trigger the coprocess to read EOF when QEMU is `exec` + # at the end of this script. To work around that, we will just clear + # the `FD_CLOEXEC` bits as a first step. + enable -f ${hostPkgs.bash}/lib/bash/fdflags fdflags + # leave a dangling subprocess because the swtpm ctrl socket has + # "terminate" when the last connection disconnects, it stops swtpm. + # When qemu stops, or if the main shell process ends, the coproc will + # get signaled by virtue of the pipe between main and coproc ending. + # Which in turns triggers a socat connect-disconnect to swtpm which + # will stop it. + coproc waitingswtpm { + read || : + echo "" | ${lib.getExe hostPkgs.socat} STDIO UNIX-CONNECT:"$NIX_SWTPM_DIR"/socket + } + # Clear `FD_CLOEXEC` on the coprocess' file descriptor stdin. + fdflags -s-cloexec ''${waitingswtpm[1]} ''} cd "$TMPDIR" |