summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2023-11-05 12:36:49 +0000
committerAlyssa Ross <hi@alyssa.is>2024-02-23 15:27:58 +0100
commitbc1bcf6468072c00b3da0b6f23560f5060447705 (patch)
treec912701423e626bb4ccfe5e84df6be0234f6d37c
parent0e92a62b9a4cab9e6725b905e8ebb671792dc15d (diff)
downloadspectrum-bc1bcf6468072c00b3da0b6f23560f5060447705.tar
spectrum-bc1bcf6468072c00b3da0b6f23560f5060447705.tar.gz
spectrum-bc1bcf6468072c00b3da0b6f23560f5060447705.tar.bz2
spectrum-bc1bcf6468072c00b3da0b6f23560f5060447705.tar.lz
spectrum-bc1bcf6468072c00b3da0b6f23560f5060447705.tar.xz
spectrum-bc1bcf6468072c00b3da0b6f23560f5060447705.tar.zst
spectrum-bc1bcf6468072c00b3da0b6f23560f5060447705.zip
host/start-vm: find config from /run/vm
Having a symlink in the service directory was a nice idea, but since
it has to be different for every service, it's not compatible with
templated services, and would prevent us switching to them.  The only
thing that varies between instances of templated services is the name,
so we have to introduce a mapping of VM name to config directory.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
-rw-r--r--host/rootfs/Makefile2
-rw-r--r--host/rootfs/etc/s6-rc/ext-rc-init/up6
-rw-r--r--host/start-vm/lib.rs12
-rw-r--r--host/start-vm/start-vm.rs3
-rw-r--r--host/start-vm/tests/vm_command-basic.rs11
-rw-r--r--host/start-vm/tests/vm_command-multiple-disks.rs9
-rw-r--r--host/start-vm/tests/vm_command-shared-dir.rs9
7 files changed, 31 insertions, 21 deletions
diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
index cf985c3..a108a29 100644
--- a/host/rootfs/Makefile
+++ b/host/rootfs/Makefile
@@ -37,7 +37,7 @@ FILES = \
 	usr/bin/vm-console \
 	usr/bin/vm-start \
 	usr/bin/vm-stop
-DIRS = dev etc/s6-linux-init/env ext run proc sys
+DIRS = dev etc/s6-linux-init/env etc/s6-linux-init/run-image/vm ext run proc sys
 
 # These are separate because they need to be included, but putting
 # them as make dependencies would confuse make.
diff --git a/host/rootfs/etc/s6-rc/ext-rc-init/up b/host/rootfs/etc/s6-rc/ext-rc-init/up
index f6d0e77..b2c2595 100644
--- a/host/rootfs/etc/s6-rc/ext-rc-init/up
+++ b/host/rootfs/etc/s6-rc/ext-rc-init/up
@@ -10,8 +10,10 @@ if {
   forx -po0 -E dir { $dirs }
   backtick -E name { basename -- $dir }
 
-  if { mkdir vm-${name} vm-${name}/data vm-${name}/dependencies.d vm-${name}/env }
-  if { ln -s $dir vm-${name}/data/config }
+  if { mkdir /run/vm/${name} }
+  if { ln -s $dir /run/vm/${name}/config }
+
+  if { mkdir vm-${name} vm-${name}/dependencies.d vm-${name}/env }
   if { redirfd -w 1 vm-${name}/type echo longrun }
   if { redirfd -w 1 vm-${name}/notification-fd echo 3 }
   if { redirfd -w 1 vm-${name}/run printf "#!/bin/execlineb -P\n/bin/start-vm" }
diff --git a/host/start-vm/lib.rs b/host/start-vm/lib.rs
index 33c19bb..0c1e0d2 100644
--- a/host/start-vm/lib.rs
+++ b/host/start-vm/lib.rs
@@ -47,8 +47,12 @@ pub fn create_api_socket() -> Result<UnixListener, String> {
     Ok(api_socket)
 }
 
-pub fn vm_command(dir: &Path, api_socket_fd: RawFd) -> Result<Command, String> {
-    let vm_name = dir
+pub fn vm_command(
+    service_dir: &Path,
+    vm_dir: &Path,
+    api_socket_fd: RawFd,
+) -> Result<Command, String> {
+    let vm_name = service_dir
         .file_name()
         .ok_or_else(|| "directory has no name".to_string())?
         .as_bytes();
@@ -63,7 +67,7 @@ pub fn vm_command(dir: &Path, api_socket_fd: RawFd) -> Result<Command, String> {
 
     let vm_name = OsStr::from_bytes(&vm_name[3..]);
 
-    let config_dir = dir.join("data/config");
+    let config_dir = vm_dir.join(vm_name).join("config");
 
     let mut command = Command::new("cloud-hypervisor");
     command.args(["--api-socket", &format!("fd={api_socket_fd}")]);
@@ -186,7 +190,7 @@ mod tests {
 
     #[test]
     fn test_vm_name_comma() {
-        assert!(vm_command(Path::new("/vm-,"), -1)
+        assert!(vm_command(Path::new("/vm-,"), Path::new(""), -1)
             .unwrap_err()
             .contains("comma"));
     }
diff --git a/host/start-vm/start-vm.rs b/host/start-vm/start-vm.rs
index bbe80bd..7dfca09 100644
--- a/host/start-vm/start-vm.rs
+++ b/host/start-vm/start-vm.rs
@@ -3,6 +3,7 @@
 
 use std::env::current_dir;
 use std::os::unix::prelude::*;
+use std::path::Path;
 use std::process::exit;
 
 use start_vm::{create_api_socket, notify_readiness, prog_name, vm_command};
@@ -25,7 +26,7 @@ unsafe fn run() -> String {
         return e;
     }
 
-    match vm_command(&dir, api_socket.into_raw_fd()) {
+    match vm_command(&dir, Path::new("/run/vm"), api_socket.into_raw_fd()) {
         Ok(mut command) => format!("failed to exec: {}", command.exec()),
         Err(e) => e,
     }
diff --git a/host/start-vm/tests/vm_command-basic.rs b/host/start-vm/tests/vm_command-basic.rs
index 92d78d8..d67a739 100644
--- a/host/start-vm/tests/vm_command-basic.rs
+++ b/host/start-vm/tests/vm_command-basic.rs
@@ -8,18 +8,19 @@ use start_vm::vm_command;
 use test_helper::TempDir;
 
 fn main() -> std::io::Result<()> {
-    let tmp_dir = TempDir::new()?;
+    let service_dir_parent = TempDir::new()?;
+    let service_dir = service_dir_parent.path().join("vm-testvm");
 
-    let service_dir = tmp_dir.path().join("vm-testvm");
+    let vm_dir = TempDir::new()?;
 
-    let kernel_path = service_dir.join("data/config/vmlinux");
-    let image_path = service_dir.join("data/config/blk/root.img");
+    let kernel_path = vm_dir.path().join("testvm/config/vmlinux");
+    let image_path = vm_dir.path().join("testvm/config/blk/root.img");
 
     create_dir_all(image_path.parent().unwrap())?;
     File::create(&kernel_path)?;
     File::create(&image_path)?;
 
-    let command = vm_command(&service_dir, 4).unwrap();
+    let command = vm_command(&service_dir, vm_dir.path(), 4).unwrap();
     assert_eq!(command.get_program(), "cloud-hypervisor");
 
     let mut expected_disk_arg = OsString::from("path=");
diff --git a/host/start-vm/tests/vm_command-multiple-disks.rs b/host/start-vm/tests/vm_command-multiple-disks.rs
index e17d505..68ed495 100644
--- a/host/start-vm/tests/vm_command-multiple-disks.rs
+++ b/host/start-vm/tests/vm_command-multiple-disks.rs
@@ -10,10 +10,11 @@ use start_vm::vm_command;
 use test_helper::TempDir;
 
 fn main() -> std::io::Result<()> {
-    let tmp_dir = TempDir::new()?;
+    let service_dir_parent = TempDir::new()?;
+    let service_dir = service_dir_parent.path().join("vm-testvm");
 
-    let service_dir = tmp_dir.path().join("vm-testvm");
-    let vm_config = service_dir.join("data/config");
+    let vm_dir = TempDir::new()?;
+    let vm_config = vm_dir.path().join("testvm/config");
 
     create_dir_all(&vm_config)?;
     File::create(vm_config.join("vmlinux"))?;
@@ -27,7 +28,7 @@ fn main() -> std::io::Result<()> {
         symlink("/dev/null", image_path)?;
     }
 
-    let command = vm_command(&service_dir, -1).unwrap();
+    let command = vm_command(&service_dir, vm_dir.path(), -1).unwrap();
     let mut args = command.get_args();
 
     assert!(args.any(|arg| arg == "--disk"));
diff --git a/host/start-vm/tests/vm_command-shared-dir.rs b/host/start-vm/tests/vm_command-shared-dir.rs
index d310d09..481230a 100644
--- a/host/start-vm/tests/vm_command-shared-dir.rs
+++ b/host/start-vm/tests/vm_command-shared-dir.rs
@@ -10,10 +10,11 @@ use start_vm::vm_command;
 use test_helper::TempDir;
 
 fn main() -> std::io::Result<()> {
-    let tmp_dir = TempDir::new()?;
+    let service_dir_parent = TempDir::new()?;
+    let service_dir = service_dir_parent.path().join("vm-testvm");
 
-    let service_dir = tmp_dir.path().join("vm-testvm");
-    let vm_config = service_dir.join("data/config");
+    let vm_dir = TempDir::new()?;
+    let vm_config = vm_dir.path().join("testvm/config");
 
     create_dir_all(&vm_config)?;
     File::create(vm_config.join("vmlinux"))?;
@@ -28,7 +29,7 @@ fn main() -> std::io::Result<()> {
     create_dir(vm_config.join("shared-dirs/dir2"))?;
     symlink("/", vm_config.join("shared-dirs/dir2/dir"))?;
 
-    let command = vm_command(&service_dir, -1).unwrap();
+    let command = vm_command(&service_dir, vm_dir.path(), -1).unwrap();
     let mut args = command.get_args();
 
     assert!(args.any(|arg| arg == "--fs"));