mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-21 21:25:19 +00:00
main: switch command parsing to use clap
Partially revert 111225a2a5
and add the new dbus and pvpanic arguments.
As we are switching back to clap observe the following changes.
A few examples:
1. `-v -v -v` needs to be written as`-vvv`
2. `--disk D1 --disk D2` and others need to be written as `--disk D1 D2`.
3. `--option value` needs to be written as `--option=value.`
Change integration tests to adapt to the breaking changes.
Signed-off-by: Wei Liu <liuwe@microsoft.com>
Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@intel.com>
This commit is contained in:
parent
6113483363
commit
7bc3452139
107
Cargo.lock
generated
107
Cargo.lock
generated
@ -34,6 +34,55 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstream"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"anstyle-parse",
|
||||||
|
"anstyle-query",
|
||||||
|
"anstyle-wincon",
|
||||||
|
"colorchoice",
|
||||||
|
"is-terminal",
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-parse"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333"
|
||||||
|
dependencies = [
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-query"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.48.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-wincon"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"windows-sys 0.48.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.75"
|
version = "1.0.75"
|
||||||
@ -77,9 +126,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "argh"
|
name = "argh"
|
||||||
version = "0.1.10"
|
version = "0.1.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ab257697eb9496bf75526f0217b5ed64636a9cfafa78b8365c71bd283fcef93e"
|
checksum = "7af5ba06967ff7214ce4c7419c7d185be7ecd6cc4965a8f6e1d8ce0398aad219"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"argh_derive",
|
"argh_derive",
|
||||||
"argh_shared",
|
"argh_shared",
|
||||||
@ -87,21 +136,24 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "argh_derive"
|
name = "argh_derive"
|
||||||
version = "0.1.10"
|
version = "0.1.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b382dbd3288e053331f03399e1db106c9fb0d8562ad62cb04859ae926f324fa6"
|
checksum = "56df0aeedf6b7a2fc67d06db35b09684c3e8da0c95f8f27685cb17e08413d87a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"argh_shared",
|
"argh_shared",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 1.0.109",
|
"syn 2.0.31",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "argh_shared"
|
name = "argh_shared"
|
||||||
version = "0.1.10"
|
version = "0.1.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "64cb94155d965e3d37ffbbe7cc5b82c3dd79dd33bd48e536f73d2cfb8d85506f"
|
checksum = "5693f39141bda5760ecc4111ab08da40565d1771038c4a0250f03457ec707531"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-broadcast"
|
name = "async-broadcast"
|
||||||
@ -364,6 +416,33 @@ version = "1.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "4.3.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1640e5cc7fb47dbb8338fd471b105e7ed6c3cb2aeb00c2e067127ffd3764a05d"
|
||||||
|
dependencies = [
|
||||||
|
"clap_builder",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_builder"
|
||||||
|
version = "4.3.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "98c59138d527eeaf9b53f35a77fcc1fad9d883116070c63d5de1c7dc7b00c72b"
|
||||||
|
dependencies = [
|
||||||
|
"anstream",
|
||||||
|
"anstyle",
|
||||||
|
"clap_lex",
|
||||||
|
"strsim",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_lex"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cloud-hypervisor"
|
name = "cloud-hypervisor"
|
||||||
version = "35.0.0"
|
version = "35.0.0"
|
||||||
@ -371,6 +450,7 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"api_client",
|
"api_client",
|
||||||
"argh",
|
"argh",
|
||||||
|
"clap",
|
||||||
"dhat",
|
"dhat",
|
||||||
"dirs",
|
"dirs",
|
||||||
"epoll",
|
"epoll",
|
||||||
@ -395,6 +475,12 @@ dependencies = [
|
|||||||
"zbus",
|
"zbus",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorchoice"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "concurrent-queue"
|
name = "concurrent-queue"
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
@ -2084,6 +2170,12 @@ version = "1.0.11"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
|
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8parse"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid"
|
name = "uuid"
|
||||||
version = "1.3.4"
|
version = "1.3.4"
|
||||||
@ -2364,6 +2456,7 @@ dependencies = [
|
|||||||
"block",
|
"block",
|
||||||
"blocking",
|
"blocking",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
"clap",
|
||||||
"devices",
|
"devices",
|
||||||
"epoll",
|
"epoll",
|
||||||
"event_monitor",
|
"event_monitor",
|
||||||
|
@ -32,6 +32,7 @@ debug = true
|
|||||||
anyhow = "1.0.75"
|
anyhow = "1.0.75"
|
||||||
api_client = { path = "api_client" }
|
api_client = { path = "api_client" }
|
||||||
argh = "0.1.9"
|
argh = "0.1.9"
|
||||||
|
clap = { version = "4.3.11", features = ["string"] }
|
||||||
dhat = { version = "0.3.2", optional = true }
|
dhat = { version = "0.3.2", optional = true }
|
||||||
epoll = "4.3.3"
|
epoll = "4.3.3"
|
||||||
event_monitor = { path = "event_monitor" }
|
event_monitor = { path = "event_monitor" }
|
||||||
|
187
fuzz/Cargo.lock
generated
187
fuzz/Cargo.lock
generated
@ -10,6 +10,54 @@ dependencies = [
|
|||||||
"zerocopy",
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstream"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"anstyle-parse",
|
||||||
|
"anstyle-query",
|
||||||
|
"anstyle-wincon",
|
||||||
|
"colorchoice",
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-parse"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140"
|
||||||
|
dependencies = [
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-query"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-wincon"
|
||||||
|
version = "3.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.75"
|
version = "1.0.75"
|
||||||
@ -57,37 +105,6 @@ dependencies = [
|
|||||||
"vmm-sys-util",
|
"vmm-sys-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "argh"
|
|
||||||
version = "0.1.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7af5ba06967ff7214ce4c7419c7d185be7ecd6cc4965a8f6e1d8ce0398aad219"
|
|
||||||
dependencies = [
|
|
||||||
"argh_derive",
|
|
||||||
"argh_shared",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "argh_derive"
|
|
||||||
version = "0.1.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "56df0aeedf6b7a2fc67d06db35b09684c3e8da0c95f8f27685cb17e08413d87a"
|
|
||||||
dependencies = [
|
|
||||||
"argh_shared",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.32",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "argh_shared"
|
|
||||||
version = "0.1.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5693f39141bda5760ecc4111ab08da40565d1771038c4a0250f03457ec707531"
|
|
||||||
dependencies = [
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@ -165,13 +182,40 @@ version = "1.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "4.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956"
|
||||||
|
dependencies = [
|
||||||
|
"clap_builder",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_builder"
|
||||||
|
version = "4.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45"
|
||||||
|
dependencies = [
|
||||||
|
"anstream",
|
||||||
|
"anstyle",
|
||||||
|
"clap_lex",
|
||||||
|
"strsim",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_lex"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cloud-hypervisor"
|
name = "cloud-hypervisor"
|
||||||
version = "35.0.0"
|
version = "35.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"api_client",
|
"api_client",
|
||||||
"argh",
|
"clap",
|
||||||
"epoll",
|
"epoll",
|
||||||
"event_monitor",
|
"event_monitor",
|
||||||
"hypervisor",
|
"hypervisor",
|
||||||
@ -213,6 +257,12 @@ dependencies = [
|
|||||||
"vmm-sys-util",
|
"vmm-sys-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorchoice"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crc32c"
|
name = "crc32c"
|
||||||
version = "0.6.4"
|
version = "0.6.4"
|
||||||
@ -822,6 +872,12 @@ version = "1.0.12"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8parse"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid"
|
name = "uuid"
|
||||||
version = "1.4.1"
|
version = "1.4.1"
|
||||||
@ -1035,6 +1091,7 @@ dependencies = [
|
|||||||
"bitflags 2.4.1",
|
"bitflags 2.4.1",
|
||||||
"block",
|
"block",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
"clap",
|
||||||
"devices",
|
"devices",
|
||||||
"epoll",
|
"epoll",
|
||||||
"event_monitor",
|
"event_monitor",
|
||||||
@ -1165,6 +1222,72 @@ version = "0.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.48.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm",
|
||||||
|
"windows_aarch64_msvc",
|
||||||
|
"windows_i686_gnu",
|
||||||
|
"windows_i686_msvc",
|
||||||
|
"windows_x86_64_gnu",
|
||||||
|
"windows_x86_64_gnullvm",
|
||||||
|
"windows_x86_64_msvc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.7.11"
|
version = "0.7.11"
|
||||||
|
@ -358,13 +358,11 @@ pub fn performance_block_io(control: &PerformanceTestControl) -> f64 {
|
|||||||
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
|
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--disk",
|
|
||||||
format!(
|
format!(
|
||||||
"path={}",
|
"path={}",
|
||||||
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--disk",
|
|
||||||
format!("path={BLK_IO_TEST_IMG}").as_str(),
|
format!("path={BLK_IO_TEST_IMG}").as_str(),
|
||||||
])
|
])
|
||||||
.default_net()
|
.default_net()
|
||||||
|
712
src/main.rs
712
src/main.rs
@ -6,7 +6,7 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate event_monitor;
|
extern crate event_monitor;
|
||||||
|
|
||||||
use argh::FromArgs;
|
use clap::{Arg, ArgAction, ArgGroup, ArgMatches, Command};
|
||||||
use libc::EFD_NONBLOCK;
|
use libc::EFD_NONBLOCK;
|
||||||
use log::{warn, LevelFilter};
|
use log::{warn, LevelFilter};
|
||||||
use option_parser::OptionParser;
|
use option_parser::OptionParser;
|
||||||
@ -128,6 +128,10 @@ impl log::Log for Logger {
|
|||||||
fn flush(&self) {}
|
fn flush(&self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn prepare_default_values() -> (String, String, String) {
|
||||||
|
(default_vcpus(), default_memory(), default_rng())
|
||||||
|
}
|
||||||
|
|
||||||
fn default_vcpus() -> String {
|
fn default_vcpus() -> String {
|
||||||
format!(
|
format!(
|
||||||
"boot={},max_phys_bits={}",
|
"boot={},max_phys_bits={}",
|
||||||
@ -144,280 +148,323 @@ fn default_rng() -> String {
|
|||||||
format!("src={}", config::DEFAULT_RNG_SOURCE)
|
format!("src={}", config::DEFAULT_RNG_SOURCE)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromArgs)]
|
fn create_app(default_vcpus: String, default_memory: String, default_rng: String) -> Command {
|
||||||
/// Launch a cloud-hypervisor VMM.
|
#[allow(clippy::let_and_return)]
|
||||||
pub struct TopLevel {
|
let app = Command::new("cloud-hypervisor")
|
||||||
#[argh(option, long = "cpus", default = "default_vcpus()")]
|
// 'BUILD_VERSION' is set by the build script 'build.rs' at
|
||||||
/// boot=<boot_vcpus>, max=<max_vcpus>, topology=<threads_per_core>:<cores_per_die>:<dies_per_package>:<packages>, kvm_hyperv=on|off, max_phys_bits=<maximum_number_of_physical_bits>, affinity=<list_of_vcpus_with_their_associated_cpuset>, features=<list_of_features_to_enable>
|
// compile time
|
||||||
cpus: String,
|
.author(env!("CARGO_PKG_AUTHORS"))
|
||||||
|
.about("Launch a cloud-hypervisor VMM.")
|
||||||
#[argh(option, long = "platform")]
|
.group(ArgGroup::new("vm-config").multiple(true))
|
||||||
/// num_pci_segments=<num_pci_segments>, iommu_segments=<list_of_segments>, serial_number=<dmi_device_serial_number>, uuid=<dmi_device_uuid>, oem_strings=<list_of_strings>
|
.group(ArgGroup::new("vmm-config").multiple(true))
|
||||||
platform: Option<String>,
|
.group(ArgGroup::new("logging").multiple(true))
|
||||||
|
.arg(
|
||||||
#[argh(option, long = "memory", default = "default_memory()")]
|
Arg::new("cpus")
|
||||||
/// size=<guest_memory_size>, mergeable=on|off, shared=on|off, hugepages=on|off, hugepage_size=<hugepage_size>, hotplug_method=acpi|virtio-mem, hotplug_size=<hotpluggable_memory_size>, hotplugged_size=<hotplugged_memory_size>, prefault=on|off, thp=on|off
|
.long("cpus")
|
||||||
memory: String,
|
.help(
|
||||||
|
"boot=<boot_vcpus>,max=<max_vcpus>,\
|
||||||
#[argh(option, long = "memory-zone")]
|
topology=<threads_per_core>:<cores_per_die>:<dies_per_package>:<packages>,\
|
||||||
/// size=<guest_memory_region_size>, file=<backing_file>, shared=on|off, hugepages=on|off, hugepage_size=<hugepage_size>, host_numa_node=<node_id>, id=<zone_identifier>, hotplug_size=<hotpluggable_memory_size>, hotplugged_size=<hotplugged_memory_size>, prefault=on|off
|
kvm_hyperv=on|off,max_phys_bits=<maximum_number_of_physical_bits>,\
|
||||||
memory_zone: Vec<String>,
|
affinity=<list_of_vcpus_with_their_associated_cpuset>,\
|
||||||
|
features=<list_of_features_to_enable>",
|
||||||
#[argh(option, long = "firmware")]
|
)
|
||||||
/// path to firmware that is loaded in an architectural specific way
|
.default_value(default_vcpus)
|
||||||
firmware: Option<String>,
|
.group("vm-config"),
|
||||||
|
)
|
||||||
#[argh(option, long = "kernel")]
|
.arg(
|
||||||
/// path to kernel or firmware that supports a PVH entry point or architecture equivalent
|
Arg::new("platform")
|
||||||
kernel: Option<String>,
|
.long("platform")
|
||||||
|
.help("num_pci_segments=<num_pci_segments>,iommu_segments=<list_of_segments>,serial_number=<dmi_device_serial_number>,uuid=<dmi_device_uuid>,oem_strings=<list_of_strings>")
|
||||||
#[argh(option, long = "initramfs")]
|
.num_args(1)
|
||||||
/// path to initramfs image
|
.group("vm-config"),
|
||||||
initramfs: Option<String>,
|
)
|
||||||
|
.arg(
|
||||||
#[argh(option, long = "cmdline")]
|
Arg::new("memory")
|
||||||
/// kernel command line
|
.long("memory")
|
||||||
cmdline: Option<String>,
|
.help(
|
||||||
|
"Memory parameters \
|
||||||
#[argh(option, long = "disk")]
|
\"size=<guest_memory_size>,mergeable=on|off,shared=on|off,\
|
||||||
/// path=<disk_image_path>, readonly=on|off, direct=on|off, iommu=on|off, num_queues=<number_of_queues>, queue_size=<size_of_each_queue>, vhost_user=on|off, socket=<vhost_user_socket_path>, bw_size=<bytes>, bw_one_time_burst=<bytes>, bw_refill_time=<ms>, ops_size=<io_ops>, ops_one_time_burst=<io_ops>, ops_refill_time=<ms>, id=<device_id>, pci_segment=<segment_id>
|
hugepages=on|off,hugepage_size=<hugepage_size>,\
|
||||||
disk: Vec<String>,
|
hotplug_method=acpi|virtio-mem,\
|
||||||
|
hotplug_size=<hotpluggable_memory_size>,\
|
||||||
#[argh(option, long = "net")]
|
hotplugged_size=<hotplugged_memory_size>,\
|
||||||
/// tap=<if_name>, ip=<ip_addr>, mask=<net_mask>, mac=<mac_addr>, fd=<fd1,fd2...>, iommu=on|off, num_queues=<number_of_queues>, queue_size=<size_of_each_queue>, id=<device_id>, vhost_user=<vhost_user_enable>, socket=<vhost_user_socket_path>, vhost_mode=client|server, bw_size=<bytes>, bw_one_time_burst=<bytes>, bw_refill_time=<ms>, ops_size=<io_ops>, ops_one_time_burst=<io_ops>, ops_refill_time=<ms>, pci_segment=<segment_id>, offload_tso=on|off, offload_ufo=on|off, offload_csum=on|off
|
prefault=on|off,thp=on|off\"",
|
||||||
net: Vec<String>,
|
)
|
||||||
|
.default_value(default_memory)
|
||||||
#[argh(option, long = "rng", default = "default_rng()")]
|
.group("vm-config"),
|
||||||
/// src=<entropy_source_path>, iommu=on|off
|
)
|
||||||
rng: String,
|
.arg(
|
||||||
|
Arg::new("memory-zone")
|
||||||
#[argh(option, long = "balloon")]
|
.long("memory-zone")
|
||||||
/// size=<balloon_size>, deflate_on_oom=on|off, free_page_reporting=on|off
|
.help(
|
||||||
balloon: Option<String>,
|
"User defined memory zone parameters \
|
||||||
|
\"size=<guest_memory_region_size>,file=<backing_file>,\
|
||||||
#[argh(option, long = "fs")]
|
shared=on|off,\
|
||||||
/// tag=<tag_name>, socket=<socket_path>, num_queues=<number_of_queues>, queue_size=<size_of_each_queue>, id=<device_id>, pci_segment=<segment_id>
|
hugepages=on|off,hugepage_size=<hugepage_size>,\
|
||||||
fs: Vec<String>,
|
host_numa_node=<node_id>,\
|
||||||
|
id=<zone_identifier>,hotplug_size=<hotpluggable_memory_size>,\
|
||||||
#[argh(option, long = "pmem")]
|
hotplugged_size=<hotplugged_memory_size>,\
|
||||||
/// file=<backing_file_path>, size=<persistent_memory_size>, iommu=on|off, discard_writes=on|off, id=<device_id>, pci_segment=<segment_id>
|
prefault=on|off\"",
|
||||||
pmem: Vec<String>,
|
)
|
||||||
|
.num_args(1..)
|
||||||
#[argh(option, long = "serial", default = "String::from(\"null\")")]
|
.group("vm-config"),
|
||||||
/// off|null|pty|tty|file=/path/to/a/file
|
)
|
||||||
serial: String,
|
.arg(
|
||||||
|
Arg::new("firmware")
|
||||||
#[argh(option, long = "console", default = "String::from(\"tty\")")]
|
.long("firmware")
|
||||||
/// off|null|pty|tty|file=/path/to/a/file, iommu=on|off
|
.help("Path to firmware that is loaded in an architectural specific way")
|
||||||
console: String,
|
.num_args(1)
|
||||||
|
.group("vm-config"),
|
||||||
#[argh(option, long = "device")]
|
)
|
||||||
/// path=<device_path>, iommu=on|off, id=<device_id>, pci_segment=<segment_id>
|
.arg(
|
||||||
device: Vec<String>,
|
Arg::new("kernel")
|
||||||
|
.long("kernel")
|
||||||
#[argh(option, long = "user-device")]
|
.help(
|
||||||
/// socket=<socket_path>, id=<device_id>, pci_segment=<segment_id>
|
"Path to kernel to load. This may be a kernel or firmware that supports a PVH \
|
||||||
user_device: Vec<String>,
|
entry point (e.g. vmlinux) or architecture equivalent",
|
||||||
|
)
|
||||||
#[argh(option, long = "vdpa")]
|
.num_args(1)
|
||||||
/// path=<device_path>, num_queues=<number_of_queues>, iommu=on|off, id=<device_id>, pci_segment=<segment_id>
|
.group("vm-config"),
|
||||||
vdpa: Vec<String>,
|
)
|
||||||
|
.arg(
|
||||||
#[argh(option, long = "vsock")]
|
Arg::new("initramfs")
|
||||||
/// cid=<context_id>, socket=<socket_path>, iommu=on|off, id=<device_id>, pci_segment=<segment_id>
|
.long("initramfs")
|
||||||
vsock: Option<String>,
|
.help("Path to initramfs image")
|
||||||
|
.num_args(1)
|
||||||
#[argh(switch, long = "pvpanic")]
|
.group("vm-config"),
|
||||||
/// enable pvpanic device
|
)
|
||||||
pvpanic: bool,
|
.arg(
|
||||||
|
Arg::new("cmdline")
|
||||||
#[argh(option, long = "numa")]
|
.long("cmdline")
|
||||||
/// guest_numa_id=<node_id>, cpus=<cpus_id>, distances=<list_of_distances_to_destination_nodes>, memory_zones=<list_of_memory_zones>, sgx_epc_sections=<list_of_sgx_epc_sections>
|
.help("Kernel command line")
|
||||||
numa: Vec<String>,
|
.num_args(1)
|
||||||
|
.group("vm-config"),
|
||||||
#[argh(switch, long = "watchdog")]
|
)
|
||||||
/// enable virtio-watchdog
|
.arg(
|
||||||
watchdog: bool,
|
Arg::new("disk")
|
||||||
|
.long("disk")
|
||||||
#[argh(switch, short = 'v')]
|
.help(config::DiskConfig::SYNTAX)
|
||||||
/// set the level of debugging output
|
.num_args(1..)
|
||||||
verbosity: u8,
|
.group("vm-config"),
|
||||||
|
)
|
||||||
#[argh(option, long = "log-file")]
|
.arg(
|
||||||
/// path to log file
|
Arg::new("net")
|
||||||
log_file: Option<String>,
|
.long("net")
|
||||||
|
.help(config::NetConfig::SYNTAX)
|
||||||
#[argh(option, long = "api-socket")]
|
.num_args(1..)
|
||||||
/// path=<path/to/a/file>|fd=<fd>
|
.group("vm-config"),
|
||||||
api_socket: Option<String>,
|
)
|
||||||
|
.arg(
|
||||||
#[cfg(feature = "dbus_api")]
|
Arg::new("rng")
|
||||||
#[argh(option, long = "dbus-service-name")]
|
.long("rng")
|
||||||
/// well known name of the service
|
.help(
|
||||||
dbus_name: Option<String>,
|
"Random number generator parameters \"src=<entropy_source_path>,iommu=on|off\"",
|
||||||
|
)
|
||||||
#[cfg(feature = "dbus_api")]
|
.default_value(default_rng)
|
||||||
#[argh(option, long = "dbus-object-path")]
|
.group("vm-config"),
|
||||||
/// object path to serve the dbus interface
|
)
|
||||||
dbus_path: Option<String>,
|
.arg(
|
||||||
|
Arg::new("balloon")
|
||||||
#[cfg(feature = "dbus_api")]
|
.long("balloon")
|
||||||
#[argh(switch, long = "dbus-system-bus")]
|
.help(config::BalloonConfig::SYNTAX)
|
||||||
/// use the system bus instead of a session bus
|
.num_args(1)
|
||||||
dbus_system_bus: bool,
|
.group("vm-config"),
|
||||||
|
)
|
||||||
#[argh(option, long = "event-monitor")]
|
.arg(
|
||||||
/// path=<path/to/a/file>|fd=<fd>
|
Arg::new("fs")
|
||||||
event_monitor: Option<String>,
|
.long("fs")
|
||||||
|
.help(config::FsConfig::SYNTAX)
|
||||||
#[argh(option, long = "restore")]
|
.num_args(1..)
|
||||||
/// source_url=<source_url>, prefault=on|off
|
.group("vm-config"),
|
||||||
restore: Option<String>,
|
)
|
||||||
|
.arg(
|
||||||
#[argh(option, long = "seccomp", default = "String::from(\"true\")")]
|
Arg::new("pmem")
|
||||||
/// seccomp configuration (true, false or log)
|
.long("pmem")
|
||||||
seccomp: String,
|
.help(config::PmemConfig::SYNTAX)
|
||||||
|
.num_args(1..)
|
||||||
#[argh(option, long = "tpm")]
|
.group("vm-config"),
|
||||||
/// socket=<path/to/a/socket>
|
)
|
||||||
tpm: Option<String>,
|
.arg(
|
||||||
|
Arg::new("serial")
|
||||||
|
.long("serial")
|
||||||
|
.help("Control serial port: off|null|pty|tty|file=/path/to/a/file")
|
||||||
|
.default_value("null")
|
||||||
|
.group("vm-config"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("console")
|
||||||
|
.long("console")
|
||||||
|
.help(
|
||||||
|
"Control (virtio) console: \"off|null|pty|tty|file=/path/to/a/file,iommu=on|off\"",
|
||||||
|
)
|
||||||
|
.default_value("tty")
|
||||||
|
.group("vm-config"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("device")
|
||||||
|
.long("device")
|
||||||
|
.help(config::DeviceConfig::SYNTAX)
|
||||||
|
.num_args(1..)
|
||||||
|
.group("vm-config"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("user-device")
|
||||||
|
.long("user-device")
|
||||||
|
.help(config::UserDeviceConfig::SYNTAX)
|
||||||
|
.num_args(1..)
|
||||||
|
.group("vm-config"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("vdpa")
|
||||||
|
.long("vdpa")
|
||||||
|
.help(config::VdpaConfig::SYNTAX)
|
||||||
|
.num_args(1..)
|
||||||
|
.group("vm-config"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("vsock")
|
||||||
|
.long("vsock")
|
||||||
|
.help(config::VsockConfig::SYNTAX)
|
||||||
|
.num_args(1)
|
||||||
|
.group("vm-config"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("pvpanic")
|
||||||
|
.long("pvpanic")
|
||||||
|
.help("Enable pvpanic device")
|
||||||
|
.num_args(0)
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
|
.group("vm-config"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("numa")
|
||||||
|
.long("numa")
|
||||||
|
.help(config::NumaConfig::SYNTAX)
|
||||||
|
.num_args(1..)
|
||||||
|
.group("vm-config"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("watchdog")
|
||||||
|
.long("watchdog")
|
||||||
|
.help("Enable virtio-watchdog")
|
||||||
|
.num_args(0)
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
|
.group("vm-config"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("v")
|
||||||
|
.short('v')
|
||||||
|
.action(ArgAction::Count)
|
||||||
|
.help("Sets the level of debugging output")
|
||||||
|
.group("logging"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("log-file")
|
||||||
|
.long("log-file")
|
||||||
|
.help("Log file. Standard error is used if not specified")
|
||||||
|
.num_args(1)
|
||||||
|
.group("logging"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("api-socket")
|
||||||
|
.long("api-socket")
|
||||||
|
.help("HTTP API socket (UNIX domain socket): path=</path/to/a/file> or fd=<fd>.")
|
||||||
|
.num_args(1)
|
||||||
|
.group("vmm-config"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("event-monitor")
|
||||||
|
.long("event-monitor")
|
||||||
|
.help("File to report events on: path=</path/to/a/file> or fd=<fd>")
|
||||||
|
.num_args(1)
|
||||||
|
.group("vmm-config"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("restore")
|
||||||
|
.long("restore")
|
||||||
|
.help(config::RestoreConfig::SYNTAX)
|
||||||
|
.num_args(1)
|
||||||
|
.group("vmm-config"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("seccomp")
|
||||||
|
.long("seccomp")
|
||||||
|
.num_args(1)
|
||||||
|
.value_parser(["true", "false", "log"])
|
||||||
|
.default_value("true"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("tpm")
|
||||||
|
.long("tpm")
|
||||||
|
.num_args(1)
|
||||||
|
.help(config::TpmConfig::SYNTAX)
|
||||||
|
.group("vmm-config"),
|
||||||
|
);
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
#[argh(option, long = "sgx-epc")]
|
let app = app.arg(
|
||||||
/// id=<epc_section_identifier>, size=<epc_section_size>, prefault=on|off
|
Arg::new("sgx-epc")
|
||||||
sgx_epc: Vec<String>,
|
.long("sgx-epc")
|
||||||
|
.help(config::SgxEpcConfig::SYNTAX)
|
||||||
|
.num_args(1..)
|
||||||
|
.group("vm-config"),
|
||||||
|
);
|
||||||
|
|
||||||
#[cfg(feature = "guest_debug")]
|
#[cfg(feature = "guest_debug")]
|
||||||
#[argh(option, long = "gdb")]
|
let app = app.arg(
|
||||||
/// path=<path/to/a/file>
|
Arg::new("gdb")
|
||||||
gdb: Option<String>,
|
.long("gdb")
|
||||||
|
.help("GDB socket (UNIX domain socket): path=</path/to/a/file>")
|
||||||
|
.num_args(1)
|
||||||
|
.group("vmm-config"),
|
||||||
|
);
|
||||||
|
|
||||||
#[argh(switch, short = 'V', long = "version")]
|
#[cfg(feature = "dbus_api")]
|
||||||
/// print version information
|
let app = app
|
||||||
version: bool,
|
.arg(
|
||||||
|
Arg::new("dbus-service-name")
|
||||||
|
.long("dbus-service-name")
|
||||||
|
.help("Well known name of the device")
|
||||||
|
.num_args(1)
|
||||||
|
.group("vmm-config"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("dbus-object-path")
|
||||||
|
.long("dbus-object-path")
|
||||||
|
.help("Object path to serve the dbus interface")
|
||||||
|
.num_args(1)
|
||||||
|
.group("vmm-config"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("dbus-system-bus")
|
||||||
|
.long("dbus-system-bus")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
|
.help("Use the system bus instead of a session bus")
|
||||||
|
.num_args(0)
|
||||||
|
.group("vmm-config"),
|
||||||
|
);
|
||||||
|
|
||||||
|
app.arg(
|
||||||
|
Arg::new("version")
|
||||||
|
.short('V')
|
||||||
|
.long("version")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
|
.help("Print version")
|
||||||
|
.num_args(0),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TopLevel {
|
fn start_vmm(cmd_arguments: ArgMatches) -> Result<Option<String>, Error> {
|
||||||
fn to_vm_params(&self) -> config::VmParams<'_> {
|
let log_level = match cmd_arguments.get_count("v") {
|
||||||
let cpus = &self.cpus;
|
|
||||||
let memory = &self.memory;
|
|
||||||
let memory_zones = if !self.memory_zone.is_empty() {
|
|
||||||
Some(self.memory_zone.iter().map(|x| x.as_str()).collect())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let rng = &self.rng;
|
|
||||||
let serial = &self.serial;
|
|
||||||
let firmware = self.firmware.as_deref();
|
|
||||||
let kernel = self.kernel.as_deref();
|
|
||||||
let initramfs = self.initramfs.as_deref();
|
|
||||||
let cmdline = self.cmdline.as_deref();
|
|
||||||
|
|
||||||
let disks = if !self.disk.is_empty() {
|
|
||||||
Some(self.disk.iter().map(|x| x.as_str()).collect())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
let net = if !self.net.is_empty() {
|
|
||||||
Some(self.net.iter().map(|x| x.as_str()).collect())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
let console = &self.console;
|
|
||||||
let balloon = self.balloon.as_deref();
|
|
||||||
let fs = if !self.fs.is_empty() {
|
|
||||||
Some(self.fs.iter().map(|x| x.as_str()).collect())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
let pmem = if !self.pmem.is_empty() {
|
|
||||||
Some(self.pmem.iter().map(|x| x.as_str()).collect())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let devices = if !self.device.is_empty() {
|
|
||||||
Some(self.device.iter().map(|x| x.as_str()).collect())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let user_devices = if !self.user_device.is_empty() {
|
|
||||||
Some(self.user_device.iter().map(|x| x.as_str()).collect())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let vdpa = if !self.vdpa.is_empty() {
|
|
||||||
Some(self.vdpa.iter().map(|x| x.as_str()).collect())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
let vsock = self.vsock.as_deref();
|
|
||||||
|
|
||||||
let pvpanic = self.pvpanic;
|
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
|
||||||
let sgx_epc = if !self.sgx_epc.is_empty() {
|
|
||||||
Some(self.sgx_epc.iter().map(|x| x.as_str()).collect())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
let numa = if !self.numa.is_empty() {
|
|
||||||
Some(self.numa.iter().map(|x| x.as_str()).collect())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let watchdog = self.watchdog;
|
|
||||||
let platform = self.platform.as_deref();
|
|
||||||
#[cfg(feature = "guest_debug")]
|
|
||||||
let gdb = self.gdb.is_some();
|
|
||||||
let tpm = self.tpm.as_deref();
|
|
||||||
|
|
||||||
config::VmParams {
|
|
||||||
cpus,
|
|
||||||
memory,
|
|
||||||
memory_zones,
|
|
||||||
firmware,
|
|
||||||
kernel,
|
|
||||||
initramfs,
|
|
||||||
cmdline,
|
|
||||||
disks,
|
|
||||||
net,
|
|
||||||
rng,
|
|
||||||
balloon,
|
|
||||||
fs,
|
|
||||||
pmem,
|
|
||||||
serial,
|
|
||||||
console,
|
|
||||||
devices,
|
|
||||||
user_devices,
|
|
||||||
vdpa,
|
|
||||||
vsock,
|
|
||||||
pvpanic,
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
|
||||||
sgx_epc,
|
|
||||||
numa,
|
|
||||||
watchdog,
|
|
||||||
#[cfg(feature = "guest_debug")]
|
|
||||||
gdb,
|
|
||||||
platform,
|
|
||||||
tpm,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn start_vmm(toplevel: TopLevel) -> Result<Option<String>, Error> {
|
|
||||||
let log_level = match toplevel.verbosity {
|
|
||||||
0 => LevelFilter::Warn,
|
0 => LevelFilter::Warn,
|
||||||
1 => LevelFilter::Info,
|
1 => LevelFilter::Info,
|
||||||
2 => LevelFilter::Debug,
|
2 => LevelFilter::Debug,
|
||||||
_ => LevelFilter::Trace,
|
_ => LevelFilter::Trace,
|
||||||
};
|
};
|
||||||
|
|
||||||
let log_file: Box<dyn std::io::Write + Send> = if let Some(ref file) = toplevel.log_file {
|
let log_file: Box<dyn std::io::Write + Send> = if let Some(ref file) =
|
||||||
|
cmd_arguments.get_one::<String>("log-file")
|
||||||
|
{
|
||||||
Box::new(std::fs::File::create(std::path::Path::new(file)).map_err(Error::LogFileCreation)?)
|
Box::new(std::fs::File::create(std::path::Path::new(file)).map_err(Error::LogFileCreation)?)
|
||||||
} else {
|
} else {
|
||||||
Box::new(std::io::stderr())
|
Box::new(std::io::stderr())
|
||||||
@ -430,37 +477,47 @@ fn start_vmm(toplevel: TopLevel) -> Result<Option<String>, Error> {
|
|||||||
.map(|()| log::set_max_level(log_level))
|
.map(|()| log::set_max_level(log_level))
|
||||||
.map_err(Error::LoggerSetup)?;
|
.map_err(Error::LoggerSetup)?;
|
||||||
|
|
||||||
let (api_socket_path, api_socket_fd) = if let Some(ref socket_config) = toplevel.api_socket {
|
let (api_socket_path, api_socket_fd) =
|
||||||
let mut parser = OptionParser::new();
|
if let Some(socket_config) = cmd_arguments.get_one::<String>("api-socket") {
|
||||||
parser.add("path").add("fd");
|
let mut parser = OptionParser::new();
|
||||||
parser.parse(socket_config).unwrap_or_default();
|
parser.add("path").add("fd");
|
||||||
|
parser.parse(socket_config).unwrap_or_default();
|
||||||
|
|
||||||
if let Some(fd) = parser.get("fd") {
|
if let Some(fd) = parser.get("fd") {
|
||||||
(
|
(
|
||||||
None,
|
None,
|
||||||
Some(fd.parse::<RawFd>().map_err(Error::ParsingApiSocket)?),
|
Some(fd.parse::<RawFd>().map_err(Error::ParsingApiSocket)?),
|
||||||
)
|
)
|
||||||
} else if let Some(path) = parser.get("path") {
|
} else if let Some(path) = parser.get("path") {
|
||||||
(Some(path), None)
|
(Some(path), None)
|
||||||
|
} else {
|
||||||
|
(
|
||||||
|
cmd_arguments
|
||||||
|
.get_one::<String>("api-socket")
|
||||||
|
.map(|s| s.to_string()),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
(toplevel.api_socket.as_ref().map(|s| s.to_string()), None)
|
(None, None)
|
||||||
}
|
};
|
||||||
} else {
|
|
||||||
(None, None)
|
|
||||||
};
|
|
||||||
|
|
||||||
let (api_request_sender, api_request_receiver) = channel();
|
let (api_request_sender, api_request_receiver) = channel();
|
||||||
let api_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::CreateApiEventFd)?;
|
let api_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::CreateApiEventFd)?;
|
||||||
|
|
||||||
let api_request_sender_clone = api_request_sender.clone();
|
let api_request_sender_clone = api_request_sender.clone();
|
||||||
let seccomp_action = match &toplevel.seccomp as &str {
|
let seccomp_action = if let Some(seccomp_value) = cmd_arguments.get_one::<String>("seccomp") {
|
||||||
"true" => SeccompAction::Trap,
|
match seccomp_value as &str {
|
||||||
"false" => SeccompAction::Allow,
|
"true" => SeccompAction::Trap,
|
||||||
"log" => SeccompAction::Log,
|
"false" => SeccompAction::Allow,
|
||||||
val => {
|
"log" => SeccompAction::Log,
|
||||||
// The user providing an invalid value will be rejected
|
val => {
|
||||||
panic!("Invalid parameter {val} for \"--seccomp\" flag");
|
// The user providing an invalid value will be rejected
|
||||||
|
panic!("Invalid parameter {val} for \"--seccomp\" flag");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
SeccompAction::Trap
|
||||||
};
|
};
|
||||||
|
|
||||||
if seccomp_action == SeccompAction::Trap {
|
if seccomp_action == SeccompAction::Trap {
|
||||||
@ -498,7 +555,7 @@ fn start_vmm(toplevel: TopLevel) -> Result<Option<String>, Error> {
|
|||||||
let hypervisor = hypervisor::new().map_err(Error::CreateHypervisor)?;
|
let hypervisor = hypervisor::new().map_err(Error::CreateHypervisor)?;
|
||||||
|
|
||||||
#[cfg(feature = "guest_debug")]
|
#[cfg(feature = "guest_debug")]
|
||||||
let gdb_socket_path = if let Some(ref gdb_config) = toplevel.gdb {
|
let gdb_socket_path = if let Some(gdb_config) = cmd_arguments.get_one::<String>("gdb") {
|
||||||
let mut parser = OptionParser::new();
|
let mut parser = OptionParser::new();
|
||||||
parser.add("path");
|
parser.add("path");
|
||||||
parser.parse(gdb_config).map_err(Error::ParsingGdb)?;
|
parser.parse(gdb_config).map_err(Error::ParsingGdb)?;
|
||||||
@ -519,8 +576,8 @@ fn start_vmm(toplevel: TopLevel) -> Result<Option<String>, Error> {
|
|||||||
let exit_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::CreateExitEventFd)?;
|
let exit_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::CreateExitEventFd)?;
|
||||||
|
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
let mut event_monitor = toplevel
|
let mut event_monitor = cmd_arguments
|
||||||
.event_monitor
|
.get_one::<String>("event-monitor")
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|monitor_config| {
|
.map(|monitor_config| {
|
||||||
let mut parser = OptionParser::new();
|
let mut parser = OptionParser::new();
|
||||||
@ -555,8 +612,11 @@ fn start_vmm(toplevel: TopLevel) -> Result<Option<String>, Error> {
|
|||||||
.transpose()?;
|
.transpose()?;
|
||||||
|
|
||||||
#[cfg(feature = "dbus_api")]
|
#[cfg(feature = "dbus_api")]
|
||||||
let dbus_options = match (&toplevel.dbus_name, &toplevel.dbus_path) {
|
let dbus_options = match (
|
||||||
(Some(ref name), Some(ref path)) => {
|
cmd_arguments.get_one::<String>("dbus-service-name"),
|
||||||
|
cmd_arguments.get_one::<String>("dbus-object-path"),
|
||||||
|
) {
|
||||||
|
(Some(name), Some(path)) => {
|
||||||
// monitor is either set (file based) or not.
|
// monitor is either set (file based) or not.
|
||||||
// if it's not set, create one without file support.
|
// if it's not set, create one without file support.
|
||||||
let mut monitor = match event_monitor.take() {
|
let mut monitor = match event_monitor.take() {
|
||||||
@ -564,9 +624,9 @@ fn start_vmm(toplevel: TopLevel) -> Result<Option<String>, Error> {
|
|||||||
None => event_monitor::set_monitor(None).map_err(Error::EventMonitorIo)?,
|
None => event_monitor::set_monitor(None).map_err(Error::EventMonitorIo)?,
|
||||||
};
|
};
|
||||||
let options = DBusApiOptions {
|
let options = DBusApiOptions {
|
||||||
service_name: name.to_owned(),
|
service_name: name.to_string(),
|
||||||
object_path: path.to_owned(),
|
object_path: path.to_string(),
|
||||||
system_bus: toplevel.dbus_system_bus,
|
system_bus: cmd_arguments.get_flag("dbus-system-bus"),
|
||||||
event_monitor_rx: monitor.subscribe(),
|
event_monitor_rx: monitor.subscribe(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -612,10 +672,11 @@ fn start_vmm(toplevel: TopLevel) -> Result<Option<String>, Error> {
|
|||||||
.map_err(Error::StartVmmThread)?;
|
.map_err(Error::StartVmmThread)?;
|
||||||
|
|
||||||
let r: Result<(), Error> = (|| {
|
let r: Result<(), Error> = (|| {
|
||||||
let payload_present = toplevel.kernel.is_some() || toplevel.firmware.is_some();
|
let payload_present =
|
||||||
|
cmd_arguments.contains_id("kernel") || cmd_arguments.contains_id("firmware");
|
||||||
|
|
||||||
if payload_present {
|
if payload_present {
|
||||||
let vm_params = toplevel.to_vm_params();
|
let vm_params = config::VmParams::from_arg_matches(&cmd_arguments);
|
||||||
let vm_config = config::VmConfig::parse(vm_params).map_err(Error::ParsingConfig)?;
|
let vm_config = config::VmConfig::parse(vm_params).map_err(Error::ParsingConfig)?;
|
||||||
|
|
||||||
// Create and boot the VM based off the VM config we just built.
|
// Create and boot the VM based off the VM config we just built.
|
||||||
@ -627,12 +688,12 @@ fn start_vmm(toplevel: TopLevel) -> Result<Option<String>, Error> {
|
|||||||
)
|
)
|
||||||
.map_err(Error::VmCreate)?;
|
.map_err(Error::VmCreate)?;
|
||||||
vmm::api::vm_boot(api_evt.try_clone().unwrap(), sender).map_err(Error::VmBoot)?;
|
vmm::api::vm_boot(api_evt.try_clone().unwrap(), sender).map_err(Error::VmBoot)?;
|
||||||
} else if let Some(restore_params) = toplevel.restore {
|
} else if let Some(restore_params) = cmd_arguments.get_one::<String>("restore") {
|
||||||
vmm::api::vm_restore(
|
vmm::api::vm_restore(
|
||||||
api_evt.try_clone().unwrap(),
|
api_evt.try_clone().unwrap(),
|
||||||
api_request_sender,
|
api_request_sender,
|
||||||
Arc::new(
|
Arc::new(
|
||||||
config::RestoreConfig::parse(&restore_params).map_err(Error::ParsingRestore)?,
|
config::RestoreConfig::parse(restore_params).map_err(Error::ParsingRestore)?,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.map_err(Error::VmRestore)?;
|
.map_err(Error::VmRestore)?;
|
||||||
@ -672,19 +733,20 @@ fn main() {
|
|||||||
// SAFETY: trivially safe
|
// SAFETY: trivially safe
|
||||||
let _ = unsafe { libc::umask(0o077) };
|
let _ = unsafe { libc::umask(0o077) };
|
||||||
|
|
||||||
let toplevel: TopLevel = argh::from_env();
|
let (default_vcpus, default_memory, default_rng) = prepare_default_values();
|
||||||
|
let cmd_arguments = create_app(default_vcpus, default_memory, default_rng).get_matches();
|
||||||
|
|
||||||
if toplevel.version {
|
if cmd_arguments.get_flag("version") {
|
||||||
println!("{} {}", env!("CARGO_BIN_NAME"), env!("BUILD_VERSION"));
|
println!("{} {}", env!("CARGO_BIN_NAME"), env!("BUILD_VERSION"));
|
||||||
|
|
||||||
if toplevel.verbosity != 0 {
|
if cmd_arguments.get_count("v") != 0 {
|
||||||
println!("Enabled features: {:?}", vmm::feature_list());
|
println!("Enabled features: {:?}", vmm::feature_list());
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let exit_code = match start_vmm(toplevel) {
|
let exit_code = match start_vmm(cmd_arguments) {
|
||||||
Ok(path) => {
|
Ok(path) => {
|
||||||
path.map(|s| std::fs::remove_file(s).ok());
|
path.map(|s| std::fs::remove_file(s).ok());
|
||||||
0
|
0
|
||||||
@ -704,45 +766,18 @@ fn main() {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod unit_tests {
|
mod unit_tests {
|
||||||
use crate::config::HotplugMethod;
|
use crate::config::HotplugMethod;
|
||||||
use crate::TopLevel;
|
use crate::{create_app, prepare_default_values};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use vmm::config::{
|
use vmm::config::{
|
||||||
ConsoleConfig, ConsoleOutputMode, CpuFeatures, CpusConfig, MemoryConfig, PayloadConfig,
|
ConsoleConfig, ConsoleOutputMode, CpuFeatures, CpusConfig, MemoryConfig, PayloadConfig,
|
||||||
RngConfig, VmConfig,
|
RngConfig, VmConfig, VmParams,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Taken from argh
|
|
||||||
fn cmd<'a>(default: &'a str, path: &'a str) -> &'a str {
|
|
||||||
std::path::Path::new(path)
|
|
||||||
.file_name()
|
|
||||||
.and_then(|s| s.to_str())
|
|
||||||
.unwrap_or(default)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Some code taken from argh since it does not provide a helper to parse arbitrary strings
|
|
||||||
fn get_vm_config_from_vec(args: &[&str]) -> VmConfig {
|
fn get_vm_config_from_vec(args: &[&str]) -> VmConfig {
|
||||||
let strings: Vec<String> = args.iter().map(|x| x.to_string()).collect();
|
let (default_vcpus, default_memory, default_rng) = prepare_default_values();
|
||||||
let cmd = cmd(&strings[0], &strings[0]);
|
let cmd_arguments =
|
||||||
let strs: Vec<&str> = strings.iter().map(|s| s.as_str()).collect();
|
create_app(default_vcpus, default_memory, default_rng).get_matches_from(args);
|
||||||
let toplevel = <TopLevel as argh::FromArgs>::from_args(&[cmd], &strs[1..]).unwrap_or_else(
|
let vm_params = VmParams::from_arg_matches(&cmd_arguments);
|
||||||
|early_exit| {
|
|
||||||
std::process::exit(match early_exit.status {
|
|
||||||
Ok(()) => {
|
|
||||||
println!("{}", early_exit.output);
|
|
||||||
0
|
|
||||||
}
|
|
||||||
Err(()) => {
|
|
||||||
eprintln!(
|
|
||||||
"{}\nRun {} --help for more information.",
|
|
||||||
early_exit.output, cmd
|
|
||||||
);
|
|
||||||
1
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
let vm_params = toplevel.to_vm_params();
|
|
||||||
|
|
||||||
VmConfig::parse(vm_params).unwrap()
|
VmConfig::parse(vm_params).unwrap()
|
||||||
}
|
}
|
||||||
@ -1005,7 +1040,6 @@ mod unit_tests {
|
|||||||
"/path/to/kernel",
|
"/path/to/kernel",
|
||||||
"--disk",
|
"--disk",
|
||||||
"path=/path/to/disk/1",
|
"path=/path/to/disk/1",
|
||||||
"--disk",
|
|
||||||
"path=/path/to/disk/2",
|
"path=/path/to/disk/2",
|
||||||
],
|
],
|
||||||
r#"{
|
r#"{
|
||||||
@ -1024,7 +1058,6 @@ mod unit_tests {
|
|||||||
"/path/to/kernel",
|
"/path/to/kernel",
|
||||||
"--disk",
|
"--disk",
|
||||||
"path=/path/to/disk/1",
|
"path=/path/to/disk/1",
|
||||||
"--disk",
|
|
||||||
"path=/path/to/disk/2",
|
"path=/path/to/disk/2",
|
||||||
],
|
],
|
||||||
r#"{
|
r#"{
|
||||||
@ -1299,7 +1332,6 @@ mod unit_tests {
|
|||||||
"--memory", "shared=true",
|
"--memory", "shared=true",
|
||||||
"--fs",
|
"--fs",
|
||||||
"tag=virtiofs1,socket=/path/to/sock1",
|
"tag=virtiofs1,socket=/path/to/sock1",
|
||||||
"--fs",
|
|
||||||
"tag=virtiofs2,socket=/path/to/sock2",
|
"tag=virtiofs2,socket=/path/to/sock2",
|
||||||
],
|
],
|
||||||
r#"{
|
r#"{
|
||||||
@ -1318,7 +1350,6 @@ mod unit_tests {
|
|||||||
"--memory", "shared=true",
|
"--memory", "shared=true",
|
||||||
"--fs",
|
"--fs",
|
||||||
"tag=virtiofs1,socket=/path/to/sock1",
|
"tag=virtiofs1,socket=/path/to/sock1",
|
||||||
"--fs",
|
|
||||||
"tag=virtiofs2,socket=/path/to/sock2",
|
"tag=virtiofs2,socket=/path/to/sock2",
|
||||||
],
|
],
|
||||||
r#"{
|
r#"{
|
||||||
@ -1380,7 +1411,6 @@ mod unit_tests {
|
|||||||
"/path/to/kernel",
|
"/path/to/kernel",
|
||||||
"--pmem",
|
"--pmem",
|
||||||
"file=/path/to/img/1,size=1G",
|
"file=/path/to/img/1,size=1G",
|
||||||
"--pmem",
|
|
||||||
"file=/path/to/img/2,size=2G",
|
"file=/path/to/img/2,size=2G",
|
||||||
],
|
],
|
||||||
r#"{
|
r#"{
|
||||||
@ -1547,7 +1577,6 @@ mod unit_tests {
|
|||||||
"/path/to/kernel",
|
"/path/to/kernel",
|
||||||
"--device",
|
"--device",
|
||||||
"path=/path/to/device/1",
|
"path=/path/to/device/1",
|
||||||
"--device",
|
|
||||||
"path=/path/to/device/2",
|
"path=/path/to/device/2",
|
||||||
],
|
],
|
||||||
r#"{
|
r#"{
|
||||||
@ -1566,7 +1595,6 @@ mod unit_tests {
|
|||||||
"/path/to/kernel",
|
"/path/to/kernel",
|
||||||
"--device",
|
"--device",
|
||||||
"path=/path/to/device/1",
|
"path=/path/to/device/1",
|
||||||
"--device",
|
|
||||||
"path=/path/to/device/2",
|
"path=/path/to/device/2",
|
||||||
],
|
],
|
||||||
r#"{
|
r#"{
|
||||||
@ -1643,7 +1671,6 @@ mod unit_tests {
|
|||||||
"/path/to/kernel",
|
"/path/to/kernel",
|
||||||
"--vdpa",
|
"--vdpa",
|
||||||
"path=/path/to/device/1",
|
"path=/path/to/device/1",
|
||||||
"--vdpa",
|
|
||||||
"path=/path/to/device/2,num_queues=2",
|
"path=/path/to/device/2,num_queues=2",
|
||||||
],
|
],
|
||||||
r#"{
|
r#"{
|
||||||
@ -1662,7 +1689,6 @@ mod unit_tests {
|
|||||||
"/path/to/kernel",
|
"/path/to/kernel",
|
||||||
"--vdpa",
|
"--vdpa",
|
||||||
"path=/path/to/device/1",
|
"path=/path/to/device/1",
|
||||||
"--vdpa",
|
|
||||||
"path=/path/to/device/2",
|
"path=/path/to/device/2",
|
||||||
],
|
],
|
||||||
r#"{
|
r#"{
|
||||||
|
@ -47,7 +47,7 @@ write_files:
|
|||||||
# 1G ram requires 512 pages
|
# 1G ram requires 512 pages
|
||||||
echo 512 | sudo tee /proc/sys/vm/nr_hugepages
|
echo 512 | sudo tee /proc/sys/vm/nr_hugepages
|
||||||
sudo chmod a+rwX /dev/hugepages
|
sudo chmod a+rwX /dev/hugepages
|
||||||
/mnt/cloud-hypervisor --kernel /mnt/vmlinux --cmdline "console=hvc0 reboot=k panic=1 nomodules root=/dev/vda1 VFIOTAG" --disk path=/mnt/focal-server-cloudimg-amd64-custom-20210609-0.raw --disk path=/mnt/cloudinit.img --cpus boot=1 --memory size=512M,hotplug_size=1G,hugepages=on --device path=/sys/bus/pci/devices/0000:00:05.0/ --device path=/sys/bus/pci/devices/0000:00:07.0/ --device path=/sys/bus/pci/devices/0000:00:08.0/ --api-socket /tmp/ch_api.sock
|
/mnt/cloud-hypervisor --kernel /mnt/vmlinux --cmdline "console=hvc0 reboot=k panic=1 nomodules root=/dev/vda1 VFIOTAG" --disk path=/mnt/focal-server-cloudimg-amd64-custom-20210609-0.raw path=/mnt/cloudinit.img --cpus boot=1 --memory size=512M,hotplug_size=1G,hugepages=on --device path=/sys/bus/pci/devices/0000:00:05.0/ path=/sys/bus/pci/devices/0000:00:07.0/ path=/sys/bus/pci/devices/0000:00:08.0/ --api-socket=/tmp/ch_api.sock
|
||||||
|
|
||||||
-
|
-
|
||||||
path: /etc/systemd/system/notify-booted.service
|
path: /etc/systemd/system/notify-booted.service
|
||||||
|
@ -1152,7 +1152,7 @@ impl ToString for VerbosityLevel {
|
|||||||
match self {
|
match self {
|
||||||
Warn => "".to_string(),
|
Warn => "".to_string(),
|
||||||
Info => "-v".to_string(),
|
Info => "-v".to_string(),
|
||||||
Debug => "-v -v".to_string(),
|
Debug => "-vv".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1203,7 +1203,7 @@ impl<'a> GuestCommand<'a> {
|
|||||||
self.command.arg("-v");
|
self.command.arg("-v");
|
||||||
}
|
}
|
||||||
Debug => {
|
Debug => {
|
||||||
self.command.args(["-v", "-v"]);
|
self.command.args(["-vv"]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1271,7 +1271,6 @@ impl<'a> GuestCommand<'a> {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--disk",
|
|
||||||
format!(
|
format!(
|
||||||
"path={}",
|
"path={}",
|
||||||
self.guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
self.guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
||||||
|
@ -102,23 +102,21 @@ impl TargetApi {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn guest_args(&self) -> Vec<&str> {
|
fn guest_args(&self) -> Vec<String> {
|
||||||
match self {
|
match self {
|
||||||
TargetApi::HttpApi(api_socket) => {
|
TargetApi::HttpApi(api_socket) => {
|
||||||
vec!["--api-socket", api_socket.as_str()]
|
vec![format!("--api-socket={}", api_socket.as_str())]
|
||||||
}
|
}
|
||||||
TargetApi::DBusApi(service_name, object_path) => {
|
TargetApi::DBusApi(service_name, object_path) => {
|
||||||
vec![
|
vec![
|
||||||
"--dbus-service-name",
|
format!("--dbus-service-name={}", service_name.as_str()),
|
||||||
service_name.as_str(),
|
format!("--dbus-object-path={}", object_path.as_str()),
|
||||||
"--dbus-object-path",
|
|
||||||
object_path.as_str(),
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remote_args(&self) -> Vec<&str> {
|
fn remote_args(&self) -> Vec<String> {
|
||||||
// `guest_args` and `remote_args` are consistent with each other
|
// `guest_args` and `remote_args` are consistent with each other
|
||||||
self.guest_args()
|
self.guest_args()
|
||||||
}
|
}
|
||||||
@ -625,7 +623,7 @@ fn prepare_swtpm_daemon(tmp_dir: &TempDir) -> (std::process::Command, String) {
|
|||||||
|
|
||||||
fn remote_command(api_socket: &str, command: &str, arg: Option<&str>) -> bool {
|
fn remote_command(api_socket: &str, command: &str, arg: Option<&str>) -> bool {
|
||||||
let mut cmd = Command::new(clh_command("ch-remote"));
|
let mut cmd = Command::new(clh_command("ch-remote"));
|
||||||
cmd.args(["--api-socket", api_socket, command]);
|
cmd.args([&format!("--api-socket={api_socket}"), command]);
|
||||||
|
|
||||||
if let Some(arg) = arg {
|
if let Some(arg) = arg {
|
||||||
cmd.arg(arg);
|
cmd.arg(arg);
|
||||||
@ -643,7 +641,7 @@ fn remote_command(api_socket: &str, command: &str, arg: Option<&str>) -> bool {
|
|||||||
|
|
||||||
fn remote_command_w_output(api_socket: &str, command: &str, arg: Option<&str>) -> (bool, Vec<u8>) {
|
fn remote_command_w_output(api_socket: &str, command: &str, arg: Option<&str>) -> (bool, Vec<u8>) {
|
||||||
let mut cmd = Command::new(clh_command("ch-remote"));
|
let mut cmd = Command::new(clh_command("ch-remote"));
|
||||||
cmd.args(["--api-socket", api_socket, command]);
|
cmd.args([&format!("--api-socket={api_socket}"), command]);
|
||||||
|
|
||||||
if let Some(arg) = arg {
|
if let Some(arg) = arg {
|
||||||
cmd.arg(arg);
|
cmd.arg(arg);
|
||||||
@ -662,18 +660,18 @@ fn resize_command(
|
|||||||
event_file: Option<&str>,
|
event_file: Option<&str>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut cmd = Command::new(clh_command("ch-remote"));
|
let mut cmd = Command::new(clh_command("ch-remote"));
|
||||||
cmd.args(["--api-socket", api_socket, "resize"]);
|
cmd.args([&format!("--api-socket={api_socket}"), "resize"]);
|
||||||
|
|
||||||
if let Some(desired_vcpus) = desired_vcpus {
|
if let Some(desired_vcpus) = desired_vcpus {
|
||||||
cmd.args(["--cpus", &format!("{desired_vcpus}")]);
|
cmd.arg(format!("--cpus={desired_vcpus}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(desired_ram) = desired_ram {
|
if let Some(desired_ram) = desired_ram {
|
||||||
cmd.args(["--memory", &format!("{desired_ram}")]);
|
cmd.arg(format!("--memory={desired_ram}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(desired_balloon) = desired_balloon {
|
if let Some(desired_balloon) = desired_balloon {
|
||||||
cmd.args(["--balloon", &format!("{desired_balloon}")]);
|
cmd.arg(format!("--balloon={desired_balloon}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let ret = cmd.status().expect("Failed to launch ch-remote").success();
|
let ret = cmd.status().expect("Failed to launch ch-remote").success();
|
||||||
@ -698,13 +696,10 @@ fn resize_command(
|
|||||||
fn resize_zone_command(api_socket: &str, id: &str, desired_size: &str) -> bool {
|
fn resize_zone_command(api_socket: &str, id: &str, desired_size: &str) -> bool {
|
||||||
let mut cmd = Command::new(clh_command("ch-remote"));
|
let mut cmd = Command::new(clh_command("ch-remote"));
|
||||||
cmd.args([
|
cmd.args([
|
||||||
"--api-socket",
|
&format!("--api-socket={api_socket}"),
|
||||||
api_socket,
|
|
||||||
"resize-zone",
|
"resize-zone",
|
||||||
"--id",
|
&format!("--id={id}"),
|
||||||
id,
|
&format!("--size={desired_size}"),
|
||||||
"--size",
|
|
||||||
desired_size,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
cmd.status().expect("Failed to launch ch-remote").success()
|
cmd.status().expect("Failed to launch ch-remote").success()
|
||||||
@ -757,7 +752,7 @@ fn setup_ovs_dpdk_guests(
|
|||||||
.args(["--kernel", direct_kernel_boot_path().to_str().unwrap()])
|
.args(["--kernel", direct_kernel_boot_path().to_str().unwrap()])
|
||||||
.args(["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE])
|
.args(["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE])
|
||||||
.default_disks()
|
.default_disks()
|
||||||
.args(["--net", guest1.default_net_string().as_str(), "--net", "vhost_user=true,socket=/tmp/dpdkvhostclient1,num_queues=2,queue_size=256,vhost_mode=server"])
|
.args(["--net", guest1.default_net_string().as_str(), "vhost_user=true,socket=/tmp/dpdkvhostclient1,num_queues=2,queue_size=256,vhost_mode=server"])
|
||||||
.capture_output()
|
.capture_output()
|
||||||
.spawn()
|
.spawn()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -807,7 +802,7 @@ fn setup_ovs_dpdk_guests(
|
|||||||
.args(["--kernel", direct_kernel_boot_path().to_str().unwrap()])
|
.args(["--kernel", direct_kernel_boot_path().to_str().unwrap()])
|
||||||
.args(["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE])
|
.args(["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE])
|
||||||
.default_disks()
|
.default_disks()
|
||||||
.args(["--net", guest2.default_net_string().as_str(), "--net", "vhost_user=true,socket=/tmp/dpdkvhostclient2,num_queues=2,queue_size=256,vhost_mode=server"])
|
.args(["--net", guest2.default_net_string().as_str(), "vhost_user=true,socket=/tmp/dpdkvhostclient2,num_queues=2,queue_size=256,vhost_mode=server"])
|
||||||
.capture_output()
|
.capture_output()
|
||||||
.spawn()
|
.spawn()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -1040,17 +1035,13 @@ fn _test_guest_numa_nodes(acpi: bool) {
|
|||||||
.args([
|
.args([
|
||||||
"--memory-zone",
|
"--memory-zone",
|
||||||
"id=mem0,size=1G,hotplug_size=3G",
|
"id=mem0,size=1G,hotplug_size=3G",
|
||||||
"--memory-zone",
|
|
||||||
"id=mem1,size=2G,hotplug_size=3G",
|
"id=mem1,size=2G,hotplug_size=3G",
|
||||||
"--memory-zone",
|
|
||||||
"id=mem2,size=3G,hotplug_size=3G",
|
"id=mem2,size=3G,hotplug_size=3G",
|
||||||
])
|
])
|
||||||
.args([
|
.args([
|
||||||
"--numa",
|
"--numa",
|
||||||
"guest_numa_id=0,cpus=[0-2,9],distances=[1@15,2@20],memory_zones=mem0",
|
"guest_numa_id=0,cpus=[0-2,9],distances=[1@15,2@20],memory_zones=mem0",
|
||||||
"--numa",
|
|
||||||
"guest_numa_id=1,cpus=[3-4,6-8],distances=[0@20,2@25],memory_zones=mem1",
|
"guest_numa_id=1,cpus=[3-4,6-8],distances=[0@20,2@25],memory_zones=mem1",
|
||||||
"--numa",
|
|
||||||
"guest_numa_id=2,cpus=[5,10-11],distances=[0@25,1@30],memory_zones=mem2",
|
"guest_numa_id=2,cpus=[5,10-11],distances=[0@25,1@30],memory_zones=mem2",
|
||||||
])
|
])
|
||||||
.args(["--kernel", kernel_path.to_str().unwrap()])
|
.args(["--kernel", kernel_path.to_str().unwrap()])
|
||||||
@ -1353,13 +1344,11 @@ fn test_vhost_user_blk(
|
|||||||
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
|
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--disk",
|
|
||||||
format!(
|
format!(
|
||||||
"path={}",
|
"path={}",
|
||||||
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--disk",
|
|
||||||
blk_params.as_str(),
|
blk_params.as_str(),
|
||||||
])
|
])
|
||||||
.default_net()
|
.default_net()
|
||||||
@ -1499,7 +1488,6 @@ fn test_boot_from_vhost_user_blk(
|
|||||||
.args([
|
.args([
|
||||||
"--disk",
|
"--disk",
|
||||||
blk_boot_params.as_str(),
|
blk_boot_params.as_str(),
|
||||||
"--disk",
|
|
||||||
format!(
|
format!(
|
||||||
"path={}",
|
"path={}",
|
||||||
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
||||||
@ -2195,7 +2183,6 @@ fn _test_virtio_iommu(acpi: bool) {
|
|||||||
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
|
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--disk",
|
|
||||||
format!(
|
format!(
|
||||||
"path={},iommu=on",
|
"path={},iommu=on",
|
||||||
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
||||||
@ -2617,9 +2604,7 @@ mod common_parallel {
|
|||||||
.args([
|
.args([
|
||||||
"--memory-zone",
|
"--memory-zone",
|
||||||
"id=mem0,size=1G,hotplug_size=2G",
|
"id=mem0,size=1G,hotplug_size=2G",
|
||||||
"--memory-zone",
|
|
||||||
"id=mem1,size=1G,shared=on",
|
"id=mem1,size=1G,shared=on",
|
||||||
"--memory-zone",
|
|
||||||
"id=mem2,size=1G,host_numa_node=0,hotplug_size=2G",
|
"id=mem2,size=1G,host_numa_node=0,hotplug_size=2G",
|
||||||
])
|
])
|
||||||
.args(["--kernel", kernel_path.to_str().unwrap()])
|
.args(["--kernel", kernel_path.to_str().unwrap()])
|
||||||
@ -2876,13 +2861,11 @@ mod common_parallel {
|
|||||||
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
|
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--disk",
|
|
||||||
format!(
|
format!(
|
||||||
"path={}",
|
"path={}",
|
||||||
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--disk",
|
|
||||||
format!("path={test_disk_path},pci_segment=15").as_str(),
|
format!("path={test_disk_path},pci_segment=15").as_str(),
|
||||||
])
|
])
|
||||||
.capture_output()
|
.capture_output()
|
||||||
@ -3103,13 +3086,11 @@ mod common_parallel {
|
|||||||
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
|
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--disk",
|
|
||||||
format!(
|
format!(
|
||||||
"path={}",
|
"path={}",
|
||||||
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--disk",
|
|
||||||
format!(
|
format!(
|
||||||
"path={},readonly=on,direct=on,num_queues=4,_disable_io_uring={}",
|
"path={},readonly=on,direct=on,num_queues=4,_disable_io_uring={}",
|
||||||
blk_file_path.to_str().unwrap(),
|
blk_file_path.to_str().unwrap(),
|
||||||
@ -3276,13 +3257,11 @@ mod common_parallel {
|
|||||||
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
|
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--disk",
|
|
||||||
format!(
|
format!(
|
||||||
"path={}",
|
"path={}",
|
||||||
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--disk",
|
|
||||||
format!("path={vhdx_path}").as_str(),
|
format!("path={vhdx_path}").as_str(),
|
||||||
])
|
])
|
||||||
.default_net()
|
.default_net()
|
||||||
@ -3352,7 +3331,6 @@ mod common_parallel {
|
|||||||
.args([
|
.args([
|
||||||
"--disk",
|
"--disk",
|
||||||
format!("path={},direct=on", os_path.as_path().to_str().unwrap()).as_str(),
|
format!("path={},direct=on", os_path.as_path().to_str().unwrap()).as_str(),
|
||||||
"--disk",
|
|
||||||
format!(
|
format!(
|
||||||
"path={}",
|
"path={}",
|
||||||
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
||||||
@ -3730,9 +3708,7 @@ mod common_parallel {
|
|||||||
.args([
|
.args([
|
||||||
"--net",
|
"--net",
|
||||||
guest.default_net_string().as_str(),
|
guest.default_net_string().as_str(),
|
||||||
"--net",
|
|
||||||
"tap=,mac=8a:6b:6f:5a:de:ac,ip=192.168.3.1,mask=255.255.255.0",
|
"tap=,mac=8a:6b:6f:5a:de:ac,ip=192.168.3.1,mask=255.255.255.0",
|
||||||
"--net",
|
|
||||||
"tap=mytap1,mac=fe:1f:9e:e1:60:f2,ip=192.168.4.1,mask=255.255.255.0",
|
"tap=mytap1,mac=fe:1f:9e:e1:60:f2,ip=192.168.4.1,mask=255.255.255.0",
|
||||||
])
|
])
|
||||||
.capture_output()
|
.capture_output()
|
||||||
@ -4294,15 +4270,12 @@ mod common_parallel {
|
|||||||
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
|
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--disk",
|
|
||||||
format!(
|
format!(
|
||||||
"path={}",
|
"path={}",
|
||||||
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--disk",
|
|
||||||
format!("path={}", vfio_disk_path.to_str().unwrap()).as_str(),
|
format!("path={}", vfio_disk_path.to_str().unwrap()).as_str(),
|
||||||
"--disk",
|
|
||||||
format!("path={},iommu=on", blk_file_path.to_str().unwrap()).as_str(),
|
format!("path={},iommu=on", blk_file_path.to_str().unwrap()).as_str(),
|
||||||
])
|
])
|
||||||
.args([
|
.args([
|
||||||
@ -4315,19 +4288,16 @@ mod common_parallel {
|
|||||||
.args([
|
.args([
|
||||||
"--net",
|
"--net",
|
||||||
format!("tap={},mac={}", vfio_tap0, guest.network.guest_mac).as_str(),
|
format!("tap={},mac={}", vfio_tap0, guest.network.guest_mac).as_str(),
|
||||||
"--net",
|
|
||||||
format!(
|
format!(
|
||||||
"tap={},mac={},iommu=on",
|
"tap={},mac={},iommu=on",
|
||||||
vfio_tap1, guest.network.l2_guest_mac1
|
vfio_tap1, guest.network.l2_guest_mac1
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--net",
|
|
||||||
format!(
|
format!(
|
||||||
"tap={},mac={},iommu=on",
|
"tap={},mac={},iommu=on",
|
||||||
vfio_tap2, guest.network.l2_guest_mac2
|
vfio_tap2, guest.network.l2_guest_mac2
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--net",
|
|
||||||
format!(
|
format!(
|
||||||
"tap={},mac={},iommu=on",
|
"tap={},mac={},iommu=on",
|
||||||
vfio_tap3, guest.network.l2_guest_mac3
|
vfio_tap3, guest.network.l2_guest_mac3
|
||||||
@ -4405,7 +4375,7 @@ mod common_parallel {
|
|||||||
let vfio_hotplug_output = guest
|
let vfio_hotplug_output = guest
|
||||||
.ssh_command_l1(
|
.ssh_command_l1(
|
||||||
"sudo /mnt/ch-remote \
|
"sudo /mnt/ch-remote \
|
||||||
--api-socket /tmp/ch_api.sock \
|
--api-socket=/tmp/ch_api.sock \
|
||||||
add-device path=/sys/bus/pci/devices/0000:00:09.0,id=vfio123",
|
add-device path=/sys/bus/pci/devices/0000:00:09.0,id=vfio123",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -4445,7 +4415,7 @@ mod common_parallel {
|
|||||||
guest
|
guest
|
||||||
.ssh_command_l1(
|
.ssh_command_l1(
|
||||||
"sudo /mnt/ch-remote \
|
"sudo /mnt/ch-remote \
|
||||||
--api-socket /tmp/ch_api.sock \
|
--api-socket=/tmp/ch_api.sock \
|
||||||
remove-device vfio123",
|
remove-device vfio123",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -4476,8 +4446,8 @@ mod common_parallel {
|
|||||||
guest
|
guest
|
||||||
.ssh_command_l1(
|
.ssh_command_l1(
|
||||||
"sudo /mnt/ch-remote \
|
"sudo /mnt/ch-remote \
|
||||||
--api-socket /tmp/ch_api.sock \
|
--api-socket=/tmp/ch_api.sock \
|
||||||
resize --memory 1073741824",
|
resize --memory=1073741824",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(guest.get_total_memory_l2().unwrap_or_default() > 960_000);
|
assert!(guest.get_total_memory_l2().unwrap_or_default() > 960_000);
|
||||||
@ -4600,7 +4570,6 @@ mod common_parallel {
|
|||||||
.args([
|
.args([
|
||||||
"--net",
|
"--net",
|
||||||
guest.default_net_string().as_str(),
|
guest.default_net_string().as_str(),
|
||||||
"--net",
|
|
||||||
"tap=,mac=8a:6b:6f:5a:de:ac,ip=192.168.3.1,mask=255.255.255.0",
|
"tap=,mac=8a:6b:6f:5a:de:ac,ip=192.168.3.1,mask=255.255.255.0",
|
||||||
])
|
])
|
||||||
.capture_output()
|
.capture_output()
|
||||||
@ -5339,13 +5308,11 @@ mod common_parallel {
|
|||||||
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
|
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--disk",
|
|
||||||
format!(
|
format!(
|
||||||
"path={}",
|
"path={}",
|
||||||
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--disk",
|
|
||||||
format!("path={}", &loop_dev).as_str(),
|
format!("path={}", &loop_dev).as_str(),
|
||||||
])
|
])
|
||||||
.default_net()
|
.default_net()
|
||||||
@ -5917,7 +5884,6 @@ mod common_parallel {
|
|||||||
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
|
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--disk",
|
|
||||||
cloudinit_params.as_str(),
|
cloudinit_params.as_str(),
|
||||||
])
|
])
|
||||||
.args(["--net", net_params.as_str()])
|
.args(["--net", net_params.as_str()])
|
||||||
@ -8213,9 +8179,7 @@ mod windows {
|
|||||||
.args([
|
.args([
|
||||||
"--net",
|
"--net",
|
||||||
windows_guest.guest().default_net_string().as_str(),
|
windows_guest.guest().default_net_string().as_str(),
|
||||||
"--net",
|
|
||||||
"tap=,mac=8a:6b:6f:5a:de:ac,ip=192.168.3.1,mask=255.255.255.0",
|
"tap=,mac=8a:6b:6f:5a:de:ac,ip=192.168.3.1,mask=255.255.255.0",
|
||||||
"--net",
|
|
||||||
"tap=mytap42,mac=fe:1f:9e:e1:60:f2,ip=192.168.4.1,mask=255.255.255.0",
|
"tap=mytap42,mac=fe:1f:9e:e1:60:f2,ip=192.168.4.1,mask=255.255.255.0",
|
||||||
])
|
])
|
||||||
.capture_output()
|
.capture_output()
|
||||||
@ -8368,15 +8332,12 @@ mod vfio {
|
|||||||
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
|
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--disk",
|
|
||||||
format!(
|
format!(
|
||||||
"path={}",
|
"path={}",
|
||||||
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--disk",
|
|
||||||
format!("path={}", vfio_disk_path.to_str().unwrap()).as_str(),
|
format!("path={}", vfio_disk_path.to_str().unwrap()).as_str(),
|
||||||
"--disk",
|
|
||||||
format!("path={},iommu=on", blk_file_path.to_str().unwrap()).as_str(),
|
format!("path={},iommu=on", blk_file_path.to_str().unwrap()).as_str(),
|
||||||
])
|
])
|
||||||
.args([
|
.args([
|
||||||
@ -8389,19 +8350,16 @@ mod vfio {
|
|||||||
.args([
|
.args([
|
||||||
"--net",
|
"--net",
|
||||||
format!("tap={},mac={}", vfio_tap0, guest.network.guest_mac).as_str(),
|
format!("tap={},mac={}", vfio_tap0, guest.network.guest_mac).as_str(),
|
||||||
"--net",
|
|
||||||
format!(
|
format!(
|
||||||
"tap={},mac={},iommu=on",
|
"tap={},mac={},iommu=on",
|
||||||
vfio_tap1, guest.network.l2_guest_mac1
|
vfio_tap1, guest.network.l2_guest_mac1
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--net",
|
|
||||||
format!(
|
format!(
|
||||||
"tap={},mac={},iommu=on",
|
"tap={},mac={},iommu=on",
|
||||||
vfio_tap2, guest.network.l2_guest_mac2
|
vfio_tap2, guest.network.l2_guest_mac2
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--net",
|
|
||||||
format!(
|
format!(
|
||||||
"tap={},mac={},iommu=on",
|
"tap={},mac={},iommu=on",
|
||||||
vfio_tap3, guest.network.l2_guest_mac3
|
vfio_tap3, guest.network.l2_guest_mac3
|
||||||
@ -8479,7 +8437,7 @@ mod vfio {
|
|||||||
let vfio_hotplug_output = guest
|
let vfio_hotplug_output = guest
|
||||||
.ssh_command_l1(
|
.ssh_command_l1(
|
||||||
"sudo /mnt/ch-remote \
|
"sudo /mnt/ch-remote \
|
||||||
--api-socket /tmp/ch_api.sock \
|
--api-socket=/tmp/ch_api.sock \
|
||||||
add-device path=/sys/bus/pci/devices/0000:00:09.0,id=vfio123",
|
add-device path=/sys/bus/pci/devices/0000:00:09.0,id=vfio123",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -8519,7 +8477,7 @@ mod vfio {
|
|||||||
guest
|
guest
|
||||||
.ssh_command_l1(
|
.ssh_command_l1(
|
||||||
"sudo /mnt/ch-remote \
|
"sudo /mnt/ch-remote \
|
||||||
--api-socket /tmp/ch_api.sock \
|
--api-socket=/tmp/ch_api.sock \
|
||||||
remove-device vfio123",
|
remove-device vfio123",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -8550,8 +8508,8 @@ mod vfio {
|
|||||||
guest
|
guest
|
||||||
.ssh_command_l1(
|
.ssh_command_l1(
|
||||||
"sudo /mnt/ch-remote \
|
"sudo /mnt/ch-remote \
|
||||||
--api-socket /tmp/ch_api.sock \
|
--api-socket=/tmp/ch_api.sock \
|
||||||
resize --memory 1073741824",
|
resize --memory=1073741824",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(guest.get_total_memory_l2().unwrap_or_default() > 960_000);
|
assert!(guest.get_total_memory_l2().unwrap_or_default() > 960_000);
|
||||||
@ -8709,8 +8667,7 @@ mod live_migration {
|
|||||||
// Start to receive migration from the destintion VM
|
// Start to receive migration from the destintion VM
|
||||||
let mut receive_migration = Command::new(clh_command("ch-remote"))
|
let mut receive_migration = Command::new(clh_command("ch-remote"))
|
||||||
.args([
|
.args([
|
||||||
"--api-socket",
|
&format!("--api-socket={dest_api_socket}"),
|
||||||
dest_api_socket,
|
|
||||||
"receive-migration",
|
"receive-migration",
|
||||||
&format! {"unix:{migration_socket}"},
|
&format! {"unix:{migration_socket}"},
|
||||||
])
|
])
|
||||||
@ -8723,15 +8680,14 @@ mod live_migration {
|
|||||||
// Start to send migration from the source VM
|
// Start to send migration from the source VM
|
||||||
|
|
||||||
let mut args = [
|
let mut args = [
|
||||||
"--api-socket".to_string(),
|
format!("--api-socket={}", &src_api_socket),
|
||||||
src_api_socket.to_string(),
|
|
||||||
"send-migration".to_string(),
|
"send-migration".to_string(),
|
||||||
format! {"unix:{migration_socket}"},
|
format! {"unix:{migration_socket}"},
|
||||||
]
|
]
|
||||||
.to_vec();
|
.to_vec();
|
||||||
|
|
||||||
if local {
|
if local {
|
||||||
args.insert(3, "--local".to_string());
|
args.insert(2, "--local".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut send_migration = Command::new(clh_command("ch-remote"))
|
let mut send_migration = Command::new(clh_command("ch-remote"))
|
||||||
@ -9190,15 +9146,11 @@ mod live_migration {
|
|||||||
"size=0,hotplug_method=virtio-mem,shared=on",
|
"size=0,hotplug_method=virtio-mem,shared=on",
|
||||||
"--memory-zone",
|
"--memory-zone",
|
||||||
"id=mem0,size=1G,hotplug_size=4G,shared=on",
|
"id=mem0,size=1G,hotplug_size=4G,shared=on",
|
||||||
"--memory-zone",
|
|
||||||
"id=mem1,size=1G,hotplug_size=4G,shared=on",
|
"id=mem1,size=1G,hotplug_size=4G,shared=on",
|
||||||
"--memory-zone",
|
|
||||||
"id=mem2,size=2G,hotplug_size=4G,shared=on",
|
"id=mem2,size=2G,hotplug_size=4G,shared=on",
|
||||||
"--numa",
|
"--numa",
|
||||||
"guest_numa_id=0,cpus=[0-2,9],distances=[1@15,2@20],memory_zones=mem0",
|
"guest_numa_id=0,cpus=[0-2,9],distances=[1@15,2@20],memory_zones=mem0",
|
||||||
"--numa",
|
|
||||||
"guest_numa_id=1,cpus=[3-4,6-8],distances=[0@20,2@25],memory_zones=mem1",
|
"guest_numa_id=1,cpus=[3-4,6-8],distances=[0@20,2@25],memory_zones=mem1",
|
||||||
"--numa",
|
|
||||||
"guest_numa_id=2,cpus=[5,10-11],distances=[0@25,1@30],memory_zones=mem2",
|
"guest_numa_id=2,cpus=[5,10-11],distances=[0@25,1@30],memory_zones=mem2",
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
@ -9207,15 +9159,11 @@ mod live_migration {
|
|||||||
"size=0,hotplug_method=virtio-mem",
|
"size=0,hotplug_method=virtio-mem",
|
||||||
"--memory-zone",
|
"--memory-zone",
|
||||||
"id=mem0,size=1G,hotplug_size=4G",
|
"id=mem0,size=1G,hotplug_size=4G",
|
||||||
"--memory-zone",
|
|
||||||
"id=mem1,size=1G,hotplug_size=4G",
|
"id=mem1,size=1G,hotplug_size=4G",
|
||||||
"--memory-zone",
|
|
||||||
"id=mem2,size=2G,hotplug_size=4G",
|
"id=mem2,size=2G,hotplug_size=4G",
|
||||||
"--numa",
|
"--numa",
|
||||||
"guest_numa_id=0,cpus=[0-2,9],distances=[1@15,2@20],memory_zones=mem0",
|
"guest_numa_id=0,cpus=[0-2,9],distances=[1@15,2@20],memory_zones=mem0",
|
||||||
"--numa",
|
|
||||||
"guest_numa_id=1,cpus=[3-4,6-8],distances=[0@20,2@25],memory_zones=mem1",
|
"guest_numa_id=1,cpus=[3-4,6-8],distances=[0@20,2@25],memory_zones=mem1",
|
||||||
"--numa",
|
|
||||||
"guest_numa_id=2,cpus=[5,10-11],distances=[0@25,1@30],memory_zones=mem2",
|
"guest_numa_id=2,cpus=[5,10-11],distances=[0@25,1@30],memory_zones=mem2",
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
@ -9773,43 +9721,51 @@ mod live_migration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore = "See #5791"]
|
||||||
fn test_live_upgrade_basic() {
|
fn test_live_upgrade_basic() {
|
||||||
_test_live_migration(true, false)
|
_test_live_migration(true, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore = "See #5791"]
|
||||||
fn test_live_upgrade_local() {
|
fn test_live_upgrade_local() {
|
||||||
_test_live_migration(true, true)
|
_test_live_migration(true, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "mshv"))]
|
#[cfg(not(feature = "mshv"))]
|
||||||
|
#[ignore = "See #5791"]
|
||||||
fn test_live_upgrade_numa() {
|
fn test_live_upgrade_numa() {
|
||||||
_test_live_migration_numa(true, false)
|
_test_live_migration_numa(true, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(feature = "mshv"))]
|
#[cfg(not(feature = "mshv"))]
|
||||||
|
#[ignore = "See #5791"]
|
||||||
fn test_live_upgrade_numa_local() {
|
fn test_live_upgrade_numa_local() {
|
||||||
_test_live_migration_numa(true, true)
|
_test_live_migration_numa(true, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore = "See #5791"]
|
||||||
fn test_live_upgrade_watchdog() {
|
fn test_live_upgrade_watchdog() {
|
||||||
_test_live_migration_watchdog(true, false)
|
_test_live_migration_watchdog(true, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore = "See #5791"]
|
||||||
fn test_live_upgrade_watchdog_local() {
|
fn test_live_upgrade_watchdog_local() {
|
||||||
_test_live_migration_watchdog(true, true)
|
_test_live_migration_watchdog(true, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore = "See #5791"]
|
||||||
fn test_live_upgrade_balloon() {
|
fn test_live_upgrade_balloon() {
|
||||||
_test_live_migration_balloon(true, false)
|
_test_live_migration_balloon(true, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore = "See #5791"]
|
||||||
fn test_live_upgrade_balloon_local() {
|
fn test_live_upgrade_balloon_local() {
|
||||||
_test_live_migration_balloon(true, true)
|
_test_live_migration_balloon(true, true)
|
||||||
}
|
}
|
||||||
@ -9838,6 +9794,7 @@ mod live_migration {
|
|||||||
#[test]
|
#[test]
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
#[cfg(not(feature = "mshv"))]
|
#[cfg(not(feature = "mshv"))]
|
||||||
|
#[ignore = "See #5791"]
|
||||||
fn test_live_upgrade_ovs_dpdk() {
|
fn test_live_upgrade_ovs_dpdk() {
|
||||||
_test_live_migration_ovs_dpdk(true, false);
|
_test_live_migration_ovs_dpdk(true, false);
|
||||||
}
|
}
|
||||||
@ -9845,6 +9802,7 @@ mod live_migration {
|
|||||||
#[test]
|
#[test]
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
#[cfg(not(feature = "mshv"))]
|
#[cfg(not(feature = "mshv"))]
|
||||||
|
#[ignore = "See #5791"]
|
||||||
fn test_live_upgrade_ovs_dpdk_local() {
|
fn test_live_upgrade_ovs_dpdk_local() {
|
||||||
_test_live_migration_ovs_dpdk(true, true);
|
_test_live_migration_ovs_dpdk(true, true);
|
||||||
}
|
}
|
||||||
@ -10043,13 +10001,11 @@ mod rate_limiter {
|
|||||||
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
|
guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--disk",
|
|
||||||
format!(
|
format!(
|
||||||
"path={}",
|
"path={}",
|
||||||
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
guest.disk_config.disk(DiskType::CloudInit).unwrap()
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
"--disk",
|
|
||||||
test_blk_params.as_str(),
|
test_blk_params.as_str(),
|
||||||
])
|
])
|
||||||
.default_net()
|
.default_net()
|
||||||
|
@ -24,6 +24,7 @@ bitflags = "2.4.1"
|
|||||||
block = { path = "../block" }
|
block = { path = "../block" }
|
||||||
blocking = { version = "1.3.0", optional = true }
|
blocking = { version = "1.3.0", optional = true }
|
||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0.0"
|
||||||
|
clap = "4.3.11"
|
||||||
devices = { path = "../devices" }
|
devices = { path = "../devices" }
|
||||||
epoll = "4.3.3"
|
epoll = "4.3.3"
|
||||||
event_monitor = { path = "../event_monitor" }
|
event_monitor = { path = "../event_monitor" }
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
pub use crate::vm_config::*;
|
pub use crate::vm_config::*;
|
||||||
|
use clap::ArgMatches;
|
||||||
use option_parser::{
|
use option_parser::{
|
||||||
ByteSized, IntegerList, OptionParser, OptionParserError, StringList, Toggle, Tuple,
|
ByteSized, IntegerList, OptionParser, OptionParserError, StringList, Toggle, Tuple,
|
||||||
};
|
};
|
||||||
@ -402,6 +403,90 @@ pub struct VmParams<'a> {
|
|||||||
pub tpm: Option<&'a str>,
|
pub tpm: Option<&'a str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> VmParams<'a> {
|
||||||
|
pub fn from_arg_matches(args: &'a ArgMatches) -> Self {
|
||||||
|
// These .unwrap()s cannot fail as there is a default value defined
|
||||||
|
let cpus = args.get_one::<String>("cpus").unwrap();
|
||||||
|
let memory = args.get_one::<String>("memory").unwrap();
|
||||||
|
let memory_zones: Option<Vec<&str>> = args
|
||||||
|
.get_many::<String>("memory-zone")
|
||||||
|
.map(|x| x.map(|y| y as &str).collect());
|
||||||
|
let rng = args.get_one::<String>("rng").unwrap();
|
||||||
|
let serial = args.get_one::<String>("serial").unwrap();
|
||||||
|
let firmware = args.get_one::<String>("firmware").map(|x| x as &str);
|
||||||
|
let kernel = args.get_one::<String>("kernel").map(|x| x as &str);
|
||||||
|
let initramfs = args.get_one::<String>("initramfs").map(|x| x as &str);
|
||||||
|
let cmdline = args.get_one::<String>("cmdline").map(|x| x as &str);
|
||||||
|
let disks: Option<Vec<&str>> = args
|
||||||
|
.get_many::<String>("disk")
|
||||||
|
.map(|x| x.map(|y| y as &str).collect());
|
||||||
|
let net: Option<Vec<&str>> = args
|
||||||
|
.get_many::<String>("net")
|
||||||
|
.map(|x| x.map(|y| y as &str).collect());
|
||||||
|
let console = args.get_one::<String>("console").unwrap();
|
||||||
|
let balloon = args.get_one::<String>("balloon").map(|x| x as &str);
|
||||||
|
let fs: Option<Vec<&str>> = args
|
||||||
|
.get_many::<String>("fs")
|
||||||
|
.map(|x| x.map(|y| y as &str).collect());
|
||||||
|
let pmem: Option<Vec<&str>> = args
|
||||||
|
.get_many::<String>("pmem")
|
||||||
|
.map(|x| x.map(|y| y as &str).collect());
|
||||||
|
let devices: Option<Vec<&str>> = args
|
||||||
|
.get_many::<String>("device")
|
||||||
|
.map(|x| x.map(|y| y as &str).collect());
|
||||||
|
let user_devices: Option<Vec<&str>> = args
|
||||||
|
.get_many::<String>("user-device")
|
||||||
|
.map(|x| x.map(|y| y as &str).collect());
|
||||||
|
let vdpa: Option<Vec<&str>> = args
|
||||||
|
.get_many::<String>("vdpa")
|
||||||
|
.map(|x| x.map(|y| y as &str).collect());
|
||||||
|
let vsock: Option<&str> = args.get_one::<String>("vsock").map(|x| x as &str);
|
||||||
|
let pvpanic = args.get_flag("pvpanic");
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
let sgx_epc: Option<Vec<&str>> = args
|
||||||
|
.get_many::<String>("sgx-epc")
|
||||||
|
.map(|x| x.map(|y| y as &str).collect());
|
||||||
|
let numa: Option<Vec<&str>> = args
|
||||||
|
.get_many::<String>("numa")
|
||||||
|
.map(|x| x.map(|y| y as &str).collect());
|
||||||
|
let watchdog = args.get_flag("watchdog");
|
||||||
|
let platform = args.get_one::<String>("platform").map(|x| x as &str);
|
||||||
|
#[cfg(feature = "guest_debug")]
|
||||||
|
let gdb = args.contains_id("gdb");
|
||||||
|
let tpm: Option<&str> = args.get_one::<String>("tpm").map(|x| x as &str);
|
||||||
|
VmParams {
|
||||||
|
cpus,
|
||||||
|
memory,
|
||||||
|
memory_zones,
|
||||||
|
firmware,
|
||||||
|
kernel,
|
||||||
|
initramfs,
|
||||||
|
cmdline,
|
||||||
|
disks,
|
||||||
|
net,
|
||||||
|
rng,
|
||||||
|
balloon,
|
||||||
|
fs,
|
||||||
|
pmem,
|
||||||
|
serial,
|
||||||
|
console,
|
||||||
|
devices,
|
||||||
|
user_devices,
|
||||||
|
vdpa,
|
||||||
|
vsock,
|
||||||
|
pvpanic,
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
sgx_epc,
|
||||||
|
numa,
|
||||||
|
watchdog,
|
||||||
|
#[cfg(feature = "guest_debug")]
|
||||||
|
gdb,
|
||||||
|
platform,
|
||||||
|
tpm,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ParseHotplugMethodError {
|
pub enum ParseHotplugMethodError {
|
||||||
InvalidValue(String),
|
InvalidValue(String),
|
||||||
@ -776,6 +861,14 @@ impl MemoryConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DiskConfig {
|
impl DiskConfig {
|
||||||
|
pub const SYNTAX: &'static str = "Disk parameters \
|
||||||
|
\"path=<disk_image_path>,readonly=on|off,direct=on|off,iommu=on|off,\
|
||||||
|
num_queues=<number_of_queues>,queue_size=<size_of_each_queue>,\
|
||||||
|
vhost_user=on|off,socket=<vhost_user_socket_path>,\
|
||||||
|
bw_size=<bytes>,bw_one_time_burst=<bytes>,bw_refill_time=<ms>,\
|
||||||
|
ops_size=<io_ops>,ops_one_time_burst=<io_ops>,ops_refill_time=<ms>,\
|
||||||
|
id=<device_id>,pci_segment=<segment_id>\"";
|
||||||
|
|
||||||
pub fn parse(disk: &str) -> Result<Self> {
|
pub fn parse(disk: &str) -> Result<Self> {
|
||||||
let mut parser = OptionParser::new();
|
let mut parser = OptionParser::new();
|
||||||
parser
|
parser
|
||||||
@ -951,6 +1044,14 @@ impl FromStr for VhostMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl NetConfig {
|
impl NetConfig {
|
||||||
|
pub const SYNTAX: &'static str = "Network parameters \
|
||||||
|
\"tap=<if_name>,ip=<ip_addr>,mask=<net_mask>,mac=<mac_addr>,fd=<fd1,fd2...>,iommu=on|off,\
|
||||||
|
num_queues=<number_of_queues>,queue_size=<size_of_each_queue>,id=<device_id>,\
|
||||||
|
vhost_user=<vhost_user_enable>,socket=<vhost_user_socket_path>,vhost_mode=client|server,\
|
||||||
|
bw_size=<bytes>,bw_one_time_burst=<bytes>,bw_refill_time=<ms>,\
|
||||||
|
ops_size=<io_ops>,ops_one_time_burst=<io_ops>,ops_refill_time=<ms>,pci_segment=<segment_id>\
|
||||||
|
offload_tso=on|off,offload_ufo=on|off,offload_csum=on|off\"";
|
||||||
|
|
||||||
pub fn parse(net: &str) -> Result<Self> {
|
pub fn parse(net: &str) -> Result<Self> {
|
||||||
let mut parser = OptionParser::new();
|
let mut parser = OptionParser::new();
|
||||||
|
|
||||||
@ -1191,6 +1292,10 @@ impl RngConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BalloonConfig {
|
impl BalloonConfig {
|
||||||
|
pub const SYNTAX: &'static str =
|
||||||
|
"Balloon parameters \"size=<balloon_size>,deflate_on_oom=on|off,\
|
||||||
|
free_page_reporting=on|off\"";
|
||||||
|
|
||||||
pub fn parse(balloon: &str) -> Result<Self> {
|
pub fn parse(balloon: &str) -> Result<Self> {
|
||||||
let mut parser = OptionParser::new();
|
let mut parser = OptionParser::new();
|
||||||
parser.add("size");
|
parser.add("size");
|
||||||
@ -1225,6 +1330,10 @@ impl BalloonConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FsConfig {
|
impl FsConfig {
|
||||||
|
pub const SYNTAX: &'static str = "virtio-fs parameters \
|
||||||
|
\"tag=<tag_name>,socket=<socket_path>,num_queues=<number_of_queues>,\
|
||||||
|
queue_size=<size_of_each_queue>,id=<device_id>,pci_segment=<segment_id>\"";
|
||||||
|
|
||||||
pub fn parse(fs: &str) -> Result<Self> {
|
pub fn parse(fs: &str) -> Result<Self> {
|
||||||
let mut parser = OptionParser::new();
|
let mut parser = OptionParser::new();
|
||||||
parser
|
parser
|
||||||
@ -1289,6 +1398,10 @@ impl FsConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PmemConfig {
|
impl PmemConfig {
|
||||||
|
pub const SYNTAX: &'static str = "Persistent memory parameters \
|
||||||
|
\"file=<backing_file_path>,size=<persistent_memory_size>,iommu=on|off,\
|
||||||
|
discard_writes=on|off,id=<device_id>,pci_segment=<segment_id>\"";
|
||||||
|
|
||||||
pub fn parse(pmem: &str) -> Result<Self> {
|
pub fn parse(pmem: &str) -> Result<Self> {
|
||||||
let mut parser = OptionParser::new();
|
let mut parser = OptionParser::new();
|
||||||
parser
|
parser
|
||||||
@ -1402,6 +1515,9 @@ impl ConsoleConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DeviceConfig {
|
impl DeviceConfig {
|
||||||
|
pub const SYNTAX: &'static str =
|
||||||
|
"Direct device assignment parameters \"path=<device_path>,iommu=on|off,id=<device_id>,pci_segment=<segment_id>\"";
|
||||||
|
|
||||||
pub fn parse(device: &str) -> Result<Self> {
|
pub fn parse(device: &str) -> Result<Self> {
|
||||||
let mut parser = OptionParser::new();
|
let mut parser = OptionParser::new();
|
||||||
parser.add("path").add("id").add("iommu").add("pci_segment");
|
parser.add("path").add("id").add("iommu").add("pci_segment");
|
||||||
@ -1448,6 +1564,9 @@ impl DeviceConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl UserDeviceConfig {
|
impl UserDeviceConfig {
|
||||||
|
pub const SYNTAX: &'static str =
|
||||||
|
"Userspace device socket=<socket_path>,id=<device_id>,pci_segment=<segment_id>\"";
|
||||||
|
|
||||||
pub fn parse(user_device: &str) -> Result<Self> {
|
pub fn parse(user_device: &str) -> Result<Self> {
|
||||||
let mut parser = OptionParser::new();
|
let mut parser = OptionParser::new();
|
||||||
parser.add("socket").add("id").add("pci_segment");
|
parser.add("socket").add("id").add("pci_segment");
|
||||||
@ -1490,6 +1609,10 @@ impl UserDeviceConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl VdpaConfig {
|
impl VdpaConfig {
|
||||||
|
pub const SYNTAX: &'static str = "vDPA device \
|
||||||
|
\"path=<device_path>,num_queues=<number_of_queues>,iommu=on|off,\
|
||||||
|
id=<device_id>,pci_segment=<segment_id>\"";
|
||||||
|
|
||||||
pub fn parse(vdpa: &str) -> Result<Self> {
|
pub fn parse(vdpa: &str) -> Result<Self> {
|
||||||
let mut parser = OptionParser::new();
|
let mut parser = OptionParser::new();
|
||||||
parser
|
parser
|
||||||
@ -1546,6 +1669,9 @@ impl VdpaConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl VsockConfig {
|
impl VsockConfig {
|
||||||
|
pub const SYNTAX: &'static str = "Virtio VSOCK parameters \
|
||||||
|
\"cid=<context_id>,socket=<socket_path>,iommu=on|off,id=<device_id>,pci_segment=<segment_id>\"";
|
||||||
|
|
||||||
pub fn parse(vsock: &str) -> Result<Self> {
|
pub fn parse(vsock: &str) -> Result<Self> {
|
||||||
let mut parser = OptionParser::new();
|
let mut parser = OptionParser::new();
|
||||||
parser
|
parser
|
||||||
@ -1603,6 +1729,9 @@ impl VsockConfig {
|
|||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
impl SgxEpcConfig {
|
impl SgxEpcConfig {
|
||||||
|
pub const SYNTAX: &'static str = "SGX EPC parameters \
|
||||||
|
\"id=<epc_section_identifier>,size=<epc_section_size>,prefault=on|off\"";
|
||||||
|
|
||||||
pub fn parse(sgx_epc: &str) -> Result<Self> {
|
pub fn parse(sgx_epc: &str) -> Result<Self> {
|
||||||
let mut parser = OptionParser::new();
|
let mut parser = OptionParser::new();
|
||||||
parser.add("id").add("size").add("prefault");
|
parser.add("id").add("size").add("prefault");
|
||||||
@ -1625,6 +1754,10 @@ impl SgxEpcConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl NumaConfig {
|
impl NumaConfig {
|
||||||
|
pub const SYNTAX: &'static str = "Settings related to a given NUMA node \
|
||||||
|
\"guest_numa_id=<node_id>,cpus=<cpus_id>,distances=<list_of_distances_to_destination_nodes>,\
|
||||||
|
memory_zones=<list_of_memory_zones>,sgx_epc_sections=<list_of_sgx_epc_sections>\"";
|
||||||
|
|
||||||
pub fn parse(numa: &str) -> Result<Self> {
|
pub fn parse(numa: &str) -> Result<Self> {
|
||||||
let mut parser = OptionParser::new();
|
let mut parser = OptionParser::new();
|
||||||
parser
|
parser
|
||||||
@ -1689,6 +1822,11 @@ pub struct RestoreConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl RestoreConfig {
|
impl RestoreConfig {
|
||||||
|
pub const SYNTAX: &'static str = "Restore from a VM snapshot. \
|
||||||
|
\nRestore parameters \"source_url=<source_url>,prefault=on|off\" \
|
||||||
|
\n`source_url` should be a valid URL (e.g file:///foo/bar or tcp://192.168.1.10/foo) \
|
||||||
|
\n`prefault` brings memory pages in when enabled (disabled by default)";
|
||||||
|
|
||||||
pub fn parse(restore: &str) -> Result<Self> {
|
pub fn parse(restore: &str) -> Result<Self> {
|
||||||
let mut parser = OptionParser::new();
|
let mut parser = OptionParser::new();
|
||||||
parser.add("source_url").add("prefault");
|
parser.add("source_url").add("prefault");
|
||||||
@ -1712,6 +1850,9 @@ impl RestoreConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TpmConfig {
|
impl TpmConfig {
|
||||||
|
pub const SYNTAX: &'static str = "TPM device \
|
||||||
|
\"(UNIX Domain Socket from swtpm) socket=</path/to/a/socket>\"";
|
||||||
|
|
||||||
pub fn parse(tpm: &str) -> Result<Self> {
|
pub fn parse(tpm: &str) -> Result<Self> {
|
||||||
let mut parser = OptionParser::new();
|
let mut parser = OptionParser::new();
|
||||||
parser.add("socket");
|
parser.add("socket");
|
||||||
|
Loading…
Reference in New Issue
Block a user