From c016a0d4d345981eaca57bb638710caba79d0dc4 Mon Sep 17 00:00:00 2001 From: Omer Faruk Bayram Date: Thu, 23 Mar 2023 00:03:02 +0300 Subject: [PATCH] vmm: dbus: implement the D-Bus API This commit introduces three new dependencies: `zbus`, `futures` and `blocking`. `blocking` is used to call the Internal API in zbus' async context which is driven by `futures::executor`. They are all behind the `dbus_api` feature flag. The D-Bus API implementation is behind the same `dbus_api` feature flag as well. Signed-off-by: Omer Faruk Bayram --- .github/workflows/build.yaml | 3 + Cargo.lock | 935 +++++++++++++++++++++++++++++++---- Cargo.toml | 1 + src/main.rs | 4 +- vmm/Cargo.toml | 6 +- vmm/src/api/dbus/mod.rs | 286 +++++++++++ vmm/src/api/mod.rs | 8 +- vmm/src/lib.rs | 28 +- 8 files changed, 1173 insertions(+), 98 deletions(-) create mode 100644 vmm/src/api/dbus/mod.rs diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index bd31241e9..8f521cc10 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -42,6 +42,9 @@ jobs: - name: Build (default features + tdx) run: cargo rustc --locked --bin cloud-hypervisor --features "tdx" -- -D warnings -D clippy::undocumented_unsafe_blocks + - name: Build (default features + dbus_api) + run: cargo rustc --locked --bin cloud-hypervisor --features "dbus_api" -- -D warnings -D clippy::undocumented_unsafe_blocks + - name: Build (default features + guest_debug) run: cargo rustc --locked --bin cloud-hypervisor --features "guest_debug" -- -D warnings -D clippy::undocumented_unsafe_blocks diff --git a/Cargo.lock b/Cargo.lock index 628a9b561..412ead352 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -94,7 +94,7 @@ dependencies = [ "argh_shared", "proc-macro2", "quote", - "syn 1.0.107", + "syn 1.0.109", ] [[package]] @@ -103,6 +103,134 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64cb94155d965e3d37ffbbe7cc5b82c3dd79dd33bd48e536f73d2cfb8d85506f" +[[package]] +name = "async-broadcast" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c48ccdbf6ca6b121e0f586cbc0e73ae440e56c67c30fa0873b4e110d9c26d2b" +dependencies = [ + "event-listener", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-executor" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb" +dependencies = [ + "async-lock", + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-fs" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" +dependencies = [ + "async-lock", + "autocfg", + "blocking", + "futures-lite", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock", + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-lite", + "log", + "parking", + "polling", + "rustix", + "slab", + "socket2", + "waker-fn", +] + +[[package]] +name = "async-lock" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa24f727524730b077666307f2734b4a1a1c57acb79193127dcc8914d5242dd7" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-process" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a9d28b1d97e08915212e2e45310d47854eafa69600756fc735fb788f75199c9" +dependencies = [ + "async-io", + "async-lock", + "autocfg", + "blocking", + "cfg-if", + "event-listener", + "futures-lite", + "rustix", + "signal-hook", + "windows-sys 0.48.0", +] + +[[package]] +name = "async-recursion" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "async-task" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" + +[[package]] +name = "async-trait" +version = "0.1.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "atomic-waker" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" + [[package]] name = "autocfg" version = "1.1.0" @@ -139,6 +267,15 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "block_util" version = "0.1.0" @@ -159,6 +296,21 @@ dependencies = [ "vmm-sys-util", ] +[[package]] +name = "blocking" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65" +dependencies = [ + "async-channel", + "async-lock", + "async-task", + "atomic-waker", + "fastrand", + "futures-lite", + "log", +] + [[package]] name = "byteorder" version = "1.4.3" @@ -207,6 +359,24 @@ dependencies = [ "wait-timeout", ] +[[package]] +name = "concurrent-queue" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "cpufeatures" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" +dependencies = [ + "libc", +] + [[package]] name = "crc32c" version = "0.6.3" @@ -223,10 +393,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55626594feae15d266d52440b26ff77de0e22230cf0c113abe619084c1ddc910" [[package]] -name = "darling" -version = "0.14.4" +name = "crossbeam-utils" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "darling" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944" dependencies = [ "darling_core", "darling_macro", @@ -234,27 +423,38 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.4" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 1.0.107", + "syn 2.0.18", ] [[package]] name = "darling_macro" -version = "0.14.4" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" dependencies = [ "darling_core", "quote", - "syn 1.0.107", + "syn 2.0.18", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -296,23 +496,55 @@ dependencies = [ ] [[package]] -name = "dirs" -version = "5.0.0" +name = "digest" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dece029acd3353e3a58ac2e3eb3c8d6c35827a892edc6cc4138ef9c33df46ecd" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" dependencies = [ "dirs-sys", ] [[package]] name = "dirs-sys" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04414300db88f70d74c5ff54e50f9e1d1737d9a5b90f53fcf2e95ca2a9ab554b" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" dependencies = [ "libc", + "option-ext", "redox_users", - "windows-sys 0.45.0", + "windows-sys 0.48.0", +] + +[[package]] +name = "enumflags2" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c041f5090df68b32bcd905365fd51769c8b9d553fe87fde0b683534f10c01bd2" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", ] [[package]] @@ -359,6 +591,12 @@ dependencies = [ "libc", ] +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + [[package]] name = "event_monitor" version = "0.1.0" @@ -368,6 +606,15 @@ dependencies = [ "serde_json", ] +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + [[package]] name = "fdt" version = "0.1.5" @@ -381,10 +628,114 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "gdbstub" -version = "0.6.4" +name = "futures" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4fddc6f9d12cbef29e395d9a6b48c128f513c8a2ded7048c97ed5c484e53e7" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "gdbstub" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4e02bf1b1a624d96925c608f1b268d82a76cbc587ce9e59f7c755e9ea11c75c" dependencies = [ "bitflags", "cfg-if", @@ -405,10 +756,20 @@ dependencies = [ ] [[package]] -name = "getrandom" -version = "0.2.8" +name = "generic-array" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if", "libc", @@ -417,9 +778,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "221996f774192f0f718773def8201c4ae31f02616a54ccfc2d358bb0e5cefdec" +checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" [[package]] name = "glob" @@ -427,12 +788,24 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hermit-abi" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "humantime" version = "2.1.0" @@ -476,6 +849,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown", +] + [[package]] name = "instant" version = "0.1.12" @@ -487,9 +870,9 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ "hermit-abi", "libc", @@ -561,9 +944,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.139" +version = "0.2.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" [[package]] name = "libssh2-sys" @@ -581,9 +964,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf" +checksum = "56ee889ecc9568871456d42f603d6a0ce59ff328d291063a45cbdf0036baf6db" dependencies = [ "cc", "libc", @@ -602,9 +985,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.3.2" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f508063cc7bb32987c71511216bd5a32be15bccb6a80b52df8b9d7f01fc3aa2" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "lock_api" @@ -637,6 +1020,15 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + [[package]] name = "micro_http" version = "0.1.0" @@ -648,9 +1040,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.6.4" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2e212582ede878b109755efd0773a4f0f4ec851584cf0aefbeb4d9ecc114822" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" dependencies = [ "adler", ] @@ -719,6 +1111,19 @@ dependencies = [ "vmm-sys-util", ] +[[package]] +name = "nix" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +dependencies = [ + "bitflags", + "cfg-if", + "libc", + "memoffset", + "static_assertions", +] + [[package]] name = "no-std-net" version = "0.6.0" @@ -760,11 +1165,10 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.83" +version = "0.9.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "666416d899cf077260dac8698d60a60b435a46d57e82acb1be3d0dad87284e5b" +checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e" dependencies = [ - "autocfg", "cc", "libc", "openssl-src", @@ -772,10 +1176,32 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "option_parser" version = "0.1.0" +[[package]] +name = "ordered-stream" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" +dependencies = [ + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "parking" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" + [[package]] name = "parking_lot" version = "0.11.2" @@ -794,7 +1220,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.6", + "parking_lot_core 0.9.7", ] [[package]] @@ -806,22 +1232,22 @@ dependencies = [ "cfg-if", "instant", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "smallvec", "winapi", ] [[package]] name = "parking_lot_core" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "smallvec", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -866,6 +1292,18 @@ dependencies = [ "wait-timeout", ] +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "pkg-config" version = "0.3.27" @@ -917,7 +1355,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 1.0.107", + "syn 1.0.109", ] [[package]] @@ -963,6 +1401,38 @@ dependencies = [ "pnet_sys", ] +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] + [[package]] name = "proc-macro2" version = "1.0.59" @@ -985,13 +1455,43 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "rate_limiter" version = "0.1.0" @@ -1010,6 +1510,15 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + [[package]] name = "redox_users" version = "0.4.3" @@ -1017,7 +1526,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom", - "redox_syscall", + "redox_syscall 0.2.16", "thiserror", ] @@ -1040,13 +1549,13 @@ checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "remain" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5704e2cda92fd54202f05430725317ba0ea7d0c96b246ca0a92e45177127ba3b" +checksum = "e13cca257d068dd3a390d04b2c3009a3fad2ee5048dfa8f239d048372810470c" dependencies = [ "proc-macro2", "quote", - "syn 1.0.107", + "syn 2.0.18", ] [[package]] @@ -1072,16 +1581,16 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.3" +version = "0.37.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b24138615de35e32031d041a09032ef3487a616d901ca4db224e7d557efae2" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" dependencies = [ "bitflags", "errno", "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -1128,7 +1637,7 @@ checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.12", + "syn 2.0.18", ] [[package]] @@ -1143,10 +1652,21 @@ dependencies = [ ] [[package]] -name = "serde_with" -version = "2.3.2" +name = "serde_repr" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "331bb8c3bf9b92457ab7abecf07078c13f7d270ba490103e84e8b014490cd0b0" +checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "serde_with" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" dependencies = [ "serde", "serde_with_macros", @@ -1154,20 +1674,31 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859011bddcc11f289f07f467cc1fe01c7a941daa4d8f6c40d4d1c92eb6d9319c" +checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" dependencies = [ "darling", "proc-macro2", "quote", - "syn 1.0.107", + "syn 2.0.18", ] [[package]] name = "serial_buffer" version = "0.1.0" +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "signal-hook" version = "0.3.15" @@ -1187,12 +1718,31 @@ dependencies = [ "libc", ] +[[package]] +name = "slab" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + [[package]] name = "smallvec" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "ssh2" version = "0.9.4" @@ -1205,6 +1755,12 @@ dependencies = [ "parking_lot 0.11.2", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "strsim" version = "0.10.0" @@ -1213,9 +1769,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.107" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", @@ -1224,9 +1780,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.12" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79d9531f94112cfc3e4c8f5f02cb2b58f72c97b7efd85f70203cc6d8efda5927" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" dependencies = [ "proc-macro2", "quote", @@ -1243,6 +1799,19 @@ dependencies = [ "libc", ] +[[package]] +name = "tempfile" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.3.5", + "rustix", + "windows-sys 0.45.0", +] + [[package]] name = "termcolor" version = "1.2.0" @@ -1284,7 +1853,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.12", + "syn 2.0.18", ] [[package]] @@ -1293,6 +1862,23 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820" +[[package]] +name = "toml_datetime" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" + +[[package]] +name = "toml_edit" +version = "0.19.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + [[package]] name = "tpm" version = "0.1.0" @@ -1318,10 +1904,58 @@ dependencies = [ ] [[package]] -name = "unicode-ident" -version = "1.0.6" +name = "tracing" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "uds_windows" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce65604324d3cce9b966701489fbd0cf318cb1f7bd9dd07ac9a4ee6fb791930d" +dependencies = [ + "tempfile", + "winapi", +] + +[[package]] +name = "unicode-ident" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" [[package]] name = "uuid" @@ -1338,6 +1972,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "versionize" version = "0.1.10" @@ -1350,7 +1990,7 @@ dependencies = [ "quote", "serde", "serde_derive", - "syn 1.0.107", + "syn 1.0.109", "versionize_derive", "vmm-sys-util", ] @@ -1362,7 +2002,7 @@ source = "git+https://github.com/cloud-hypervisor/versionize_derive?branch=ch#e5 dependencies = [ "proc-macro2", "quote", - "syn 1.0.107", + "syn 1.0.109", ] [[package]] @@ -1376,7 +2016,7 @@ dependencies = [ [[package]] name = "vfio-ioctls" version = "0.2.0" -source = "git+https://github.com/rust-vmm/vfio?branch=main#ea8f710464a24690ce109e6b7dfaa623dc518304" +source = "git+https://github.com/rust-vmm/vfio?branch=main#89f8e77dd1a2829197ecde65b686bafcc8a1def4" dependencies = [ "byteorder", "kvm-bindings", @@ -1387,7 +2027,7 @@ dependencies = [ "mshv-ioctls", "thiserror", "vfio-bindings", - "vm-memory 0.10.0", + "vm-memory 0.11.0", "vmm-sys-util", ] @@ -1570,7 +2210,7 @@ dependencies = [ [[package]] name = "vm-fdt" version = "0.2.0" -source = "git+https://github.com/rust-vmm/vm-fdt?branch=main#ad21ede0ddb4cc97448eeb64c1dfc27803b9ec08" +source = "git+https://github.com/rust-vmm/vm-fdt?branch=main#77212bd0d62913e445c89376bcbbecd595afc5b1" [[package]] name = "vm-memory" @@ -1626,9 +2266,11 @@ dependencies = [ "arch", "bitflags", "block_util", + "blocking", "devices", "epoll", "event_monitor", + "futures", "gdbstub", "gdbstub_arch", "hypervisor", @@ -1662,6 +2304,7 @@ dependencies = [ "vm-migration", "vm-virtio", "vmm-sys-util", + "zbus", "zerocopy", ] @@ -1686,6 +2329,12 @@ dependencies = [ "libc", ] +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -1723,21 +2372,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-sys" version = "0.45.0" @@ -1870,6 +2504,91 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +[[package]] +name = "winnow" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28" +dependencies = [ + "memchr", +] + +[[package]] +name = "xdg-home" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2769203cd13a0c6015d515be729c526d041e9cf2c0cc478d57faee85f40c6dcd" +dependencies = [ + "nix", + "winapi", +] + +[[package]] +name = "zbus" +version = "3.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c3d77c9966c28321f1907f0b6c5a5561189d1f7311eea6d94180c6be9daab29" +dependencies = [ + "async-broadcast", + "async-executor", + "async-fs", + "async-io", + "async-lock", + "async-process", + "async-recursion", + "async-task", + "async-trait", + "byteorder", + "derivative", + "enumflags2", + "event-listener", + "futures-core", + "futures-sink", + "futures-util", + "hex", + "nix", + "once_cell", + "ordered-stream", + "rand", + "serde", + "serde_repr", + "sha1", + "static_assertions", + "tracing", + "uds_windows", + "winapi", + "xdg-home", + "zbus_macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "3.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6e341d12edaff644e539ccbbf7f161601294c9a84ed3d7e015da33155b435af" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "regex", + "syn 1.0.109", + "winnow", + "zvariant_utils", +] + +[[package]] +name = "zbus_names" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82441e6033be0a741157a72951a3e4957d519698f3a824439cc131c5ba77ac2a" +dependencies = [ + "serde", + "static_assertions", + "zvariant", +] + [[package]] name = "zerocopy" version = "0.6.1" @@ -1888,5 +2607,43 @@ checksum = "6505e6815af7de1746a08f69c69606bb45695a17149517680f3b2149713b19a3" dependencies = [ "proc-macro2", "quote", - "syn 1.0.107", + "syn 1.0.109", +] + +[[package]] +name = "zvariant" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622cc473f10cef1b0d73b7b34a266be30ebdcfaea40ec297dd8cbda088f9f93c" +dependencies = [ + "byteorder", + "enumflags2", + "libc", + "serde", + "static_assertions", + "zvariant_derive", +] + +[[package]] +name = "zvariant_derive" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d9c1b57352c25b778257c661f3c4744b7cefb7fc09dd46909a153cce7773da2" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", + "zvariant_utils", +] + +[[package]] +name = "zvariant_utils" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7234f0d811589db492d16893e3f21e8e2fd282e6d01b0cddee310322062cc200" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] diff --git a/Cargo.toml b/Cargo.toml index 9364e2ddc..4017e982d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -65,6 +65,7 @@ wait-timeout = "0.2.0" [features] default = ["kvm"] +dbus_api = ["vmm/dbus_api"] dhat-heap = ["dhat"] # For heap profiling guest_debug = ["vmm/guest_debug"] kvm = ["vmm/kvm"] diff --git a/src/main.rs b/src/main.rs index e54806ef3..8455bfec5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -445,7 +445,7 @@ fn start_vmm(toplevel: TopLevel) -> Result, Error> { let (api_request_sender, api_request_receiver) = channel(); let api_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::CreateApiEventFd)?; - let http_sender = api_request_sender.clone(); + let api_request_sender_clone = api_request_sender.clone(); let seccomp_action = match &toplevel.seccomp as &str { "true" => SeccompAction::Trap, "false" => SeccompAction::Allow, @@ -518,7 +518,7 @@ fn start_vmm(toplevel: TopLevel) -> Result, Error> { &api_socket_path, api_socket_fd, api_evt.try_clone().unwrap(), - http_sender, + api_request_sender_clone, api_request_receiver, #[cfg(feature = "guest_debug")] gdb_socket_path, diff --git a/vmm/Cargo.toml b/vmm/Cargo.toml index a6aad34e9..5f67a8098 100644 --- a/vmm/Cargo.toml +++ b/vmm/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [features] default = [] +dbus_api = ["blocking", "futures", "zbus"] guest_debug = ["kvm", "gdbstub", "gdbstub_arch"] kvm = ["hypervisor/kvm", "vfio-ioctls/kvm", "vm-device/kvm", "pci/kvm"] mshv = ["hypervisor/mshv", "vfio-ioctls/mshv", "vm-device/mshv", "pci/mshv"] @@ -19,9 +20,11 @@ arc-swap = "1.5.1" arch = { path = "../arch" } bitflags = "1.3.2" block_util = { path = "../block_util" } +blocking = { version = "1.3.0", optional = true } devices = { path = "../devices" } epoll = "4.3.1" event_monitor = { path = "../event_monitor" } +futures = { version = "0.3.27", optional = true } gdbstub = { version = "0.6.4", optional = true } gdbstub_arch = { version = "0.2.4", optional = true } hypervisor = { path = "../hypervisor" } @@ -55,4 +58,5 @@ vm-memory = { version = "0.10.0", features = ["backend-mmap", "backend-atomic", vm-migration = { path = "../vm-migration" } vm-virtio = { path = "../vm-virtio" } vmm-sys-util = { version = "0.11.0", features = ["with-serde"] } -zerocopy = "0.6.1" \ No newline at end of file +zbus = { version = "3.11.1", optional = true } +zerocopy = "0.6.1" diff --git a/vmm/src/api/dbus/mod.rs b/vmm/src/api/dbus/mod.rs new file mode 100644 index 000000000..90d16a445 --- /dev/null +++ b/vmm/src/api/dbus/mod.rs @@ -0,0 +1,286 @@ +// Copyright © 2023 Sartura Ltd. +// +// SPDX-License-Identifier: Apache-2.0 +// +use super::{ApiRequest, VmAction}; +use crate::{Error as VmmError, Result as VmmResult}; +use futures::executor; +use hypervisor::HypervisorType; +use seccompiler::SeccompAction; +use std::sync::mpsc::Sender; +use std::sync::{Arc, Mutex}; +use std::thread; +use vmm_sys_util::eventfd::EventFd; +use zbus::fdo::{self, Result}; +use zbus::zvariant::Optional; +use zbus::{dbus_interface, ConnectionBuilder}; + +pub struct DBusApi { + api_notifier: EventFd, + api_sender: futures::lock::Mutex>, +} + +fn api_error(error: impl std::fmt::Debug) -> fdo::Error { + fdo::Error::Failed(format!("{error:?}")) +} + +impl DBusApi { + pub fn new(api_notifier: EventFd, api_sender: Sender) -> Self { + Self { + api_notifier, + api_sender: futures::lock::Mutex::new(api_sender), + } + } + + async fn clone_api_sender(&self) -> Sender { + // lock the async mutex, clone the `Sender` and then immediately + // drop the MutexGuard so that other tasks can clone the + // `Sender` as well + self.api_sender.lock().await.clone() + } + + fn clone_api_notifier(&self) -> Result { + self.api_notifier + .try_clone() + .map_err(|err| fdo::Error::IOError(format!("{err:?}"))) + } + + async fn vm_action(&self, action: VmAction) -> Result> { + let api_sender = self.clone_api_sender().await; + let api_notifier = self.clone_api_notifier()?; + + let result = blocking::unblock(move || super::vm_action(api_notifier, api_sender, action)) + .await + .map_err(api_error)? + // We're using `from_utf8_lossy` here to not deal with the + // error case of `from_utf8` as we know that `b.body` is valid JSON. + .map(|b| String::from_utf8_lossy(&b.body).to_string()); + + Ok(result.into()) + } +} + +#[dbus_interface] +impl DBusApi { + async fn vmm_ping(&self) -> Result { + let api_sender = self.clone_api_sender().await; + let api_notifier = self.clone_api_notifier()?; + + let result = blocking::unblock(move || super::vmm_ping(api_notifier, api_sender)) + .await + .map_err(api_error)?; + serde_json::to_string(&result).map_err(api_error) + } + + async fn vmm_shutdown(&self) -> Result<()> { + let api_sender = self.clone_api_sender().await; + let api_notifier = self.clone_api_notifier()?; + + blocking::unblock(move || super::vmm_shutdown(api_notifier, api_sender)) + .await + .map_err(api_error) + } + + async fn vm_add_device(&self, device_config: String) -> Result> { + let device_config = Arc::new(serde_json::from_str(&device_config).map_err(api_error)?); + self.vm_action(VmAction::AddDevice(device_config)).await + } + + async fn vm_add_disk(&self, disk_config: String) -> Result> { + let disk_config = Arc::new(serde_json::from_str(&disk_config).map_err(api_error)?); + self.vm_action(VmAction::AddDisk(disk_config)).await + } + + async fn vm_add_fs(&self, fs_config: String) -> Result> { + let fs_config = Arc::new(serde_json::from_str(&fs_config).map_err(api_error)?); + self.vm_action(VmAction::AddFs(fs_config)).await + } + + async fn vm_add_net(&self, net_config: String) -> Result> { + let net_config = Arc::new(serde_json::from_str(&net_config).map_err(api_error)?); + self.vm_action(VmAction::AddNet(net_config)).await + } + + async fn vm_add_pmem(&self, pmem_config: String) -> Result> { + let pmem_config = Arc::new(serde_json::from_str(&pmem_config).map_err(api_error)?); + self.vm_action(VmAction::AddPmem(pmem_config)).await + } + + async fn vm_add_user_device(&self, vm_add_user_device: String) -> Result> { + let vm_add_user_device = + Arc::new(serde_json::from_str(&vm_add_user_device).map_err(api_error)?); + self.vm_action(VmAction::AddUserDevice(vm_add_user_device)) + .await + } + + async fn vm_add_vdpa(&self, vdpa_config: String) -> Result> { + let vdpa_config = Arc::new(serde_json::from_str(&vdpa_config).map_err(api_error)?); + self.vm_action(VmAction::AddVdpa(vdpa_config)).await + } + + async fn vm_add_vsock(&self, vsock_config: String) -> Result> { + let vsock_config = Arc::new(serde_json::from_str(&vsock_config).map_err(api_error)?); + self.vm_action(VmAction::AddVsock(vsock_config)).await + } + + async fn vm_boot(&self) -> Result<()> { + self.vm_action(VmAction::Boot).await.map(|_| ()) + } + + #[allow(unused_variables)] + // zbus doesn't support cfg attributes on interface methods + // as a workaround, we make the *call to the internal API* conditionally + // compile and return an error on unsupported platforms. + async fn vm_coredump(&self, vm_coredump_data: String) -> Result<()> { + #[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] + { + let vm_coredump_data = + Arc::new(serde_json::from_str(&vm_coredump_data).map_err(api_error)?); + self.vm_action(VmAction::Coredump(vm_coredump_data)) + .await + .map(|_| ()) + } + + #[cfg(not(all(target_arch = "x86_64", feature = "guest_debug")))] + Err(api_error( + "VmCoredump only works on x86_64 with the `guest_debug` feature enabled", + )) + } + + async fn vm_counters(&self) -> Result> { + self.vm_action(VmAction::Counters).await + } + + async fn vm_create(&self, vm_config: String) -> Result<()> { + let api_sender = self.clone_api_sender().await; + let api_notifier = self.clone_api_notifier()?; + + let vm_config = Arc::new(Mutex::new( + serde_json::from_str(&vm_config).map_err(api_error)?, + )); + blocking::unblock(move || super::vm_create(api_notifier, api_sender, vm_config)) + .await + .map_err(api_error)?; + + Ok(()) + } + + async fn vm_delete(&self) -> Result<()> { + self.vm_action(VmAction::Delete).await.map(|_| ()) + } + + async fn vm_info(&self) -> Result { + let api_sender = self.clone_api_sender().await; + let api_notifier = self.clone_api_notifier()?; + + let result = blocking::unblock(move || super::vm_info(api_notifier, api_sender)) + .await + .map_err(api_error)?; + serde_json::to_string(&result).map_err(api_error) + } + + async fn vm_pause(&self) -> Result<()> { + self.vm_action(VmAction::Pause).await.map(|_| ()) + } + + async fn vm_power_button(&self) -> Result<()> { + self.vm_action(VmAction::PowerButton).await.map(|_| ()) + } + + async fn vm_reboot(&self) -> Result<()> { + self.vm_action(VmAction::Reboot).await.map(|_| ()) + } + + async fn vm_remove_device(&self, vm_remove_device: String) -> Result<()> { + let vm_remove_device = + Arc::new(serde_json::from_str(&vm_remove_device).map_err(api_error)?); + self.vm_action(VmAction::RemoveDevice(vm_remove_device)) + .await + .map(|_| ()) + } + + async fn vm_resize(&self, vm_resize: String) -> Result<()> { + let vm_resize = Arc::new(serde_json::from_str(&vm_resize).map_err(api_error)?); + self.vm_action(VmAction::Resize(vm_resize)) + .await + .map(|_| ()) + } + + async fn vm_resize_zone(&self, vm_resize_zone: String) -> Result<()> { + let vm_resize_zone = Arc::new(serde_json::from_str(&vm_resize_zone).map_err(api_error)?); + self.vm_action(VmAction::ResizeZone(vm_resize_zone)) + .await + .map(|_| ()) + } + + async fn vm_restore(&self, restore_config: String) -> Result<()> { + let restore_config = Arc::new(serde_json::from_str(&restore_config).map_err(api_error)?); + self.vm_action(VmAction::Restore(restore_config)) + .await + .map(|_| ()) + } + + async fn vm_receive_migration(&self, receive_migration_data: String) -> Result<()> { + let receive_migration_data = + Arc::new(serde_json::from_str(&receive_migration_data).map_err(api_error)?); + self.vm_action(VmAction::ReceiveMigration(receive_migration_data)) + .await + .map(|_| ()) + } + + async fn vm_send_migration(&self, send_migration_data: String) -> Result<()> { + let send_migration_data = + Arc::new(serde_json::from_str(&send_migration_data).map_err(api_error)?); + self.vm_action(VmAction::SendMigration(send_migration_data)) + .await + .map(|_| ()) + } + + async fn vm_resume(&self) -> Result<()> { + self.vm_action(VmAction::Resume).await.map(|_| ()) + } + + async fn vm_shutdown(&self) -> Result<()> { + self.vm_action(VmAction::Shutdown).await.map(|_| ()) + } + + async fn vm_snapshot(&self, vm_snapshot_config: String) -> Result<()> { + let vm_snapshot_config = + Arc::new(serde_json::from_str(&vm_snapshot_config).map_err(api_error)?); + self.vm_action(VmAction::Snapshot(vm_snapshot_config)) + .await + .map(|_| ()) + } +} + +// TODO: add another field to the `seccomp_filters::Thread` enum for the D-Bus API +// TODO: add command line arguments to make this configurable +pub fn start_dbus_thread( + api_notifier: EventFd, + api_sender: Sender, + _seccomp_action: &SeccompAction, + _exit_evt: EventFd, + _hypervisor_type: HypervisorType, +) -> VmmResult>> { + let dbus_iface = DBusApi::new(api_notifier, api_sender); + let connection = executor::block_on(async move { + ConnectionBuilder::session()? + .internal_executor(false) + .name("org.cloudhypervisor.ZBUS")? + .serve_at("/org/cloudhypervisor/ZBUS", dbus_iface)? + .build() + .await + }) + .map_err(VmmError::CreateDBusSession)?; + + thread::Builder::new() + .name("dbus-thread".to_string()) + .spawn(move || { + executor::block_on(async move { + loop { + connection.executor().tick().await; + } + }) + }) + .map_err(VmmError::DBusThreadSpawn) +} diff --git a/vmm/src/api/mod.rs b/vmm/src/api/mod.rs index 2f6d7d42b..8aac5d3cc 100644 --- a/vmm/src/api/mod.rs +++ b/vmm/src/api/mod.rs @@ -28,11 +28,15 @@ //! response channel Receiver. //! 5. The thread handles the response and forwards potential errors. +#[cfg(feature = "dbus_api")] +pub mod dbus; +pub mod http; + +#[cfg(feature = "dbus_api")] +pub use self::dbus::start_dbus_thread; pub use self::http::start_http_fd_thread; pub use self::http::start_http_path_thread; -pub mod http; - use crate::config::{ DeviceConfig, DiskConfig, FsConfig, NetConfig, PmemConfig, RestoreConfig, UserDeviceConfig, VdpaConfig, VmConfig, VsockConfig, diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index 910dbce45..983ba9ec8 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -113,6 +113,16 @@ pub enum Error { #[error("Error spawning HTTP thread: {0}")] HttpThreadSpawn(#[source] io::Error), + /// Cannot create D-Bus thread + #[cfg(feature = "dbus_api")] + #[error("Error spawning D-Bus thread: {0}")] + DBusThreadSpawn(#[source] io::Error), + + /// Cannot start D-Bus session + #[cfg(feature = "dbus_api")] + #[error("Error starting D-Bus session: {0}")] + CreateDBusSession(#[source] zbus::Error), + /// Cannot handle the VM STDIN stream #[error("Error handling VM stdin: {0:?}")] Stdin(VmError), @@ -301,7 +311,7 @@ pub fn start_vmm_thread( #[cfg(feature = "guest_debug")] let gdb_vm_debug_event = vm_debug_event.try_clone().map_err(Error::EventFdClone)?; - let http_api_event = api_event.try_clone().map_err(Error::EventFdClone)?; + let api_event_clone = api_event.try_clone().map_err(Error::EventFdClone)?; let hypervisor_type = hypervisor.hypervisor_type(); // Retrieve seccomp filter @@ -342,11 +352,21 @@ pub fn start_vmm_thread( .map_err(Error::VmmThreadSpawn)? }; - // The VMM thread is started, we can start serving HTTP requests + // The VMM thread is started, we can start the dbus thread + // and start serving HTTP requests + #[cfg(feature = "dbus_api")] + api::start_dbus_thread( + api_event_clone.try_clone().map_err(Error::EventFdClone)?, + api_sender.clone(), + seccomp_action, + exit_event.try_clone().map_err(Error::EventFdClone)?, + hypervisor_type, + )?; + if let Some(http_path) = http_path { api::start_http_path_thread( http_path, - http_api_event, + api_event_clone, api_sender, seccomp_action, exit_event, @@ -355,7 +375,7 @@ pub fn start_vmm_thread( } else if let Some(http_fd) = http_fd { api::start_http_fd_thread( http_fd, - http_api_event, + api_event_clone, api_sender, seccomp_action, exit_event,