Skip to content

Commit e83916a

Browse files
committed
alioth: add
1 parent 094d684 commit e83916a

File tree

10 files changed

+249
-2
lines changed

10 files changed

+249
-2
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Major Changes in microvm.nix
22

3+
## Unreleased
4+
5+
* Add the [alioth VMM](https://github.com/google/alioth)
6+
37
## 0.5.0 (2024-04-06)
48

59
* **tap interfaces** are now **multi-queue** when running with more

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ imperatively with the provided `microvm` command.
5555
| [crosvm](https://chromium.googlesource.com/chromiumos/platform/crosvm/) | Rust | 9p shares broken |
5656
| [kvmtool](https://github.com/kvmtool/kvmtool) | C | no virtiofs shares, no control socket |
5757
| [stratovirt](https://github.com/openeuler-mirror/stratovirt) | Rust | no 9p/virtiofs shares, no control socket |
58+
| [alioth](https://github.com/google/alioth) | Rust | no virtiofs shares, no control socket |
5859

5960

6061
## Installation

checks/default.nix

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ let
4747
modules = [ {
4848
microvm.hypervisor = "kvmtool";
4949
} ];
50+
} {
51+
id = "alioth";
52+
modules = [ {
53+
microvm.hypervisor = "alioth";
54+
} ];
5055
} ]
5156
# ro-store
5257
[ {

checks/startup-shutdown.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ let
3333
cloud-hypervisor = "poweroff";
3434
crosvm = "reboot";
3535
kvmtool = "reboot";
36+
alioth = "poweroff";
3637
}.${config.microvm.hypervisor};
3738
in ''
3839
${pkgs.coreutils}/bin/uname > /output/kernel-name

flake.lock

Lines changed: 39 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,18 @@
88

99
inputs = {
1010
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
11+
fenix = {
12+
url = "github:nix-community/fenix";
13+
inputs.nixpkgs.follows = "nixpkgs";
14+
};
1115
flake-utils.url = "github:numtide/flake-utils";
1216
spectrum = {
1317
url = "git+https://spectrum-os.org/git/spectrum";
1418
flake = false;
1519
};
1620
};
1721

18-
outputs = { self, nixpkgs, flake-utils, spectrum }:
22+
outputs = { self, nixpkgs, fenix, flake-utils, spectrum }:
1923
let
2024
systems = [
2125
"x86_64-linux"
@@ -91,7 +95,10 @@
9195

9296
packages =
9397
let
94-
pkgs = nixpkgs.legacyPackages.${system};
98+
pkgs = import nixpkgs {
99+
overlays = [ self.overlay ];
100+
};
101+
rustNightly = fenix.packages.${system}.minimal.toolchain;
95102
in {
96103
build-microvm = pkgs.callPackage ./pkgs/build-microvm.nix { inherit self; };
97104
doc = pkgs.callPackage ./pkgs/doc.nix { inherit nixpkgs; };
@@ -108,13 +115,20 @@
108115
crosvm-example
109116
kvmtool-example
110117
stratovirt-example
118+
alioth-example
111119
virtiofsd
112120
];
113121
pathsToLink = [ "/" ];
114122
extraOutputsToInstall = [ "dev" ];
115123
ignoreCollisions = true;
116124
};
117125
waypipe = overrideWaypipe pkgs;
126+
alioth = pkgs.callPackage ./pkgs/alioth.nix {
127+
rustPlatform = pkgs.makeRustPlatform {
128+
cargo = rustNightly;
129+
rustc = rustNightly;
130+
};
131+
};
118132
} //
119133
# wrap self.nixosConfigurations in executable packages
120134
builtins.foldl' (result: systemName:
@@ -145,7 +159,18 @@
145159
overlay = final: prev: {
146160
cloud-hypervisor-graphics = prev.callPackage (spectrum + "/pkgs/cloud-hypervisor") {};
147161
waypipe = overrideWaypipe prev;
162+
alioth =
163+
let
164+
rustNightly = fenix.packages.${final.system}.minimal.toolchain;
165+
in
166+
prev.callPackage ./pkgs/alioth.nix {
167+
rustPlatform = final.makeRustPlatform {
168+
cargo = rustNightly;
169+
rustc = rustNightly;
170+
};
171+
};
148172
};
173+
overlays.default = self.overlay;
149174

150175
nixosModules = {
151176
microvm = import ./nixos-modules/microvm;
@@ -179,6 +204,7 @@
179204
networking.hostName = "${hypervisor}-microvm";
180205
services.getty.autologinUser = "root";
181206

207+
nixpkgs.overlays = [ self.overlay ];
182208
microvm.hypervisor = hypervisor;
183209
# share the host's /nix/store if the hypervisor can do 9p
184210
microvm.shares = lib.optional (builtins.elem hypervisor hypervisorsWith9p) {

lib/default.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ rec {
77
"crosvm"
88
"kvmtool"
99
"stratovirt"
10+
"alioth"
1011
];
1112

1213
hypervisorsWithNetwork = hypervisors;

lib/runners/alioth.nix

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{ pkgs
2+
, microvmConfig
3+
, macvtapFds
4+
}:
5+
6+
let
7+
inherit (pkgs) lib;
8+
inherit (microvmConfig)
9+
user
10+
vcpu mem interfaces volumes shares devices vsock
11+
kernel initrdPath
12+
storeDisk storeOnDisk;
13+
in {
14+
command =
15+
if user != null
16+
then throw "alioth will not change user"
17+
else builtins.concatStringsSep " " (
18+
[
19+
"${pkgs.alioth}/bin/alioth" "run"
20+
"--mem-size" "${toString mem}M"
21+
"--num-cpu" (toString vcpu)
22+
"-k" (lib.escapeShellArg "${kernel}/${pkgs.stdenv.hostPlatform.linux-kernel.target}")
23+
"-i" initrdPath
24+
"-c" (lib.escapeShellArg "console=ttyS0 reboot=k panic=1 ${toString microvmConfig.kernelParams}")
25+
"--entropy"
26+
]
27+
++
28+
lib.optionals storeOnDisk [
29+
"--blk" (lib.escapeShellArg "path=${storeDisk},readonly=true")
30+
]
31+
++
32+
builtins.concatMap ({ image, ... }:
33+
[ "--blk" (lib.escapeShellArg image) ]
34+
) volumes
35+
++
36+
builtins.concatMap ({ proto, socket, tag, ... }:
37+
if proto == "virtiofs"
38+
then [
39+
"--fs" (lib.escapeShellArg "vu,socket=${socket},tag=${tag}")
40+
] else throw "9p shares not implemented for alioth"
41+
) shares
42+
++
43+
builtins.concatMap ({ type, id, mac, ... }:
44+
if type == "tap"
45+
then [
46+
"--net" (lib.escapeShellArg "if_name=${id},mac=${mac},queue_pairs=${toString vcpu}")
47+
]
48+
else throw "interface type ${type} is not supported by alioth"
49+
) interfaces
50+
++
51+
map ({ ... }:
52+
throw "PCI/USB passthrough is not supported on alioth"
53+
) devices
54+
++
55+
lib.optionals (vsock.cid != null) [
56+
"--vsock" "vhost,cid=${toString vsock.cid}"
57+
]
58+
);
59+
60+
# TODO:
61+
canShutdown = false;
62+
}

pkgs/alioth-blk-ro.patch

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
From 553d05d8364e2bbba807279b4d30949d0764b444 Mon Sep 17 00:00:00 2001
2+
From: Astro <[email protected]>
3+
Date: Tue, 9 Jul 2024 12:44:17 +0200
4+
Subject: [PATCH] feat(blk): allow configuring readonly block devices
5+
6+
---
7+
alioth-cli/src/main.rs | 2 +-
8+
alioth/src/virtio/dev/blk.rs | 11 +++++++++--
9+
2 files changed, 10 insertions(+), 3 deletions(-)
10+
11+
diff --git a/alioth-cli/src/main.rs b/alioth-cli/src/main.rs
12+
index 74aa578..3858afb 100644
13+
--- a/alioth-cli/src/main.rs
14+
+++ b/alioth-cli/src/main.rs
15+
@@ -253,7 +253,7 @@ fn main_run(args: RunArgs) -> Result<(), Error> {
16+
.context(error::CreateDevice)?;
17+
}
18+
for (index, blk) in args.blk.into_iter().enumerate() {
19+
- let param = BlockParam { path: blk.into() };
20+
+ let param: BlockParam = serde_aco::from_arg(&blk).context(error::ParseArg { arg: blk })?;
21+
vm.add_virtio_dev(format!("virtio-blk-{index}"), param)
22+
.context(error::CreateDevice)?;
23+
}
24+
diff --git a/alioth/src/virtio/dev/blk.rs b/alioth/src/virtio/dev/blk.rs
25+
index 29fc6ce..3127e24 100644
26+
--- a/alioth/src/virtio/dev/blk.rs
27+
+++ b/alioth/src/virtio/dev/blk.rs
28+
@@ -21,6 +21,7 @@ use std::sync::Arc;
29+
use bitflags::bitflags;
30+
use mio::event::Event;
31+
use mio::Registry;
32+
+use serde::Deserialize;
33+
use zerocopy::{AsBytes, FromBytes, FromZeroes};
34+
35+
use crate::mem::mapped::RamBus;
36+
@@ -122,8 +123,10 @@ pub struct BlockConfig {
37+
}
38+
impl_mmio_for_zerocopy!(BlockConfig);
39+
40+
+#[derive(Debug, Clone, Deserialize)]
41+
pub struct BlockParam {
42+
pub path: PathBuf,
43+
+ pub readonly: bool,
44+
}
45+
46+
impl DevParam for BlockParam {
47+
@@ -144,7 +147,7 @@ pub struct Block {
48+
49+
impl Block {
50+
pub fn new(param: BlockParam, name: Arc<String>) -> Result<Self> {
51+
- let disk = OpenOptions::new().read(true).write(true).open(param.path)?;
52+
+ let disk = OpenOptions::new().read(true).write(!param.readonly).open(param.path)?;
53+
let len = disk.metadata()?.len();
54+
let config = BlockConfig {
55+
capacity: len / SECTOR_SIZE as u64,
56+
@@ -152,11 +155,15 @@ impl Block {
57+
..Default::default()
58+
};
59+
let config = Arc::new(config);
60+
+ let mut feature = BlockFeature::FLUSH;
61+
+ if param.readonly {
62+
+ feature |= BlockFeature::RO;
63+
+ }
64+
Ok(Block {
65+
name,
66+
disk,
67+
config,
68+
- feature: BlockFeature::FLUSH,
69+
+ feature,
70+
})
71+
}
72+
73+
--
74+
2.44.1
75+

pkgs/alioth.nix

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# TODO: upstream to nixpkgs once it no longer requires rust nightly
2+
{ lib, fetchFromGitHub, rustPlatform }:
3+
4+
rustPlatform.buildRustPackage rec {
5+
pname = "alioth";
6+
version = "0.3.0";
7+
8+
src = fetchFromGitHub {
9+
owner = "google";
10+
repo = pname;
11+
rev = "v${version}";
12+
hash = "sha256-brlbLjlpOYz+Qzn2IG9y6ty+yF6MohG5IhI+BHu6LuA=";
13+
};
14+
15+
patches = [
16+
./alioth-blk-ro.patch
17+
];
18+
19+
cargoHash = "sha256-jRyRy1aKLk92bUvw4Q4lE8q7bnTDgJ7pWCMIW4nBo1A=";
20+
separateDebugInfo = true;
21+
22+
# TODO: Broken
23+
doCheck = false;
24+
25+
meta = with lib; {
26+
homepage = "https://github.com/google/alioth";
27+
description = "Experimental Type-2 Hypervisor in Rust implemented from scratch";
28+
license = licenses.asl20;
29+
mainProgram = "alioth";
30+
maintainers = with maintainers; [ astro ];
31+
platforms = [ "aarch64-linux" "x86_64-linux" ];
32+
};
33+
}

0 commit comments

Comments
 (0)