From 52c770925cbf53044e48d6e1459534e1dfa9cd2c Mon Sep 17 00:00:00 2001 From: Egor Lazarchuk Date: Tue, 25 Jul 2023 15:55:44 +0000 Subject: [PATCH 01/16] chore: updated baselines for network latency for aarch64 Updated baselines for network latency for aarch64 Signed-off-by: Egor Lazarchuk --- .../configs/test_network_latency_config_6.1.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/integration_tests/performance/configs/test_network_latency_config_6.1.json b/tests/integration_tests/performance/configs/test_network_latency_config_6.1.json index 1a5715decba2..5f742ad3f8d0 100644 --- a/tests/integration_tests/performance/configs/test_network_latency_config_6.1.json +++ b/tests/integration_tests/performance/configs/test_network_latency_config_6.1.json @@ -11,8 +11,8 @@ "1vcpu_1024mb.json": { "Avg": { "ping": { - "delta_percentage": 9.1, - "target": 0.024 + "delta_percentage": 18.1, + "target": 0.026 } } } @@ -23,8 +23,8 @@ "1vcpu_1024mb.json": { "Avg": { "ping": { - "delta_percentage": 9.1, - "target": 0.025 + "delta_percentage": 12.1, + "target": 0.026 } } } @@ -147,8 +147,8 @@ "1vcpu_1024mb.json": { "Avg": { "ping": { - "delta_percentage": 9.1, - "target": 0.028 + "delta_percentage": 6.1, + "target": 0.03 } } } @@ -159,8 +159,8 @@ "1vcpu_1024mb.json": { "Avg": { "ping": { - "delta_percentage": 10.1, - "target": 0.03 + "delta_percentage": 12.1, + "target": 0.032 } } } From d7f59c4a8a51aa07f95fb68af3dcc6cbecbde3f5 Mon Sep 17 00:00:00 2001 From: Marco Cali Date: Tue, 25 Jul 2023 21:05:47 +0100 Subject: [PATCH 02/16] chore: Update Slack invitation link Updated the expired Firecracker slack workspace link in the README with a new valid one. Signed-off-by: Marco Cali --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e50fe30b5f27..b8679af8402d 100644 --- a/README.md +++ b/README.md @@ -171,7 +171,7 @@ You can get in touch with the Firecracker community in the following ways: - Security-related issues, see our [security policy document](SECURITY.md). - Chat with us on our - [Slack workspace](https://join.slack.com/t/firecracker-microvm/shared_invite/zt-1fecwrorm-x5URTlOzBR2fExTU2mWfug) + [Slack workspace](https://join.slack.com/t/firecracker-microvm/shared_invite/zt-1zlb87h4z-NED1rBhVqOQ1ygBgT76wlg) _Note: most of the maintainers are on a European time zone._ - Open a GitHub issue in this repository. - Email the maintainers at From f5c00177b27da506f0d23a358c14b6094acb7ce0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jul 2023 16:24:59 +0000 Subject: [PATCH 03/16] build(deps): Bump the firecracker group with 17 updates Bumps the firecracker group with 17 updates: | Package | Update | | --- | --- | | [clap](https://github.com/clap-rs/clap) | 4.3.11 to 4.3.19 | | [serde](https://github.com/serde-rs/serde) | 1.0.171 to 1.0.175 | | [serde_json](https://github.com/serde-rs/json) | 1.0.100 to 1.0.103 | | [thiserror](https://github.com/dtolnay/thiserror) | 1.0.43 to 1.0.44 | | [aws-lc-rs](https://github.com/awslabs/aws-lc-rs) | 1.2.0 to 1.2.1 | | [either](https://github.com/bluss/either) | 1.8.1 to 1.9.0 | | [equivalent](https://github.com/cuviper/equivalent) | 1.0.0 to 1.0.1 | | [itoa](https://github.com/dtolnay/itoa) | 1.0.8 to 1.0.9 | | [num-traits](https://github.com/rust-num/num-traits) | 0.2.15 to 0.2.16 | | [paste](https://github.com/dtolnay/paste) | 1.0.13 to 1.0.14 | | [prettyplease](https://github.com/dtolnay/prettyplease) | 0.2.10 to 0.2.12 | | [proc-macro2](https://github.com/dtolnay/proc-macro2) | 1.0.64 to 1.0.66 | | [quote](https://github.com/dtolnay/quote) | 1.0.29 to 1.0.32 | | [regex-automata](https://github.com/rust-lang/regex) | 0.3.2 to 0.3.3 | | [ryu](https://github.com/dtolnay/ryu) | 1.0.14 to 1.0.15 | | [toml_edit](https://github.com/toml-rs/toml) | 0.19.12 to 0.19.14 | | [unicode-ident](https://github.com/dtolnay/unicode-ident) | 1.0.10 to 1.0.11 | Updates `clap` from 4.3.11 to 4.3.19 - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v4.3.11...v4.3.19) Updates `serde` from 1.0.171 to 1.0.175 - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.171...v1.0.175) Updates `serde_json` from 1.0.100 to 1.0.103 - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.100...v1.0.103) Updates `thiserror` from 1.0.43 to 1.0.44 - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/1.0.43...1.0.44) Updates `aws-lc-rs` from 1.2.0 to 1.2.1 - [Release notes](https://github.com/awslabs/aws-lc-rs/releases) - [Commits](https://github.com/awslabs/aws-lc-rs/compare/v1.2.0...v1.2.1) Updates `either` from 1.8.1 to 1.9.0 - [Commits](https://github.com/bluss/either/compare/1.8.1...1.9.0) Updates `equivalent` from 1.0.0 to 1.0.1 - [Commits](https://github.com/cuviper/equivalent/compare/v1.0.0...v1.0.1) Updates `itoa` from 1.0.8 to 1.0.9 - [Release notes](https://github.com/dtolnay/itoa/releases) - [Commits](https://github.com/dtolnay/itoa/compare/1.0.8...1.0.9) Updates `num-traits` from 0.2.15 to 0.2.16 - [Changelog](https://github.com/rust-num/num-traits/blob/master/RELEASES.md) - [Commits](https://github.com/rust-num/num-traits/compare/num-traits-0.2.15...num-traits-0.2.16) Updates `paste` from 1.0.13 to 1.0.14 - [Release notes](https://github.com/dtolnay/paste/releases) - [Commits](https://github.com/dtolnay/paste/compare/1.0.13...1.0.14) Updates `prettyplease` from 0.2.10 to 0.2.12 - [Release notes](https://github.com/dtolnay/prettyplease/releases) - [Commits](https://github.com/dtolnay/prettyplease/compare/0.2.10...0.2.12) Updates `proc-macro2` from 1.0.64 to 1.0.66 - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.64...1.0.66) Updates `quote` from 1.0.29 to 1.0.32 - [Release notes](https://github.com/dtolnay/quote/releases) - [Commits](https://github.com/dtolnay/quote/compare/1.0.29...1.0.32) Updates `regex-automata` from 0.3.2 to 0.3.3 - [Release notes](https://github.com/rust-lang/regex/releases) - [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/regex/compare/regex-automata-0.3.2...regex-automata-0.3.3) Updates `ryu` from 1.0.14 to 1.0.15 - [Release notes](https://github.com/dtolnay/ryu/releases) - [Commits](https://github.com/dtolnay/ryu/compare/1.0.14...1.0.15) Updates `toml_edit` from 0.19.12 to 0.19.14 - [Commits](https://github.com/toml-rs/toml/compare/v0.19.12...v0.19.14) Updates `unicode-ident` from 1.0.10 to 1.0.11 - [Release notes](https://github.com/dtolnay/unicode-ident/releases) - [Commits](https://github.com/dtolnay/unicode-ident/compare/1.0.10...1.0.11) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch dependency-group: firecracker - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch dependency-group: firecracker - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch dependency-group: firecracker - dependency-name: thiserror dependency-type: direct:production update-type: version-update:semver-patch dependency-group: firecracker - dependency-name: aws-lc-rs dependency-type: indirect update-type: version-update:semver-patch dependency-group: firecracker - dependency-name: either dependency-type: indirect update-type: version-update:semver-minor dependency-group: firecracker - dependency-name: equivalent dependency-type: indirect update-type: version-update:semver-patch dependency-group: firecracker - dependency-name: itoa dependency-type: indirect update-type: version-update:semver-patch dependency-group: firecracker - dependency-name: num-traits dependency-type: indirect update-type: version-update:semver-patch dependency-group: firecracker - dependency-name: paste dependency-type: indirect update-type: version-update:semver-patch dependency-group: firecracker - dependency-name: prettyplease dependency-type: indirect update-type: version-update:semver-patch dependency-group: firecracker - dependency-name: proc-macro2 dependency-type: indirect update-type: version-update:semver-patch dependency-group: firecracker - dependency-name: quote dependency-type: indirect update-type: version-update:semver-patch dependency-group: firecracker - dependency-name: regex-automata dependency-type: indirect update-type: version-update:semver-patch dependency-group: firecracker - dependency-name: ryu dependency-type: indirect update-type: version-update:semver-patch dependency-group: firecracker - dependency-name: toml_edit dependency-type: indirect update-type: version-update:semver-patch dependency-group: firecracker - dependency-name: unicode-ident dependency-type: indirect update-type: version-update:semver-patch dependency-group: firecracker ... Signed-off-by: dependabot[bot] --- Cargo.lock | 92 +++++++++++++++--------------- src/cpu-template-helper/Cargo.toml | 8 +-- src/firecracker/Cargo.toml | 6 +- src/jailer/Cargo.toml | 2 +- src/seccompiler/Cargo.toml | 6 +- 5 files changed, 57 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 812d3ec4e5e4..c4b8bda9cf7e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -126,9 +126,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "aws-lc-rs" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a36faed486b67c64132841663dc60d11cfaa717bcfdef5530d9109573cbe9a" +checksum = "eea34ec16d470f98567897892db1a7829b51aca0830e930c570dd1589b36c8d2" dependencies = [ "aws-lc-sys", "mirai-annotations", @@ -138,9 +138,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b37b4af8e0c9d68204098ef86a871e1776723be570bfd96e45f9fa52914c2dd" +checksum = "1d6bd58f070795f89c3c66f1cf9446703e4cc8240f894558eaf977f9f89c8a78" dependencies = [ "bindgen 0.66.1", "cmake", @@ -313,9 +313,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.11" +version = "4.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1640e5cc7fb47dbb8338fd471b105e7ed6c3cb2aeb00c2e067127ffd3764a05d" +checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" dependencies = [ "clap_builder", "clap_derive", @@ -324,9 +324,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.11" +version = "4.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98c59138d527eeaf9b53f35a77fcc1fad9d883116070c63d5de1c7dc7b00c72b" +checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" dependencies = [ "anstream", "anstyle", @@ -336,9 +336,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.3.2" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" +checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" dependencies = [ "heck", "proc-macro2", @@ -485,15 +485,15 @@ checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "equivalent" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" @@ -662,9 +662,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "jailer" @@ -856,9 +856,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", "libm", @@ -884,9 +884,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "paste" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "peeking_take_while" @@ -920,9 +920,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "prettyplease" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92139198957b410250d43fad93e630d956499a625c527eda65175c8680f83387" +checksum = "6c64d9ba0963cdcea2e1b2230fbae2bab30eb25a174be395c41e764bfb65dd62" dependencies = [ "proc-macro2", "syn 2.0.25", @@ -930,9 +930,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.64" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] @@ -956,9 +956,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.29" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" dependencies = [ "proc-macro2", ] @@ -1036,9 +1036,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83d3daa6976cffb758ec878f108ba0e062a45b2d6ca3a2cca965338855476caf" +checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" dependencies = [ "aho-corasick", "memchr", @@ -1079,9 +1079,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "same-file" @@ -1106,18 +1106,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.171" +version = "1.0.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" +checksum = "5d25439cd7397d044e2748a6fe2432b5e85db703d6d097bd014b3c0ad1ebff0b" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.171" +version = "1.0.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" +checksum = "b23f7ade6f110613c0d63858ddb8b94c1041f550eab58a16b371bdf2c9c80ab4" dependencies = [ "proc-macro2", "quote", @@ -1126,9 +1126,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.100" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c" +checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b" dependencies = [ "itoa", "ryu", @@ -1203,18 +1203,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" dependencies = [ "proc-macro2", "quote", @@ -1263,9 +1263,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.19.12" +version = "0.19.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ "indexmap", "serde", @@ -1288,9 +1288,9 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-ident" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "universal-hash" @@ -1613,9 +1613,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.4.9" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81a2094c43cc94775293eaa0e499fbc30048a6d824ac82c0351a8c0bf9112529" +checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7" dependencies = [ "memchr", ] diff --git a/src/cpu-template-helper/Cargo.toml b/src/cpu-template-helper/Cargo.toml index c0e3dcf4d5ab..64456c7e57c3 100644 --- a/src/cpu-template-helper/Cargo.toml +++ b/src/cpu-template-helper/Cargo.toml @@ -12,11 +12,11 @@ name = "cpu-template-helper" bench = false [dependencies] -clap = { version = "4.3.11", features = ["derive", "string"] } +clap = { version = "4.3.19", features = ["derive", "string"] } libc = "0.2.147" -serde = { version = "1.0.171", features = ["derive"] } -serde_json = "1.0.100" -thiserror = "1.0.43" +serde = { version = "1.0.175", features = ["derive"] } +serde_json = "1.0.103" +thiserror = "1.0.44" vmm = { path = "../vmm" } diff --git a/src/firecracker/Cargo.toml b/src/firecracker/Cargo.toml index 03f7b3d5bbd8..28211ffb0ae7 100644 --- a/src/firecracker/Cargo.toml +++ b/src/firecracker/Cargo.toml @@ -15,8 +15,8 @@ bench = false [dependencies] event-manager = "0.3.0" libc = "0.2.147" -serde_json = "1.0.100" -thiserror = "1.0.43" +serde_json = "1.0.103" +thiserror = "1.0.44" timerfd = "1.5.0" api_server = { path = "../api_server" } @@ -32,7 +32,7 @@ cargo_toml = "0.15.3" regex = { version = "1.9.1", default-features = false, features = ["std"] } # Dev-Dependencies for uffd examples -serde = { version = "1.0.171", features = ["derive"] } +serde = { version = "1.0.175", features = ["derive"] } userfaultfd = "0.6.0" [[example]] diff --git a/src/jailer/Cargo.toml b/src/jailer/Cargo.toml index bd7fe733f20a..e99ded1eaea3 100644 --- a/src/jailer/Cargo.toml +++ b/src/jailer/Cargo.toml @@ -16,6 +16,6 @@ bench = false libc = "0.2.147" nix = { version = "0.26.2", default-features = false, features = ["dir"] } regex = { version = "1.9.1", default-features = false, features = ["std"] } -thiserror = "1.0.43" +thiserror = "1.0.44" utils = { path = "../utils" } diff --git a/src/seccompiler/Cargo.toml b/src/seccompiler/Cargo.toml index 08b05bf88085..7a33395ffb8c 100644 --- a/src/seccompiler/Cargo.toml +++ b/src/seccompiler/Cargo.toml @@ -19,8 +19,8 @@ bench = false [dependencies] bincode = "1.2.1" libc = "0.2.147" -serde = { version = "1.0.171", features = ["derive"] } -serde_json = "1.0.100" -thiserror = "1.0.43" +serde = { version = "1.0.175", features = ["derive"] } +serde_json = "1.0.103" +thiserror = "1.0.44" utils = { path = "../utils" } From 87e857a5863791c7646160b246dc0a028d91019c Mon Sep 17 00:00:00 2001 From: Egor Lazarchuk Date: Mon, 24 Jul 2023 14:32:11 +0100 Subject: [PATCH 04/16] fix: update to cpu id validation during snapshot restoration Previously `validate_cpu_vendor` and `validate_cpu_manufacturer_id` checks were giving errors only when they could not obtain needed ids from host or guest. The equality checks were only used to print `info` or `error` logs. Now both methods only print logs and can not error out. Signed-off-by: Egor Lazarchuk --- CHANGELOG.md | 3 + src/vmm/src/persist.rs | 117 ++++++++++-------------- src/vmm/tests/integration_tests.rs | 139 ----------------------------- 3 files changed, 50 insertions(+), 209 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d25ec2a7b44..e1c4f9c153bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ - Updated deserialization of `bitmap` for custom CPU templates to allow usage of '_' as a separator. - Changed the strip feature of `cpu-template-helper` tool to operate bitwise. +- Better logs during validation of CPU ID in snapshot restoration path. Also + Firecracker now does not fail if it can't get CPU ID from the host or + can't find CPU ID in the snapshot. ### Fixed diff --git a/src/vmm/src/persist.rs b/src/vmm/src/persist.rs index bbb77a651d52..65b33c3fc113 100644 --- a/src/vmm/src/persist.rs +++ b/src/vmm/src/persist.rs @@ -356,18 +356,6 @@ pub fn get_snapshot_data_version( Ok(data_version) } -/// Error type for [`validate_cpu_vendor`]. -#[cfg(target_arch = "x86_64")] -#[derive(Debug, thiserror::Error, PartialEq, Eq)] -pub enum ValidateCpuVendorError { - /// Failed to read host vendor. - #[error("Failed to read host vendor: {0}")] - Host(#[from] crate::cpu_config::x86_64::cpuid::common::GetCpuidError), - /// Failed to read snapshot vendor. - #[error("Failed to read snapshot vendor")] - Snapshot, -} - /// Validates that snapshot CPU vendor matches the host CPU vendor. /// /// # Errors @@ -376,38 +364,32 @@ pub enum ValidateCpuVendorError { /// - Failed to read host vendor. /// - Failed to read snapshot vendor. #[cfg(target_arch = "x86_64")] -pub fn validate_cpu_vendor(microvm_state: &MicrovmState) -> Result { - let host_vendor_id = get_vendor_id_from_host()?; - - let snapshot_vendor_id = microvm_state.vcpu_states[0] - .cpuid - .vendor_id() - .ok_or(ValidateCpuVendorError::Snapshot)?; - - if host_vendor_id == snapshot_vendor_id { - info!("Snapshot CPU vendor id: {:?}", &snapshot_vendor_id); - Ok(true) - } else { - error!( - "Host CPU vendor id: {:?} differs from the snapshotted one: {:?}", - &host_vendor_id, &snapshot_vendor_id - ); - Ok(false) +pub fn validate_cpu_vendor(microvm_state: &MicrovmState) { + let host_vendor_id = get_vendor_id_from_host(); + let snapshot_vendor_id = microvm_state.vcpu_states[0].cpuid.vendor_id(); + match (host_vendor_id, snapshot_vendor_id) { + (Ok(host_id), Some(snapshot_id)) => { + info!("Host CPU vendor ID: {host_id:?}"); + info!("Snapshot CPU vendor ID: {snapshot_id:?}"); + if host_id != snapshot_id { + warn!("Host CPU vendor ID differs from the snapshotted one",); + } + } + (Ok(host_id), None) => { + info!("Host CPU vendor ID: {host_id:?}"); + warn!("Snapshot CPU vendor ID: couldn't get from the snapshot"); + } + (Err(_), Some(snapshot_id)) => { + warn!("Host CPU vendor ID: couldn't get from the host"); + info!("Snapshot CPU vendor ID: {snapshot_id:?}"); + } + (Err(_), None) => { + warn!("Host CPU vendor ID: couldn't get from the host"); + warn!("Snapshot CPU vendor ID: couldn't get from the snapshot"); + } } } -/// Error type for [`validate_cpu_manufacturer_id`]. -#[cfg(target_arch = "aarch64")] -#[derive(Debug, thiserror::Error, PartialEq, Eq)] -pub enum ValidateCpuManufacturerIdError { - /// Failed to read host vendor. - #[error("Failed to get manufacturer ID from host: {0}")] - Host(String), - /// Failed to read host vendor. - #[error("Failed to get manufacturer ID from state: {0}")] - Snapshot(String), -} - /// Validate that Snapshot Manufacturer ID matches /// the one from the Host /// @@ -418,27 +400,30 @@ pub enum ValidateCpuManufacturerIdError { /// - Failed to read host vendor. /// - Failed to read snapshot vendor. #[cfg(target_arch = "aarch64")] -pub fn validate_cpu_manufacturer_id( - microvm_state: &MicrovmState, -) -> Result { - let host_man_id = get_manufacturer_id_from_host() - .map_err(|err| ValidateCpuManufacturerIdError::Host(err.to_string()))?; - - for state in µvm_state.vcpu_states { - let state_man_id = get_manufacturer_id_from_state(&state.regs) - .map_err(|err| ValidateCpuManufacturerIdError::Snapshot(err.to_string()))?; - - if host_man_id != state_man_id { - error!( - "Host CPU manufacturer ID: {} differs from snapshotted one: {}", - &host_man_id, &state_man_id - ); - return Ok(false); - } else { - info!("Snapshot CPU manufacturer ID: {:?}", &state_man_id); +pub fn validate_cpu_manufacturer_id(microvm_state: &MicrovmState) { + let host_cpu_id = get_manufacturer_id_from_host(); + let snapshot_cpu_id = get_manufacturer_id_from_state(µvm_state.vcpu_states[0].regs); + match (host_cpu_id, snapshot_cpu_id) { + (Ok(host_id), Ok(snapshot_id)) => { + info!("Host CPU manufacturer ID: {host_id:?}"); + info!("Snapshot CPU manufacturer ID: {snapshot_id:?}"); + if host_id != snapshot_id { + warn!("Host CPU manufacturer ID differs from the snapshotted one",); + } + } + (Ok(host_id), Err(_)) => { + info!("Host CPU manufacturer ID: {host_id:?}"); + warn!("Snapshot CPU manufacturer ID: couldn't get from the snapshot"); + } + (Err(_), Ok(snapshot_id)) => { + warn!("Host CPU manufacturer ID: couldn't get from the host"); + info!("Snapshot CPU manufacturer ID: {snapshot_id:?}"); + } + (Err(_), Err(_)) => { + warn!("Host CPU manufacturer ID: couldn't get from the host"); + warn!("Snapshot CPU manufacturer ID: couldn't get from the snapshot"); } } - Ok(true) } /// Error type for [`snapshot_state_sanity_check`]. #[derive(Debug, thiserror::Error, PartialEq, Eq)] @@ -449,14 +434,6 @@ pub enum SnapShotStateSanityCheckError { /// No memory region defined. #[error("No memory region defined.")] NoMemory, - /// Failed to validate vCPU vendor. - #[cfg(target_arch = "x86_64")] - #[error("Failed to validate vCPU vendor: {0}")] - ValidateCpuVendor(#[from] ValidateCpuVendorError), - /// Failed to validate vCPU manufacturer id. - #[error("Failed to validate vCPU manufacturer id: {0}")] - #[cfg(target_arch = "aarch64")] - ValidateCpuManufacturerId(#[from] ValidateCpuManufacturerIdError), } /// Performs sanity checks against the state file and returns specific errors. @@ -478,9 +455,9 @@ pub fn snapshot_state_sanity_check( } #[cfg(target_arch = "x86_64")] - validate_cpu_vendor(microvm_state)?; + validate_cpu_vendor(microvm_state); #[cfg(target_arch = "aarch64")] - validate_cpu_manufacturer_id(microvm_state)?; + validate_cpu_manufacturer_id(microvm_state); Ok(()) } diff --git a/src/vmm/tests/integration_tests.rs b/src/vmm/tests/integration_tests.rs index 6e958a23d3a9..b93da25f4dc9 100644 --- a/src/vmm/tests/integration_tests.rs +++ b/src/vmm/tests/integration_tests.rs @@ -354,142 +354,3 @@ fn get_microvm_state_from_snapshot() -> MicrovmState { ) .unwrap() } - -#[cfg(target_arch = "x86_64")] -#[test] -fn test_snapshot_cpu_vendor() { - use vmm::persist::validate_cpu_vendor; - let microvm_state = get_microvm_state_from_snapshot(); - - // Check if the snapshot created above passes validation since - // the snapshot was created locally. - assert!(validate_cpu_vendor(µvm_state).is_ok()); -} - -#[cfg(target_arch = "x86_64")] -#[test] -fn test_snapshot_cpu_vendor_mismatch() { - use vmm::persist::validate_cpu_vendor; - let mut microvm_state = get_microvm_state_from_snapshot(); - - // Check if the snapshot created above passes validation since - // the snapshot was created locally. - assert_eq!(validate_cpu_vendor(µvm_state), Ok(true)); - - // Modify the vendor id in CPUID. - for entry in microvm_state.vcpu_states[0].cpuid.as_mut_slice().iter_mut() { - if entry.function == 0 && entry.index == 0 { - // Fail if vendor id is NULL as this needs furhter investigation. - assert_ne!(entry.ebx, 0); - assert_ne!(entry.ecx, 0); - assert_ne!(entry.edx, 0); - entry.ebx = 0; - break; - } - } - - // It succeeds in checking if the CPU vendor is valid, in this process it discovers the CPU - // vendor not valid. - assert_eq!(validate_cpu_vendor(µvm_state), Ok(false)); - - // Negative test: remove the vendor id from cpuid. - for entry in microvm_state.vcpu_states[0].cpuid.as_mut_slice().iter_mut() { - if entry.function == 0 && entry.index == 0 { - entry.function = 1234; - } - } - - // It succeeds in checking if the CPU vendor is valid, in this process it discovers the CPU - // vendor not valid. - assert_eq!( - validate_cpu_vendor(µvm_state), - Err(vmm::persist::ValidateCpuVendorError::Snapshot) - ); -} - -#[cfg(target_arch = "x86_64")] -#[test] -fn test_snapshot_cpu_vendor_missing() { - use vmm::persist::validate_cpu_vendor; - let mut microvm_state = get_microvm_state_from_snapshot(); - - // Check if the snapshot created above passes validation since - // the snapshot was created locally. - assert!(validate_cpu_vendor(µvm_state).is_ok()); - - // Negative test: remove the vendor id from cpuid. - for entry in microvm_state.vcpu_states[0].cpuid.as_mut_slice().iter_mut() { - if entry.function == 0 && entry.index == 0 { - entry.function = 1234; - } - } - - // This must fail as the cpu vendor entry does not exist. - assert!(validate_cpu_vendor(µvm_state).is_err()); -} - -#[cfg(target_arch = "aarch64")] -#[test] -fn test_snapshot_cpu_vendor() { - use vmm::persist::validate_cpu_manufacturer_id; - - let microvm_state = get_microvm_state_from_snapshot(); - - // Check if the snapshot created above passes validation since - // the snapshot was created locally. - assert!(validate_cpu_manufacturer_id(µvm_state).is_ok()); -} - -#[cfg(target_arch = "aarch64")] -#[test] -fn test_snapshot_cpu_vendor_missing() { - use vmm::arch::aarch64::regs::{Aarch64RegisterVec, MIDR_EL1}; - use vmm::persist::{validate_cpu_manufacturer_id, ValidateCpuManufacturerIdError}; - - let mut microvm_state = get_microvm_state_from_snapshot(); - - // Check if the snapshot created above passes validation since - // the snapshot was created locally. - assert_eq!(validate_cpu_manufacturer_id(µvm_state), Ok(true)); - - // Manufacturer id is stored in the MIDR_EL1 register. For this test we - // remove it from the state. - for state in microvm_state.vcpu_states.iter_mut() { - let mut new_regs = Aarch64RegisterVec::default(); - // Removing MIDR_EL1 register. - for reg in state.regs.iter() { - if reg.id != MIDR_EL1 { - new_regs.push(reg); - } - } - state.regs = new_regs; - } - assert!(matches!( - validate_cpu_manufacturer_id(µvm_state), - Err(ValidateCpuManufacturerIdError::Snapshot(_)) - )); -} - -#[cfg(target_arch = "aarch64")] -#[test] -fn test_snapshot_cpu_vendor_mismatch() { - use vmm::arch::aarch64::regs::MIDR_EL1; - use vmm::persist::validate_cpu_manufacturer_id; - - let mut microvm_state = get_microvm_state_from_snapshot(); - - // Check if the snapshot created above passes validation since - // the snapshot was created locally. - assert_eq!(validate_cpu_manufacturer_id(µvm_state), Ok(true)); - - // Change the MIDR_EL1 value from the VCPU states, to contain an - // invalid manufacturer ID - for state in microvm_state.vcpu_states.as_mut_slice().iter_mut() { - for mut reg in state.regs.iter_mut() { - if reg.id == MIDR_EL1 { - reg.set_value::(0x710FD081); - } - } - } - assert_eq!(validate_cpu_manufacturer_id(µvm_state), Ok(false)); -} From 7affc0450eccc0f2c9ba9e7d5ccc44077f1dab1d Mon Sep 17 00:00:00 2001 From: "Felipe R. Monteiro" Date: Mon, 24 Jul 2023 17:08:31 +0000 Subject: [PATCH 05/16] Adds stub for read_be_u16 to Kani harnesses The current implementation of read_be_u16 function leads to a significant performance degradation given a necessary loop unrolling. Using this stub, we read the same information from the buffer while avoiding the loop, thus, notably improving performance. Signed-off-by: Felipe R. Monteiro --- src/dumbo/src/pdu/ethernet.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/dumbo/src/pdu/ethernet.rs b/src/dumbo/src/pdu/ethernet.rs index 11367a506abf..2849867cc504 100644 --- a/src/dumbo/src/pdu/ethernet.rs +++ b/src/dumbo/src/pdu/ethernet.rs @@ -238,6 +238,7 @@ mod tests { } #[cfg(kani)] +#[allow(dead_code)] // Avoid warning when using stubs. mod kani_proofs { use utils::net::mac::MAC_ADDR_LEN; @@ -253,6 +254,16 @@ mod kani_proofs { } } + mod stubs { + // The current implementation of read_be_u16 function leads to a significant + // performance degradation given a necessary loop unrolling. Using this stub, + // we read the same information from the buffer while avoiding the loop, thus, + // notably improving performance. + pub fn read_be_u16(input: &[u8]) -> u16 { + u16::from_be_bytes([input[0], input[1]]) + } + } + // We consider the MMDS Network Stack spec for all postconditions in the harnesses. // See https://github.com/firecracker-microvm/firecracker/blob/main/docs/mmds/mmds-design.md#mmds-network-stack @@ -502,8 +513,8 @@ mod kani_proofs { } #[kani::proof] - #[kani::unwind(1515)] #[kani::solver(cadical)] + #[kani::stub(utils::byte_order::read_be_u16, stubs::read_be_u16)] fn verify_with_payload_len_unchecked() { // Create non-deterministic stream of bytes up to MAX_FRAME_SIZE let mut bytes: [u8; MAX_FRAME_SIZE] = kani::Arbitrary::any_array::(); From e97aba7ac8c904b859e96a87b20681b545fa2fef Mon Sep 17 00:00:00 2001 From: Jonathan Woollett-Light Date: Tue, 18 Jul 2023 10:57:35 +0100 Subject: [PATCH 06/16] fix: Move `rate_limiter` into module under `vmm` Moved `rate_limiter` into module under `vmm`. Signed-off-by: Jonathan Woollett-Light --- Cargo.lock | 61 ++++++++++--------- src/rate_limiter/Cargo.toml | 18 ------ src/vmm/Cargo.toml | 1 - src/vmm/src/devices/virtio/block/device.rs | 7 +-- src/vmm/src/devices/virtio/block/persist.rs | 6 +- src/vmm/src/devices/virtio/block/request.rs | 5 +- .../src/devices/virtio/block/test_utils.rs | 2 +- src/vmm/src/devices/virtio/net/device.rs | 5 +- src/vmm/src/devices/virtio/net/persist.rs | 4 +- src/vmm/src/devices/virtio/net/test_utils.rs | 2 +- src/vmm/src/devices/virtio/rng/device.rs | 5 +- src/vmm/src/devices/virtio/rng/persist.rs | 4 +- src/vmm/src/lib.rs | 47 +++++++++++++- .../lib.rs => vmm/src/rate_limiter/mod.rs} | 42 +------------ .../src => vmm/src/rate_limiter}/persist.rs | 0 src/vmm/src/rpc_interface.rs | 12 ++-- src/vmm/src/vmm_config/drive.rs | 2 +- src/vmm/src/vmm_config/entropy.rs | 3 +- src/vmm/src/vmm_config/mod.rs | 3 +- src/vmm/src/vmm_config/net.rs | 3 +- tests/integration_tests/test_kani.py | 2 +- 21 files changed, 109 insertions(+), 125 deletions(-) delete mode 100644 src/rate_limiter/Cargo.toml rename src/{rate_limiter/src/lib.rs => vmm/src/rate_limiter/mod.rs} (95%) rename src/{rate_limiter/src => vmm/src/rate_limiter}/persist.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index c4b8bda9cf7e..3340726c695e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -191,7 +191,7 @@ version = "0.66.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2b84e06fc203107bfbad243f4aba2af864eb7db3b1cf46ea0a023b0b433d2a7" dependencies = [ - "bitflags 2.3.1", + "bitflags 2.3.3", "cexpr", "clang-sys", "lazy_static", @@ -216,9 +216,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.1" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6776fc96284a0bb647b615056fc496d1fe1644a7ab01829818a6d91cae888b84" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" [[package]] name = "byteorder" @@ -641,13 +641,12 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "io-lifetimes", - "rustix", + "rustix 0.38.4", "windows-sys", ] @@ -747,6 +746,12 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +[[package]] +name = "linux-raw-sys" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" + [[package]] name = "log" version = "0.4.19" @@ -1002,18 +1007,6 @@ dependencies = [ "rand_core", ] -[[package]] -name = "rate_limiter" -version = "0.1.0" -dependencies = [ - "logger", - "snapshot", - "timerfd", - "utils", - "versionize", - "versionize_derive", -] - [[package]] name = "rebase-snap" version = "1.5.0-dev" @@ -1031,7 +1024,7 @@ dependencies = [ "aho-corasick", "memchr", "regex-automata", - "regex-syntax 0.7.3", + "regex-syntax 0.7.4", ] [[package]] @@ -1042,7 +1035,7 @@ checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.3", + "regex-syntax 0.7.4", ] [[package]] @@ -1053,9 +1046,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab07dc67230e4a4718e70fd5c20055a4334b121f1f9db8fe63ef39ce9b8c846" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] name = "rustc-hash" @@ -1073,7 +1066,20 @@ dependencies = [ "errno", "io-lifetimes", "libc", - "linux-raw-sys", + "linux-raw-sys 0.3.8", + "windows-sys", +] + +[[package]] +name = "rustix" +version = "0.38.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +dependencies = [ + "bitflags 2.3.3", + "errno", + "libc", + "linux-raw-sys 0.4.3", "windows-sys", ] @@ -1227,7 +1233,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d3fd47d83ad0b5c7be2e8db0b9d712901ef6ce5afbcc6f676761004f5104ea2" dependencies = [ - "rustix", + "rustix 0.37.23", ] [[package]] @@ -1328,7 +1334,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ec82f2a09c9279eb320bd9945f0df0232613d4621c093d8ba02edcb45624fd4" dependencies = [ - "bitflags 2.3.1", + "bitflags 2.3.3", "cfg-if", "libc", "nix", @@ -1444,7 +1450,7 @@ name = "vmm" version = "0.1.0" dependencies = [ "aws-lc-rs", - "bitflags 2.3.1", + "bitflags 2.3.3", "criterion", "derive_more", "device_tree", @@ -1460,7 +1466,6 @@ dependencies = [ "mmds", "net_gen", "proptest", - "rate_limiter", "seccompiler", "serde", "serde_json", diff --git a/src/rate_limiter/Cargo.toml b/src/rate_limiter/Cargo.toml deleted file mode 100644 index 8c9701b32501..000000000000 --- a/src/rate_limiter/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "rate_limiter" -version = "0.1.0" -authors = ["Amazon Firecracker team "] -edition = "2021" -license = "Apache-2.0" - -[lib] -bench = false - -[dependencies] -timerfd = "1.5.0" -versionize = "0.1.10" -versionize_derive = "0.1.5" - -logger = { path = "../logger" } -snapshot = { path = "../snapshot" } -utils = { path = "../utils" } diff --git a/src/vmm/Cargo.toml b/src/vmm/Cargo.toml index 46b605d9be27..e4993331ec43 100644 --- a/src/vmm/Cargo.toml +++ b/src/vmm/Cargo.toml @@ -34,7 +34,6 @@ dumbo = { path = "../dumbo" } logger = { path = "../logger" } mmds = { path = "../mmds" } net_gen = { path = "../net_gen" } -rate_limiter = { path = "../rate_limiter" } seccompiler = { path = "../seccompiler" } snapshot = { path = "../snapshot"} utils = { path = "../utils" } diff --git a/src/vmm/src/devices/virtio/block/device.rs b/src/vmm/src/devices/virtio/block/device.rs index 783428100e6b..387823b5bca8 100644 --- a/src/vmm/src/devices/virtio/block/device.rs +++ b/src/vmm/src/devices/virtio/block/device.rs @@ -15,9 +15,7 @@ use std::sync::atomic::AtomicUsize; use std::sync::Arc; use block_io::FileEngine; -use log::{error, warn}; -use logger::{IncMetric, METRICS}; -use rate_limiter::{BucketUpdate, RateLimiter}; +use logger::{error, warn, IncMetric, METRICS}; use serde::{Deserialize, Serialize}; use utils::eventfd::EventFd; use utils::kernel_version::{min_kernel_version_for_io_uring, KernelVersion}; @@ -35,6 +33,7 @@ use super::{ SECTOR_SIZE, }; use crate::devices::virtio::{IrqTrigger, IrqType}; +use crate::rate_limiter::{BucketUpdate, RateLimiter}; /// Configuration options for disk caching. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Deserialize, Serialize)] @@ -639,7 +638,6 @@ mod tests { use std::time::Duration; use std::{thread, u32}; - use rate_limiter::TokenType; use utils::skip_if_io_uring_unsupported; use utils::tempfile::TempFile; use utils::vm_memory::{Address, Bytes, GuestAddress}; @@ -653,6 +651,7 @@ mod tests { }; use crate::devices::virtio::test_utils::{default_mem, VirtQueue}; use crate::devices::virtio::{IO_URING_NUM_ENTRIES, VIRTQ_DESC_F_NEXT, VIRTQ_DESC_F_WRITE}; + use crate::rate_limiter::TokenType; #[test] fn test_disk_backing_file_helper() { diff --git a/src/vmm/src/devices/virtio/block/persist.rs b/src/vmm/src/devices/virtio/block/persist.rs index 2af5fca95571..c93e5e8e753d 100644 --- a/src/vmm/src/devices/virtio/block/persist.rs +++ b/src/vmm/src/devices/virtio/block/persist.rs @@ -6,9 +6,7 @@ use std::sync::atomic::AtomicUsize; use std::sync::Arc; -use log::warn; -use rate_limiter::persist::RateLimiterState; -use rate_limiter::RateLimiter; +use logger::warn; use snapshot::Persist; use utils::vm_memory::GuestMemoryMmap; use versionize::{VersionMap, Versionize, VersionizeError, VersionizeResult}; @@ -19,6 +17,8 @@ use super::*; use crate::devices::virtio::block::device::FileEngineType; use crate::devices::virtio::persist::VirtioDeviceState; use crate::devices::virtio::{DeviceState, TYPE_BLOCK}; +use crate::rate_limiter::persist::RateLimiterState; +use crate::rate_limiter::RateLimiter; #[derive(Clone, Copy, Debug, PartialEq, Eq, Versionize)] // NOTICE: Any changes to this structure require a snapshot version bump. diff --git a/src/vmm/src/devices/virtio/block/request.rs b/src/vmm/src/devices/virtio/block/request.rs index dd421a443781..170ee6b55363 100644 --- a/src/vmm/src/devices/virtio/block/request.rs +++ b/src/vmm/src/devices/virtio/block/request.rs @@ -7,9 +7,7 @@ use std::convert::From; -use log::error; -use logger::{IncMetric, METRICS}; -use rate_limiter::{RateLimiter, TokenType}; +use logger::{error, IncMetric, METRICS}; use utils::vm_memory::{ByteValued, Bytes, GuestAddress, GuestMemoryError, GuestMemoryMmap}; pub use virtio_gen::virtio_blk::{ VIRTIO_BLK_ID_BYTES, VIRTIO_BLK_S_IOERR, VIRTIO_BLK_S_OK, VIRTIO_BLK_S_UNSUPP, @@ -20,6 +18,7 @@ use super::super::DescriptorChain; use super::{io as block_io, BlockError, SECTOR_SHIFT}; use crate::devices::virtio::block::device::DiskProperties; use crate::devices::virtio::SECTOR_SIZE; +use crate::rate_limiter::{RateLimiter, TokenType}; #[derive(Debug, derive_more::From)] pub enum IoErr { diff --git a/src/vmm/src/devices/virtio/block/test_utils.rs b/src/vmm/src/devices/virtio/block/test_utils.rs index 28252901cefb..4e76d793bee6 100644 --- a/src/vmm/src/devices/virtio/block/test_utils.rs +++ b/src/vmm/src/devices/virtio/block/test_utils.rs @@ -8,7 +8,6 @@ use std::thread; #[cfg(test)] use std::time::Duration; -use rate_limiter::RateLimiter; use utils::kernel_version::{min_kernel_version_for_io_uring, KernelVersion}; use utils::tempfile::TempFile; use utils::vm_memory::{Bytes, GuestAddress}; @@ -21,6 +20,7 @@ use crate::devices::virtio::test_utils::{VirtQueue, VirtqDesc}; #[cfg(test)] use crate::devices::virtio::IrqType; use crate::devices::virtio::{Block, CacheType, Queue, RequestHeader}; +use crate::rate_limiter::RateLimiter; /// Create a default Block instance to be used in tests. pub fn default_block(file_engine_type: FileEngineType) -> Block { diff --git a/src/vmm/src/devices/virtio/net/device.rs b/src/vmm/src/devices/virtio/net/device.rs index 27ff29dcc3bc..d095672fd7b7 100755 --- a/src/vmm/src/devices/virtio/net/device.rs +++ b/src/vmm/src/devices/virtio/net/device.rs @@ -18,7 +18,6 @@ use log::{error, warn}; use logger::{IncMetric, METRICS}; use mmds::data_store::Mmds; use mmds::ns::MmdsNetworkStack; -use rate_limiter::{BucketUpdate, RateLimiter, TokenType}; use utils::eventfd::EventFd; use utils::net::mac::MacAddr; use utils::vm_memory::{ByteValued, Bytes, GuestMemoryError, GuestMemoryMmap}; @@ -29,6 +28,8 @@ use virtio_gen::virtio_net::{ }; use virtio_gen::virtio_ring::VIRTIO_RING_F_EVENT_IDX; +use crate::rate_limiter::{BucketUpdate, RateLimiter, TokenType}; + const FRAME_HEADER_MAX_LEN: usize = PAYLOAD_OFFSET + ETH_IPV4_FRAME_LEN; use crate::devices::virtio::iovec::IoVecBuffer; @@ -841,7 +842,6 @@ pub mod tests { use dumbo::pdu::arp::{EthIPv4ArpFrame, ETH_IPV4_FRAME_LEN}; use dumbo::pdu::ethernet::ETHERTYPE_ARP; use logger::{IncMetric, METRICS}; - use rate_limiter::{RateLimiter, TokenBucket, TokenType}; use utils::net::mac::MAC_ADDR_LEN; use utils::vm_memory::{Address, GuestMemory}; use virtio_gen::virtio_net::{ @@ -864,6 +864,7 @@ pub mod tests { use crate::devices::virtio::{ Net, VirtioDevice, MAX_BUFFER_SIZE, RX_INDEX, TX_INDEX, TYPE_NET, VIRTQ_DESC_F_WRITE, }; + use crate::rate_limiter::{RateLimiter, TokenBucket, TokenType}; impl Net { pub(crate) fn read_tap(&mut self) -> io::Result { diff --git a/src/vmm/src/devices/virtio/net/persist.rs b/src/vmm/src/devices/virtio/net/persist.rs index caa1d57eedfd..584a9b5d9650 100644 --- a/src/vmm/src/devices/virtio/net/persist.rs +++ b/src/vmm/src/devices/virtio/net/persist.rs @@ -11,8 +11,6 @@ use log::warn; use mmds::data_store::Mmds; use mmds::ns::MmdsNetworkStack; use mmds::persist::MmdsNetworkStackState; -use rate_limiter::persist::RateLimiterState; -use rate_limiter::RateLimiter; use snapshot::Persist; use utils::net::mac::{MacAddr, MAC_ADDR_LEN}; use utils::vm_memory::GuestMemoryMmap; @@ -23,6 +21,8 @@ use super::device::Net; use super::{NET_NUM_QUEUES, NET_QUEUE_SIZE}; use crate::devices::virtio::persist::{PersistError as VirtioStateError, VirtioDeviceState}; use crate::devices::virtio::{DeviceState, TYPE_NET}; +use crate::rate_limiter::persist::RateLimiterState; +use crate::rate_limiter::RateLimiter; #[derive(Debug, Default, Clone, Versionize)] // NOTICE: Any changes to this structure require a snapshot version bump. diff --git a/src/vmm/src/devices/virtio/net/test_utils.rs b/src/vmm/src/devices/virtio/net/test_utils.rs index b45dc023cb9a..ee81ad2c32b5 100644 --- a/src/vmm/src/devices/virtio/net/test_utils.rs +++ b/src/vmm/src/devices/virtio/net/test_utils.rs @@ -15,7 +15,6 @@ use std::sync::{Arc, Mutex}; use mmds::data_store::Mmds; use mmds::ns::MmdsNetworkStack; -use rate_limiter::RateLimiter; use utils::net::mac::MacAddr; use utils::vm_memory::{GuestAddress, GuestMemoryMmap}; @@ -25,6 +24,7 @@ use crate::devices::virtio::net::tap::{IfReqBuilder, Tap}; use crate::devices::virtio::test_utils::VirtQueue; use crate::devices::virtio::{Net, Queue, QueueError}; use crate::devices::DeviceError; +use crate::rate_limiter::RateLimiter; static NEXT_INDEX: AtomicUsize = AtomicUsize::new(1); diff --git a/src/vmm/src/devices/virtio/rng/device.rs b/src/vmm/src/devices/virtio/rng/device.rs index f98b70b70772..d10e65e11f36 100644 --- a/src/vmm/src/devices/virtio/rng/device.rs +++ b/src/vmm/src/devices/virtio/rng/device.rs @@ -6,9 +6,7 @@ use std::sync::atomic::AtomicUsize; use std::sync::Arc; use aws_lc_rs::rand; -use log::{debug, error}; -use logger::{IncMetric, METRICS}; -use rate_limiter::{RateLimiter, TokenType}; +use logger::{debug, error, IncMetric, METRICS}; use utils::eventfd::EventFd; use utils::vm_memory::{GuestMemoryError, GuestMemoryMmap}; use virtio_gen::virtio_rng::VIRTIO_F_VERSION_1; @@ -18,6 +16,7 @@ use crate::devices::virtio::device::{IrqTrigger, IrqType}; use crate::devices::virtio::iovec::IoVecBufferMut; use crate::devices::virtio::{ActivateError, DeviceState, Queue, VirtioDevice, TYPE_RNG}; use crate::devices::DeviceError; +use crate::rate_limiter::{RateLimiter, TokenType}; pub const ENTROPY_DEV_ID: &str = "rng"; diff --git a/src/vmm/src/devices/virtio/rng/persist.rs b/src/vmm/src/devices/virtio/rng/persist.rs index b773ce445d0d..e779473328ac 100644 --- a/src/vmm/src/devices/virtio/rng/persist.rs +++ b/src/vmm/src/devices/virtio/rng/persist.rs @@ -3,8 +3,6 @@ //! Defines the structures needed for saving/restoring entropy devices. -use rate_limiter::persist::RateLimiterState; -use rate_limiter::RateLimiter; use snapshot::Persist; use utils::vm_memory::GuestMemoryMmap; use versionize::{VersionMap, Versionize, VersionizeResult}; @@ -13,6 +11,8 @@ use versionize_derive::Versionize; use crate::devices::virtio::persist::PersistError as VirtioStateError; use crate::devices::virtio::rng::{Entropy, EntropyError, RNG_NUM_QUEUES, RNG_QUEUE_SIZE}; use crate::devices::virtio::{VirtioDeviceState, TYPE_RNG}; +use crate::rate_limiter::persist::RateLimiterState; +use crate::rate_limiter::RateLimiter; #[derive(Debug, Clone, Versionize)] pub struct EntropyState { diff --git a/src/vmm/src/lib.rs b/src/vmm/src/lib.rs index fb3def113710..62a0ebac3e97 100644 --- a/src/vmm/src/lib.rs +++ b/src/vmm/src/lib.rs @@ -31,6 +31,48 @@ pub mod arch; /// [This pdf](https://kernel.dk/io_uring.pdf) is also very useful, though outdated at times. pub mod io_uring; +/// # Rate Limiter +/// +/// Provides a rate limiter written in Rust useful for IO operations that need to +/// be throttled. +/// +/// ## Behavior +/// +/// The rate limiter starts off as 'unblocked' with two token buckets configured +/// with the values passed in the `RateLimiter::new()` constructor. +/// All subsequent accounting is done independently for each token bucket based +/// on the `TokenType` used. If any of the buckets runs out of budget, the limiter +/// goes in the 'blocked' state. At this point an internal timer is set up which +/// will later 'wake up' the user in order to retry sending data. The 'wake up' +/// notification will be dispatched as an event on the FD provided by the `AsRawFD` +/// trait implementation. +/// +/// The contract is that the user shall also call the `event_handler()` method on +/// receipt of such an event. +/// +/// The token buckets are replenished when a called `consume()` doesn't find enough +/// tokens in the bucket. The amount of tokens replenished is automatically calculated +/// to respect the `complete_refill_time` configuration parameter provided by the user. +/// The token buckets will never replenish above their respective `size`. +/// +/// Each token bucket can start off with a `one_time_burst` initial extra capacity +/// on top of their `size`. This initial extra credit does not replenish and +/// can be used for an initial burst of data. +/// +/// The granularity for 'wake up' events when the rate limiter is blocked is +/// currently hardcoded to `100 milliseconds`. +/// +/// ## Limitations +/// +/// This rate limiter implementation relies on the *Linux kernel's timerfd* so its +/// usage is limited to Linux systems. +/// +/// Another particularity of this implementation is that it is not self-driving. +/// It is meant to be used in an external event loop and thus implements the `AsRawFd` +/// trait and provides an *event-handler* as part of its API. This *event-handler* +/// needs to be called by the user on every event on the rate limiter's `AsRawFd` FD. +pub mod rate_limiter; + /// Handles setup and initialization a `Vmm` object. pub mod builder; /// Types for guest configuration. @@ -67,9 +109,7 @@ use std::time::Duration; use std::{fmt, io}; use event_manager::{EventManager as BaseEventManager, EventOps, Events, MutEventSubscriber}; -use log::{error, info, warn}; -use logger::{MetricsError, METRICS}; -use rate_limiter::BucketUpdate; +use logger::{error, info, warn, MetricsError, METRICS}; use seccompiler::BpfProgram; use snapshot::Persist; use userfaultfd::Uffd; @@ -92,6 +132,7 @@ use crate::devices::virtio::{ }; use crate::memory_snapshot::SnapshotMemory; use crate::persist::{MicrovmState, MicrovmStateError, VmInfo}; +use crate::rate_limiter::BucketUpdate; use crate::vmm_config::instance_info::{InstanceInfo, VmState}; use crate::vstate::vcpu::VcpuState; pub use crate::vstate::vcpu::{Vcpu, VcpuConfig, VcpuEvent, VcpuHandle, VcpuResponse}; diff --git a/src/rate_limiter/src/lib.rs b/src/vmm/src/rate_limiter/mod.rs similarity index 95% rename from src/rate_limiter/src/lib.rs rename to src/vmm/src/rate_limiter/mod.rs index 85fb2f53ba3a..001f1c5a8ac7 100644 --- a/src/rate_limiter/src/lib.rs +++ b/src/vmm/src/rate_limiter/mod.rs @@ -3,46 +3,6 @@ #![deny(missing_docs)] -//! # Rate Limiter -//! -//! Provides a rate limiter written in Rust useful for IO operations that need to -//! be throttled. -//! -//! ## Behavior -//! -//! The rate limiter starts off as 'unblocked' with two token buckets configured -//! with the values passed in the `RateLimiter::new()` constructor. -//! All subsequent accounting is done independently for each token bucket based -//! on the `TokenType` used. If any of the buckets runs out of budget, the limiter -//! goes in the 'blocked' state. At this point an internal timer is set up which -//! will later 'wake up' the user in order to retry sending data. The 'wake up' -//! notification will be dispatched as an event on the FD provided by the `AsRawFD` -//! trait implementation. -//! -//! The contract is that the user shall also call the `event_handler()` method on -//! receipt of such an event. -//! -//! The token buckets are replenished when a called `consume()` doesn't find enough -//! tokens in the bucket. The amount of tokens replenished is automatically calculated -//! to respect the `complete_refill_time` configuration parameter provided by the user. -//! The token buckets will never replenish above their respective `size`. -//! -//! Each token bucket can start off with a `one_time_burst` initial extra capacity -//! on top of their `size`. This initial extra credit does not replenish and -//! can be used for an initial burst of data. -//! -//! The granularity for 'wake up' events when the rate limiter is blocked is -//! currently hardcoded to `100 milliseconds`. -//! -//! ## Limitations -//! -//! This rate limiter implementation relies on the *Linux kernel's timerfd* so its -//! usage is limited to Linux systems. -//! -//! Another particularity of this implementation is that it is not self-driving. -//! It is meant to be used in an external event loop and thus implements the `AsRawFd` -//! trait and provides an *event-handler* as part of its API. This *event-handler* -//! needs to be called by the user on every event on the rate limiter's `AsRawFd` FD. use std::os::unix::io::{AsRawFd, RawFd}; use std::time::{Duration, Instant}; use std::{fmt, io}; @@ -570,7 +530,7 @@ mod verification { mod stubs { use std::time::Instant; - use crate::TokenBucket; + use crate::rate_limiter::TokenBucket; // On Unix, the Rust Standard Library defines Instants as // diff --git a/src/rate_limiter/src/persist.rs b/src/vmm/src/rate_limiter/persist.rs similarity index 100% rename from src/rate_limiter/src/persist.rs rename to src/vmm/src/rate_limiter/persist.rs diff --git a/src/vmm/src/rpc_interface.rs b/src/vmm/src/rpc_interface.rs index b20e81a0d801..255aa8242e85 100644 --- a/src/vmm/src/rpc_interface.rs +++ b/src/vmm/src/rpc_interface.rs @@ -1190,8 +1190,8 @@ mod tests { pub fn update_block_rate_limiter( &mut self, _: &str, - _: rate_limiter::BucketUpdate, - _: rate_limiter::BucketUpdate, + _: crate::rate_limiter::BucketUpdate, + _: crate::rate_limiter::BucketUpdate, ) -> Result<(), VmmError> { Ok(()) } @@ -1199,10 +1199,10 @@ mod tests { pub fn update_net_rate_limiters( &mut self, _: &str, - _: rate_limiter::BucketUpdate, - _: rate_limiter::BucketUpdate, - _: rate_limiter::BucketUpdate, - _: rate_limiter::BucketUpdate, + _: crate::rate_limiter::BucketUpdate, + _: crate::rate_limiter::BucketUpdate, + _: crate::rate_limiter::BucketUpdate, + _: crate::rate_limiter::BucketUpdate, ) -> Result<(), VmmError> { if self.force_errors { return Err(VmmError::DeviceManager( diff --git a/src/vmm/src/vmm_config/drive.rs b/src/vmm/src/vmm_config/drive.rs index 55102c3fba25..7af40d46609e 100644 --- a/src/vmm/src/vmm_config/drive.rs +++ b/src/vmm/src/vmm_config/drive.rs @@ -222,10 +222,10 @@ impl BlockBuilder { #[cfg(test)] mod tests { - use rate_limiter::RateLimiter; use utils::tempfile::TempFile; use super::*; + use crate::rate_limiter::RateLimiter; impl PartialEq for DriveError { fn eq(&self, other: &DriveError) -> bool { diff --git a/src/vmm/src/vmm_config/entropy.rs b/src/vmm/src/vmm_config/entropy.rs index eb46e4660172..d443f7dcda8a 100644 --- a/src/vmm/src/vmm_config/entropy.rs +++ b/src/vmm/src/vmm_config/entropy.rs @@ -90,9 +90,8 @@ impl EntropyDeviceBuilder { #[cfg(test)] mod tests { - use rate_limiter::RateLimiter; - use super::*; + use crate::rate_limiter::RateLimiter; #[test] fn test_entropy_device_create() { diff --git a/src/vmm/src/vmm_config/mod.rs b/src/vmm/src/vmm_config/mod.rs index e843abfcfc2c..74e9b78baea6 100644 --- a/src/vmm/src/vmm_config/mod.rs +++ b/src/vmm/src/vmm_config/mod.rs @@ -8,9 +8,10 @@ use std::os::unix::fs::OpenOptionsExt; use std::path::Path; use libc::O_NONBLOCK; -use rate_limiter::{BucketUpdate, RateLimiter, TokenBucket}; use serde::{Deserialize, Serialize}; +use crate::rate_limiter::{BucketUpdate, RateLimiter, TokenBucket}; + /// Wrapper for configuring the balloon device. pub mod balloon; /// Wrapper for configuring the microVM boot source. diff --git a/src/vmm/src/vmm_config/net.rs b/src/vmm/src/vmm_config/net.rs index e679cf98709a..6f21ac23064a 100644 --- a/src/vmm/src/vmm_config/net.rs +++ b/src/vmm/src/vmm_config/net.rs @@ -185,9 +185,8 @@ impl NetBuilder { mod tests { use std::str::FromStr; - use rate_limiter::RateLimiter; - use super::*; + use crate::rate_limiter::RateLimiter; impl NetBuilder { pub fn len(&self) -> usize { diff --git a/tests/integration_tests/test_kani.py b/tests/integration_tests/test_kani.py index 412f76510fe9..eab09c0d92c6 100644 --- a/tests/integration_tests/test_kani.py +++ b/tests/integration_tests/test_kani.py @@ -11,7 +11,7 @@ from framework import utils PLATFORM = platform.machine() -CRATES_WITH_PROOFS = ["dumbo", "rate_limiter"] +CRATES_WITH_PROOFS = ["dumbo", "vmm"] @pytest.mark.timeout(1800) From 4c65c30a6340e28b95ded182cd98aa5cb5717b8d Mon Sep 17 00:00:00 2001 From: Patrick Roy Date: Wed, 26 Jul 2023 16:26:25 +0100 Subject: [PATCH 07/16] test: Run unittests in debug mode Running unittests in debug mode gives us greater correctness guarantees, since `debug_assert!`s will be triggered. These are often used to perform "sanity checks" that are supposed to get compiled out in release mode for performance reasons. Additionally, our coverage test runs in debug bug, so this will make the behavior between the two tests consistent (whereas otherwise a failure of one but not the other due to a debug assertion will be confusing). Signed-off-by: Patrick Roy --- tests/integration_tests/build/test_unittests.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/integration_tests/build/test_unittests.py b/tests/integration_tests/build/test_unittests.py index 96fb6cc3ad9b..8bcb80cb5024 100644 --- a/tests/integration_tests/build/test_unittests.py +++ b/tests/integration_tests/build/test_unittests.py @@ -3,6 +3,7 @@ """A test that ensures that all unit tests pass at integration time.""" import platform + import pytest import host_tools.cargo_build as host # pylint:disable=import-error @@ -13,12 +14,13 @@ # run coverage with the `gnu` toolchains and run unit tests with the `musl` toolchains. TARGET = "{}-unknown-linux-musl".format(MACHINE) + @pytest.mark.timeout(600) def test_unittests(test_fc_session_root_path): """ Run unit and doc tests for all supported targets. """ - extra_args = "--release --target {} ".format(TARGET) + extra_args = "--target {} ".format(TARGET) host.cargo_test(test_fc_session_root_path, extra_args=extra_args) From b3632f718bc89c4a6f467b3480d3a91475d67cbe Mon Sep 17 00:00:00 2001 From: Patrick Roy Date: Thu, 27 Jul 2023 08:56:15 +0100 Subject: [PATCH 08/16] fix: specify resolver in Cargo.toml With one of the recent rust toolchain upgrades, we started getting a warning about different defaults for the results (workspaces default to resolver = "1", yet individual crates default to resolver = "2" since edition 2021). To fix this warning, explicitly set the resolver to version 2 in our top level Cargo.toml The change in resolvers is related to how features are merged. Instead of unifying them (meaning that features enabled in dependencies "leak" into other crates), they are now kept disjoint. This is why the regex dev-dependency now needs the `unicode-perl` feature explicitly enabled. [1]: https://doc.rust-lang.org/edition-guide/rust-2021/default-cargo-resolver.html Signed-off-by: Patrick Roy --- Cargo.toml | 1 + src/firecracker/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f84e1e467144..4319867f8cc4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] members = ["src/cpu-template-helper", "src/firecracker", "src/jailer", "src/rebase-snap", "src/seccompiler"] default-members = ["src/firecracker"] +resolver = "2" [profile.dev] panic = "abort" diff --git a/src/firecracker/Cargo.toml b/src/firecracker/Cargo.toml index 28211ffb0ae7..6749bee56fc1 100644 --- a/src/firecracker/Cargo.toml +++ b/src/firecracker/Cargo.toml @@ -29,7 +29,7 @@ vmm = { path = "../vmm" } [dev-dependencies] cargo_toml = "0.15.3" -regex = { version = "1.9.1", default-features = false, features = ["std"] } +regex = { version = "1.9.1", default-features = false, features = ["std", "unicode-perl"] } # Dev-Dependencies for uffd examples serde = { version = "1.0.175", features = ["derive"] } From 4651cd4d9739f424c2596cdacf6c05cf7d4dcf30 Mon Sep 17 00:00:00 2001 From: Diana Popa Date: Mon, 14 Nov 2022 16:12:29 +0200 Subject: [PATCH 09/16] devices: doc for the device bus Doc for the device bus Signed-off-by: Diana Popa --- src/vmm/src/devices/bus.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vmm/src/devices/bus.rs b/src/vmm/src/devices/bus.rs index b44a2f35cf1c..d22e5ef6a5d7 100644 --- a/src/vmm/src/devices/bus.rs +++ b/src/vmm/src/devices/bus.rs @@ -230,6 +230,7 @@ impl Bus { None } + /// Returns the device found at some address. pub fn get_device(&self, addr: u64) -> Option<(u64, &Mutex)> { if let Some((BusRange(start, len), dev)) = self.first_before(addr) { let offset = addr - start; From 3bb3d196b7d8763836cbe077e358b7e83ca299b6 Mon Sep 17 00:00:00 2001 From: Diana Popa Date: Mon, 14 Nov 2022 16:13:40 +0200 Subject: [PATCH 10/16] devices: doc for legacy devices Doc for legacy devices Signed-off-by: Diana Popa --- src/vmm/src/devices/legacy/rtc_pl031.rs | 1 + src/vmm/src/devices/legacy/serial.rs | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vmm/src/devices/legacy/rtc_pl031.rs b/src/vmm/src/devices/legacy/rtc_pl031.rs index bce26ca1e25e..a6b720fadc73 100644 --- a/src/vmm/src/devices/legacy/rtc_pl031.rs +++ b/src/vmm/src/devices/legacy/rtc_pl031.rs @@ -5,6 +5,7 @@ use std::convert::TryInto; use logger::{warn, IncMetric, RTCDeviceMetrics, METRICS}; +/// Wrapper over vm_superio's RTC implementation. #[derive(Debug)] pub struct RTCDevice(pub vm_superio::Rtc<&'static RTCDeviceMetrics>); diff --git a/src/vmm/src/devices/legacy/serial.rs b/src/vmm/src/devices/legacy/serial.rs index 2b132752483b..27a566f3b01c 100644 --- a/src/vmm/src/devices/legacy/serial.rs +++ b/src/vmm/src/devices/legacy/serial.rs @@ -20,10 +20,10 @@ use vm_superio::{Serial, Trigger}; use crate::devices::legacy::EventFdTrigger; -// Received Data Available interrupt - for letting the driver know that -// there is some pending data to be processed. +/// Received Data Available interrupt - for letting the driver know that +/// there is some pending data to be processed. pub const IER_RDA_BIT: u8 = 0b0000_0001; -// Received Data Available interrupt offset +/// Received Data Available interrupt offset pub const IER_RDA_OFFSET: u8 = 1; #[derive(Debug)] From 29eb073d5ea7c357e7ea84ad28f9070b68aa8d33 Mon Sep 17 00:00:00 2001 From: Diana Popa Date: Mon, 14 Nov 2022 16:14:05 +0200 Subject: [PATCH 11/16] devices: doc for the pseudo boot device Doc for the pseudo boot device Signed-off-by: Diana Popa --- src/vmm/src/devices/pseudo/boot_timer.rs | 1 + src/vmm/src/devices/pseudo/mod.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/vmm/src/devices/pseudo/boot_timer.rs b/src/vmm/src/devices/pseudo/boot_timer.rs index 563b67b72380..2551483ea537 100644 --- a/src/vmm/src/devices/pseudo/boot_timer.rs +++ b/src/vmm/src/devices/pseudo/boot_timer.rs @@ -36,6 +36,7 @@ impl BootTimer { } impl BootTimer { + /// Create a device at a certain point in time. pub fn new(start_ts: TimestampUs) -> BootTimer { BootTimer { start_ts } } diff --git a/src/vmm/src/devices/pseudo/mod.rs b/src/vmm/src/devices/pseudo/mod.rs index b62f55b18218..aa4174ea427b 100644 --- a/src/vmm/src/devices/pseudo/mod.rs +++ b/src/vmm/src/devices/pseudo/mod.rs @@ -1,6 +1,7 @@ // Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 +//! Implements Firecracker specific devices (e.g. signal when boot is completed). mod boot_timer; pub use self::boot_timer::BootTimer; From 958a6a9703b3d65358c5e31558e3a0999699c51f Mon Sep 17 00:00:00 2001 From: Diana Popa Date: Mon, 14 Nov 2022 16:14:32 +0200 Subject: [PATCH 12/16] devices: doc for the balloon device Doc for the balloon device Signed-off-by: Diana Popa --- src/vmm/src/devices/virtio/balloon/device.rs | 37 +++++++++++++++++-- src/vmm/src/devices/virtio/balloon/mod.rs | 22 +++++++---- src/vmm/src/devices/virtio/balloon/persist.rs | 8 ++++ 3 files changed, 57 insertions(+), 10 deletions(-) diff --git a/src/vmm/src/devices/virtio/balloon/device.rs b/src/vmm/src/devices/virtio/balloon/device.rs index 7c66d71c6ecf..727c11d0e7a7 100644 --- a/src/vmm/src/devices/virtio/balloon/device.rs +++ b/src/vmm/src/devices/virtio/balloon/device.rs @@ -64,40 +64,63 @@ struct BalloonStat { // SAFETY: Safe because BalloonStat only contains plain data. unsafe impl ByteValued for BalloonStat {} -// BalloonStats holds statistics returned from the stats_queue. +/// Holds configuration details for the balloon device. #[derive(Clone, Default, Debug, PartialEq, Eq, Serialize)] pub struct BalloonConfig { + /// Target size. pub amount_mib: u32, + /// Whether or not to ask for pages back. pub deflate_on_oom: bool, + /// Interval of time in seconds at which the balloon statistics are updated. pub stats_polling_interval_s: u16, } -// BalloonStats holds statistics returned from the stats_queue. +/// BalloonStats holds statistics returned from the stats_queue. #[derive(Clone, Default, Debug, PartialEq, Eq, Serialize)] #[serde(deny_unknown_fields)] pub struct BalloonStats { + /// The target size of the balloon, in 4K pages. pub target_pages: u32, + /// The number of 4K pages the device is currently holding. pub actual_pages: u32, + /// The target size of the balloon, in MiB. pub target_mib: u32, + /// The number of MiB the device is currently holding. pub actual_mib: u32, + /// Amount of memory swapped in. #[serde(skip_serializing_if = "Option::is_none")] pub swap_in: Option, + /// Amount of memory swapped out. #[serde(skip_serializing_if = "Option::is_none")] pub swap_out: Option, + /// Number of major faults. #[serde(skip_serializing_if = "Option::is_none")] pub major_faults: Option, + /// Number of minor faults. #[serde(skip_serializing_if = "Option::is_none")] pub minor_faults: Option, + /// The amount of memory not being used for any + /// purpose (in bytes). #[serde(skip_serializing_if = "Option::is_none")] pub free_memory: Option, + /// Total amount of memory available (in bytes). #[serde(skip_serializing_if = "Option::is_none")] pub total_memory: Option, + /// An estimate of how much memory is available (in + /// bytes) for starting new applications, without pushing the system to swap. #[serde(skip_serializing_if = "Option::is_none")] pub available_memory: Option, + /// The amount of memory, in bytes, that can be + /// quickly reclaimed without additional I/O. Typically these pages are used for + /// caching files from disk. #[serde(skip_serializing_if = "Option::is_none")] pub disk_caches: Option, + /// The number of successful hugetlb page + /// allocations in the guest. #[serde(skip_serializing_if = "Option::is_none")] pub hugetlb_allocations: Option, + /// The number of failed hugetlb page allocations + /// in the guest. #[serde(skip_serializing_if = "Option::is_none")] pub hugetlb_failures: Option, } @@ -125,7 +148,7 @@ impl BalloonStats { } } -// Virtio balloon device. +/// Virtio balloon device. pub struct Balloon { // Virtio fields. pub(crate) avail_features: u64, @@ -175,6 +198,7 @@ impl fmt::Debug for Balloon { } impl Balloon { + /// Instantiate a new balloon device. pub fn new( amount_mib: u32, deflate_on_oom: bool, @@ -419,6 +443,7 @@ impl Balloon { let _ = self.process_deflate_queue(); } + /// Provides the ID of this balloon device. pub fn id(&self) -> &str { BALLOON_DEV_ID } @@ -440,6 +465,7 @@ impl Balloon { } } + /// Update the target size of the balloon. pub fn update_size(&mut self, amount_mib: u32) -> Result<(), BalloonError> { if self.is_activated() { self.config_space.num_pages = mib_to_pages(amount_mib)?; @@ -451,6 +477,7 @@ impl Balloon { } } + /// Update the the statistics polling interval. pub fn update_stats_polling_interval(&mut self, interval_s: u16) -> Result<(), BalloonError> { if self.stats_polling_interval_s == interval_s { return Ok(()); @@ -476,10 +503,12 @@ impl Balloon { .set_state(timer_state, SetTimeFlags::Default); } + /// Obtain the number of 4K pages the device is currently holding. pub fn num_pages(&self) -> u32 { self.config_space.num_pages } + /// Obtain the size of 4K pages the device is currently holding in MIB. pub fn size_mb(&self) -> u32 { pages_to_mib(self.config_space.num_pages) } @@ -492,6 +521,7 @@ impl Balloon { self.stats_polling_interval_s } + /// Retrieve latest stats for the balloon device. pub fn latest_stats(&mut self) -> Option<&BalloonStats> { if self.stats_enabled() { self.latest_stats.target_pages = self.config_space.num_pages; @@ -504,6 +534,7 @@ impl Balloon { } } + /// Return the config of the balloon device. pub fn config(&self) -> BalloonConfig { BalloonConfig { amount_mib: self.size_mb(), diff --git a/src/vmm/src/devices/virtio/balloon/mod.rs b/src/vmm/src/devices/virtio/balloon/mod.rs index aa0ccc87b0ec..c3c9602f0704 100644 --- a/src/vmm/src/devices/virtio/balloon/mod.rs +++ b/src/vmm/src/devices/virtio/balloon/mod.rs @@ -1,6 +1,8 @@ // Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 +//! Implements a virtio balloon device. + pub mod device; mod event_handler; pub mod persist; @@ -14,25 +16,30 @@ pub use self::device::{Balloon, BalloonConfig, BalloonStats}; /// Device ID used in MMIO device identification. /// Because Balloon is unique per-vm, this ID can be hardcoded. pub const BALLOON_DEV_ID: &str = "balloon"; +/// The size of the config space. pub const BALLOON_CONFIG_SPACE_SIZE: usize = 8; +/// Max size of virtio queues. pub const BALLOON_QUEUE_SIZE: u16 = 256; +/// Number of virtio queues. pub const BALLOON_NUM_QUEUES: usize = 3; +/// Virtio queue sizes, in number of descriptor chain heads. +// There are 3 queues for a virtio device (in this order): RX, TX, Event pub const BALLOON_QUEUE_SIZES: [u16; BALLOON_NUM_QUEUES] = [BALLOON_QUEUE_SIZE, BALLOON_QUEUE_SIZE, BALLOON_QUEUE_SIZE]; // Number of 4K pages in a MiB. pub const MIB_TO_4K_PAGES: u32 = 256; -// The maximum number of pages that can be received in a single descriptor. +/// The maximum number of pages that can be received in a single descriptor. pub const MAX_PAGES_IN_DESC: usize = 256; -// The maximum number of pages that can be compacted into ranges during process_inflate(). -// Needs to be a multiple of MAX_PAGES_IN_DESC. +/// The maximum number of pages that can be compacted into ranges during process_inflate(). +/// Needs to be a multiple of MAX_PAGES_IN_DESC. pub const MAX_PAGE_COMPACT_BUFFER: usize = 2048; -// The addresses given by the driver are divided by 4096. +/// The addresses given by the driver are divided by 4096. pub const VIRTIO_BALLOON_PFN_SHIFT: u32 = 12; -// The index of the deflate queue from Balloon device queues/queues_evts vector. +/// The index of the deflate queue from Balloon device queues/queues_evts vector. pub const INFLATE_INDEX: usize = 0; -// The index of the deflate queue from Balloon device queues/queues_evts vector. +/// The index of the deflate queue from Balloon device queues/queues_evts vector. pub const DEFLATE_INDEX: usize = 1; -// The index of the deflate queue from Balloon device queues/queues_evts vector. +/// The index of the deflate queue from Balloon device queues/queues_evts vector. pub const STATS_INDEX: usize = 2; // The feature bitmap for virtio balloon. @@ -51,6 +58,7 @@ const VIRTIO_BALLOON_S_CACHES: u16 = 7; const VIRTIO_BALLOON_S_HTLB_PGALLOC: u16 = 8; const VIRTIO_BALLOON_S_HTLB_PGFAIL: u16 = 9; +/// Balloon device related errors. #[derive(Debug)] pub enum BalloonError { /// Activation error. diff --git a/src/vmm/src/devices/virtio/balloon/persist.rs b/src/vmm/src/devices/virtio/balloon/persist.rs index 05a17b939247..3402538b7299 100644 --- a/src/vmm/src/devices/virtio/balloon/persist.rs +++ b/src/vmm/src/devices/virtio/balloon/persist.rs @@ -18,6 +18,8 @@ use crate::devices::virtio::balloon::device::{BalloonStats, ConfigSpace}; use crate::devices::virtio::persist::VirtioDeviceState; use crate::devices::virtio::{DeviceState, TYPE_BALLOON}; +/// Information about the balloon config's that are saved +/// at snapshot. // NOTICE: Any changes to this structure require a snapshot version bump. #[derive(Debug, Clone, Versionize)] pub struct BalloonConfigSpaceState { @@ -25,6 +27,8 @@ pub struct BalloonConfigSpaceState { actual_pages: u32, } +/// Information about the balloon stats that are saved +/// at snapshot. // NOTICE: Any changes to this structure require a snapshot version bump. #[derive(Debug, Clone, Versionize)] pub struct BalloonStatsState { @@ -76,6 +80,8 @@ impl BalloonStatsState { } } +/// Information about the balloon that are saved +/// at snapshot. // NOTICE: Any changes to this structure require a snapshot version bump. #[derive(Debug, Clone, Versionize)] pub struct BalloonState { @@ -86,8 +92,10 @@ pub struct BalloonState { virtio_state: VirtioDeviceState, } +/// Auxiliary structure for creating a device when resuming from a snapshot. #[derive(Debug)] pub struct BalloonConstructorArgs { + /// Pointer to guest memory. pub mem: GuestMemoryMmap, } From cbf372372de06ae51aae1117ab92b55de343de17 Mon Sep 17 00:00:00 2001 From: Diana Popa Date: Mon, 14 Nov 2022 16:14:54 +0200 Subject: [PATCH 13/16] devices: doc for the virtio block Doc for the virtio block Signed-off-by: Diana Popa --- src/vmm/src/devices/virtio/block/device.rs | 9 +++++++++ src/vmm/src/devices/virtio/block/mod.rs | 15 ++++++++++++--- src/vmm/src/devices/virtio/block/persist.rs | 18 +++++++++++++++--- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/vmm/src/devices/virtio/block/device.rs b/src/vmm/src/devices/virtio/block/device.rs index 387823b5bca8..13370b50731f 100644 --- a/src/vmm/src/devices/virtio/block/device.rs +++ b/src/vmm/src/devices/virtio/block/device.rs @@ -48,6 +48,7 @@ pub enum CacheType { Writeback, } +/// The engine file type, either Sync or Async (through io_uring). #[derive(Debug, PartialEq, Eq, Deserialize, Serialize)] pub enum FileEngineType { /// Use an Async engine, based on io_uring. @@ -63,6 +64,7 @@ impl Default for FileEngineType { } impl FileEngineType { + /// Whether the Async engine is supported on the current host kernel. pub fn is_supported(&self) -> Result { match self { Self::Async if KernelVersion::get()? < min_kernel_version_for_io_uring() => Ok(false), @@ -281,6 +283,10 @@ impl Block { }) } + /// Process a single event in the VirtIO queue. + /// + /// This function is called by the event manager when the guest notifies us + /// about new buffers in the queue. pub(crate) fn process_queue_event(&mut self) { METRICS.block.queue_event_count.inc(); if let Err(err) = self.queue_evts[0].read() { @@ -327,6 +333,7 @@ impl Block { } } + /// Device specific function for peaking inside a queue and processing descriptors. pub fn process_queue(&mut self, queue_index: usize) { // This is safe since we checked in the event handler that the device is activated. let mem = self.device_state.mem().unwrap(); @@ -502,6 +509,7 @@ impl Block { &self.rate_limiter } + /// Retrieve the file engine type. pub fn file_engine_type(&self) -> FileEngineType { match self.disk.file_engine() { FileEngine::Sync(_) => FileEngineType::Sync, @@ -515,6 +523,7 @@ impl Block { } } + /// Prepare device for being snapshotted. pub fn prepare_save(&mut self) { if !self.is_activated() { return; diff --git a/src/vmm/src/devices/virtio/block/mod.rs b/src/vmm/src/devices/virtio/block/mod.rs index d455bd91dd78..d9fb35bd4b2c 100644 --- a/src/vmm/src/devices/virtio/block/mod.rs +++ b/src/vmm/src/devices/virtio/block/mod.rs @@ -1,6 +1,8 @@ // Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 +//! Implements a virtio block device. + pub mod device; mod event_handler; mod io; @@ -14,16 +16,23 @@ pub use self::device::{Block, CacheType}; pub use self::event_handler::*; pub use self::request::*; +/// Size of config space for block device. pub const BLOCK_CONFIG_SPACE_SIZE: usize = 8; +/// Sector shift for block device. pub const SECTOR_SHIFT: u8 = 9; +/// Size of block sector. pub const SECTOR_SIZE: u64 = (0x01_u64) << SECTOR_SHIFT; +/// Queue size for block device. pub const BLOCK_QUEUE_SIZE: u16 = 256; +/// The number of queues of block device. pub const BLOCK_NUM_QUEUES: usize = 1; pub const BLOCK_QUEUE_SIZES: [u16; BLOCK_NUM_QUEUES] = [BLOCK_QUEUE_SIZE]; // The virtio queue can hold up to 256 descriptors, but 1 request spreads across 2-3 descriptors. // So we can use 128 IO_URING entries without ever triggering a FullSq Error. +/// Maximum number of io uring entries we allow in the queue. pub const IO_URING_NUM_ENTRIES: u16 = 128; +/// Errors the block device can trigger. #[derive(Debug)] pub enum BlockError { /// Guest gave us too few descriptors in a descriptor chain. @@ -46,11 +55,11 @@ pub enum BlockError { FileEngine(io::BlockIoError), // Error manipulating the backing file. BackingFile(std::io::Error, String), - // Error opening eventfd. + /// Error opening eventfd. EventFd(std::io::Error), - // Error creating an irqfd. + /// Error creating an irqfd. IrqTrigger(std::io::Error), - // Error coming from the rate limiter. + /// Error coming from the rate limiter. RateLimiter(std::io::Error), // Persistence error. Persist(crate::devices::virtio::persist::PersistError), diff --git a/src/vmm/src/devices/virtio/block/persist.rs b/src/vmm/src/devices/virtio/block/persist.rs index c93e5e8e753d..5733c7628806 100644 --- a/src/vmm/src/devices/virtio/block/persist.rs +++ b/src/vmm/src/devices/virtio/block/persist.rs @@ -20,10 +20,16 @@ use crate::devices::virtio::{DeviceState, TYPE_BLOCK}; use crate::rate_limiter::persist::RateLimiterState; use crate::rate_limiter::RateLimiter; -#[derive(Clone, Copy, Debug, PartialEq, Eq, Versionize)] +/// Holds info about block's cache type. Gets saved in snapshot. // NOTICE: Any changes to this structure require a snapshot version bump. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Versionize)] pub enum CacheTypeState { + /// Flushing mechanic will be advertised to the guest driver, but + /// the operation will be a noop. Unsafe, + /// Flushing mechanic will be advertised to the guest driver and + /// flush requests coming from the guest will be performed using + /// `fsync`. Writeback, } @@ -45,13 +51,16 @@ impl From for CacheType { } } -#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Versionize)] +/// Holds info about block's file engine type. Gets saved in snapshot. // NOTICE: Any changes to this structure require a snapshot version bump. +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Versionize)] pub enum FileEngineTypeState { + /// Sync File Engine. // If the snap version does not contain the `FileEngineType`, it must have been snapshotted // on a VM using the Sync backend. #[default] Sync, + /// Async File Engine. Async, } @@ -73,8 +82,9 @@ impl From for FileEngineType { } } -#[derive(Debug, Clone, Versionize)] +/// Holds info about the block device. Gets saved in snapshot. // NOTICE: Any changes to this structure require a snapshot version bump. +#[derive(Debug, Clone, Versionize)] pub struct BlockState { id: String, partuuid: Option, @@ -112,8 +122,10 @@ impl BlockState { } } +/// Auxiliary structure for creating a device when resuming from a snapshot. #[derive(Debug)] pub struct BlockConstructorArgs { + /// Pointer to guest memory. pub mem: GuestMemoryMmap, } From 4a5dc878d6fe9fb101ea3cc6a0e682477d019f92 Mon Sep 17 00:00:00 2001 From: Diana Popa Date: Mon, 14 Nov 2022 16:15:13 +0200 Subject: [PATCH 14/16] devices: doc for the virtio net Doc for the virtio net Signed-off-by: Diana Popa --- src/vmm/src/devices/virtio/net/device.rs | 18 +++++++++++++++++- src/vmm/src/devices/virtio/net/mod.rs | 10 ++++++++-- src/vmm/src/devices/virtio/net/persist.rs | 13 +++++++++++++ src/vmm/src/devices/virtio/net/tap.rs | 1 + 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/vmm/src/devices/virtio/net/device.rs b/src/vmm/src/devices/virtio/net/device.rs index d095672fd7b7..22abe4dd80b7 100755 --- a/src/vmm/src/devices/virtio/net/device.rs +++ b/src/vmm/src/devices/virtio/net/device.rs @@ -94,10 +94,15 @@ pub struct ConfigSpace { // SAFETY: `ConfigSpace` contains only PODs. unsafe impl ByteValued for ConfigSpace {} +/// VirtIO network device. +/// +/// It emulates a network device able to exchange L2 frames between the guest +/// and a host-side tap device. #[derive(Debug)] pub struct Net { pub(crate) id: String, + /// The backend for this device: a tap. pub tap: Tap, pub(crate) avail_features: u64, @@ -124,10 +129,13 @@ pub struct Net { pub(crate) device_state: DeviceState, pub(crate) activate_evt: EventFd, + /// The MMDS stack corresponding to this interface. + /// Only if MMDS transport has been associated with it. pub mmds_ns: Option, } impl Net { + /// Create a new virtio network device with the given TAP interface. pub fn new_with_tap( id: String, tap: Tap, @@ -181,7 +189,7 @@ impl Net { }) } - /// Create a new virtio network device with the given TAP interface. + /// Create a new virtio network device given the interface name. pub fn new( id: String, tap_if_name: &str, @@ -638,6 +646,10 @@ impl Net { tap.write_iovec(buf) } + /// Process a single RX queue event. + /// + /// This is called by the event manager responding to the guest adding a new + /// buffer in the RX queue. pub fn process_rx_queue_event(&mut self) { METRICS.net.rx_queue_event_count.inc(); @@ -684,6 +696,10 @@ impl Net { } } + /// Process a single TX queue event. + /// + /// This is called by the event manager responding to the guest adding a new + /// buffer in the TX queue. pub fn process_tx_queue_event(&mut self) { METRICS.net.tx_queue_event_count.inc(); if let Err(err) = self.queue_evts[TX_INDEX].read() { diff --git a/src/vmm/src/devices/virtio/net/mod.rs b/src/vmm/src/devices/virtio/net/mod.rs index 931ad91571d5..810d5d7ee942 100644 --- a/src/vmm/src/devices/virtio/net/mod.rs +++ b/src/vmm/src/devices/virtio/net/mod.rs @@ -1,15 +1,20 @@ // Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 +//! Implements a virtio network device. + use std::io; +/// Maximum size of the frame buffers handled by this device. pub const MAX_BUFFER_SIZE: usize = 65562; +/// Queue size for network device. pub const NET_QUEUE_SIZE: u16 = 256; +/// The number of queues of the network device. pub const NET_NUM_QUEUES: usize = 2; pub const NET_QUEUE_SIZES: [u16; NET_NUM_QUEUES] = [NET_QUEUE_SIZE; NET_NUM_QUEUES]; -// The index of the rx queue from Net device queues/queues_evts vector. +/// The index of the rx queue from Net device queues/queues_evts vector. pub const RX_INDEX: usize = 0; -// The index of the tx queue from Net device queues/queues_evts vector. +/// The index of the tx queue from Net device queues/queues_evts vector. pub const TX_INDEX: usize = 1; pub mod device; @@ -32,6 +37,7 @@ pub enum NetQueue { Tx, } +/// Errors the network device can trigger. #[derive(Debug, thiserror::Error)] pub enum NetError { /// Open tap device failed diff --git a/src/vmm/src/devices/virtio/net/persist.rs b/src/vmm/src/devices/virtio/net/persist.rs index 584a9b5d9650..8fd4c14d3223 100644 --- a/src/vmm/src/devices/virtio/net/persist.rs +++ b/src/vmm/src/devices/virtio/net/persist.rs @@ -24,6 +24,8 @@ use crate::devices::virtio::{DeviceState, TYPE_NET}; use crate::rate_limiter::persist::RateLimiterState; use crate::rate_limiter::RateLimiter; +/// Information about the network config's that are saved +/// at snapshot. #[derive(Debug, Default, Clone, Versionize)] // NOTICE: Any changes to this structure require a snapshot version bump. pub struct NetConfigSpaceState { @@ -59,6 +61,8 @@ impl NetConfigSpaceState { } } +/// Information about the network device that are saved +/// at snapshot. #[derive(Debug, Clone, Versionize)] // NOTICE: Any changes to this structure require a snapshot version bump. pub struct NetState { @@ -66,22 +70,31 @@ pub struct NetState { tap_if_name: String, rx_rate_limiter_state: RateLimiterState, tx_rate_limiter_state: RateLimiterState, + /// The associated MMDS network stack. pub mmds_ns: Option, config_space: NetConfigSpaceState, virtio_state: VirtioDeviceState, } +/// Auxiliary structure for creating a device when resuming from a snapshot. #[derive(Debug)] pub struct NetConstructorArgs { + /// Pointer to guest memory. pub mem: GuestMemoryMmap, + /// Pointer to the MMDS data store. pub mmds: Option>>, } +/// Errors triggered when trying to construct a network device at resume time. #[derive(Debug, derive_more::From)] pub enum NetPersistError { + /// Failed to create a network device. CreateNet(super::NetError), + /// Failed to create a rate limiter. CreateRateLimiter(io::Error), + /// Failed to re-create the virtio state (i.e queues etc). VirtioState(VirtioStateError), + /// Indicator that no MMDS is associated with this device. NoMmdsDataStore, } diff --git a/src/vmm/src/devices/virtio/net/tap.rs b/src/vmm/src/devices/virtio/net/tap.rs index 262c04196bb9..23ab26466938 100644 --- a/src/vmm/src/devices/virtio/net/tap.rs +++ b/src/vmm/src/devices/virtio/net/tap.rs @@ -162,6 +162,7 @@ impl Tap { }) } + /// Retrieve the interface's name as a str. pub fn if_name_as_str(&self) -> &str { let len = self .if_name From ac71d456ea1ac05cce59d493096426c32b30d265 Mon Sep 17 00:00:00 2001 From: Diana Popa Date: Mon, 14 Nov 2022 16:15:29 +0200 Subject: [PATCH 15/16] devices: doc for the vsock device Doc for the vsock device Signed-off-by: Diana Popa --- src/vmm/src/devices/virtio/vsock/device.rs | 6 ++++++ src/vmm/src/devices/virtio/vsock/event_handler.rs | 3 ++- src/vmm/src/devices/virtio/vsock/mod.rs | 7 +++++++ src/vmm/src/devices/virtio/vsock/persist.rs | 15 +++++++++++---- src/vmm/src/devices/virtio/vsock/unix/mod.rs | 1 + src/vmm/src/devices/virtio/vsock/unix/muxer.rs | 1 + 6 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/vmm/src/devices/virtio/vsock/device.rs b/src/vmm/src/devices/virtio/vsock/device.rs index e732ab151970..8ca98d92644d 100644 --- a/src/vmm/src/devices/virtio/vsock/device.rs +++ b/src/vmm/src/devices/virtio/vsock/device.rs @@ -50,6 +50,7 @@ pub(crate) const VIRTIO_VSOCK_EVENT_TRANSPORT_RESET: u32 = 0; pub(crate) const AVAIL_FEATURES: u64 = 1 << uapi::VIRTIO_F_VERSION_1 as u64 | 1 << uapi::VIRTIO_F_IN_ORDER as u64; +/// Structure representing the vsock device. #[derive(Debug)] pub struct Vsock { cid: u64, @@ -77,6 +78,8 @@ impl Vsock where B: VsockBackend + Debug, { + /// Auxiliary function for creating a new virtio-vsock device with the given VM CID, vsock + /// backend and empty virtio queues. pub fn with_queues( cid: u64, backend: B, @@ -109,14 +112,17 @@ where Self::with_queues(cid, backend, queues) } + /// Provides the ID of this vsock device as used in MMIO device identification. pub fn id(&self) -> &str { defs::VSOCK_DEV_ID } + /// Retrieve the cid associated with this vsock device. pub fn cid(&self) -> u64 { self.cid } + /// Access the backend behind the device. pub fn backend(&self) -> &B { &self.backend } diff --git a/src/vmm/src/devices/virtio/vsock/event_handler.rs b/src/vmm/src/devices/virtio/vsock/event_handler.rs index 4fe09505c37a..b2e539ee1011 100755 --- a/src/vmm/src/devices/virtio/vsock/event_handler.rs +++ b/src/vmm/src/devices/virtio/vsock/event_handler.rs @@ -102,6 +102,7 @@ where false } + /// Notify backend of new events. pub fn notify_backend(&mut self, evset: EventSet) -> bool { debug!("vsock: backend event"); @@ -109,7 +110,7 @@ where // After the backend has been kicked, it might've freed up some resources, so we // can attempt to send it more data to process. // In particular, if `self.backend.send_pkt()` halted the TX queue processing (by - // reurning an error) at some point in the past, now is the time to try walking the + // returning an error) at some point in the past, now is the time to try walking the // TX queue again. let mut raise_irq = self.process_tx(); if self.backend.has_pending_rx() { diff --git a/src/vmm/src/devices/virtio/vsock/mod.rs b/src/vmm/src/devices/virtio/vsock/mod.rs index 3331329b13d4..a5889389b0ba 100644 --- a/src/vmm/src/devices/virtio/vsock/mod.rs +++ b/src/vmm/src/devices/virtio/vsock/mod.rs @@ -5,6 +5,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the THIRD-PARTY file. +//! The Firecracker vsock device aims to provide full virtio-vsock support to +//! software running inside the guest VM, while bypassing vhost kernel code on the +//! host. To that end, Firecracker implements the virtio-vsock device model, and +//! mediates communication between AF_UNIX sockets (on the host end) and AF_VSOCK +//! sockets (on the guest end). + mod csm; mod device; mod event_handler; @@ -93,6 +99,7 @@ mod defs { } } +/// Vsock device related errors. #[derive(Debug)] pub enum VsockError { /// The vsock data/buffer virtio descriptor length is smaller than expected. diff --git a/src/vmm/src/devices/virtio/vsock/persist.rs b/src/vmm/src/devices/virtio/vsock/persist.rs index b28e4e9bc2dd..7d188b58c684 100644 --- a/src/vmm/src/devices/virtio/vsock/persist.rs +++ b/src/vmm/src/devices/virtio/vsock/persist.rs @@ -16,30 +16,35 @@ use super::*; use crate::devices::virtio::persist::VirtioDeviceState; use crate::devices::virtio::{DeviceState, TYPE_VSOCK}; +/// The Vsock serializable state. // NOTICE: Any changes to this structure require a snapshot version bump. #[derive(Debug, Clone, Versionize)] pub struct VsockState { + /// The vsock backend state. pub backend: VsockBackendState, + /// The vsock frontend state. pub frontend: VsockFrontendState, } +/// The Vsock frontend serializable state. // NOTICE: Any changes to this structure require a snapshot version bump. -/// The Vsock serializable state. #[derive(Debug, Clone, Versionize)] pub struct VsockFrontendState { + /// Context IDentifier. pub cid: u64, virtio_state: VirtioDeviceState, } -// NOTICE: Any changes to this structure require a snapshot version bump. /// An enum for the serializable backend state types. +// NOTICE: Any changes to this structure require a snapshot version bump. #[derive(Debug, Clone, Versionize)] pub enum VsockBackendState { + /// UDS backend state. Uds(VsockUdsState), } -// NOTICE: Any changes to this structure require a snapshot version bump. /// The Vsock Unix Backend serializable state. +// NOTICE: Any changes to this structure require a snapshot version bump. #[derive(Debug, Clone, Versionize)] pub struct VsockUdsState { /// The path for the UDS socket. @@ -49,14 +54,16 @@ pub struct VsockUdsState { /// A helper structure that holds the constructor arguments for VsockUnixBackend #[derive(Debug)] pub struct VsockConstructorArgs { + /// Pointer to guest memory. pub mem: GuestMemoryMmap, + /// The vsock Unix Backend. pub backend: B, } /// A helper structure that holds the constructor arguments for VsockUnixBackend #[derive(Debug)] pub struct VsockUdsConstructorArgs { - // cid available in VsockFrontendState. + /// cid available in VsockFrontendState. pub cid: u64, } diff --git a/src/vmm/src/devices/virtio/vsock/unix/mod.rs b/src/vmm/src/devices/virtio/vsock/unix/mod.rs index 250d75b47404..9bc20924841c 100644 --- a/src/vmm/src/devices/virtio/vsock/unix/mod.rs +++ b/src/vmm/src/devices/virtio/vsock/unix/mod.rs @@ -26,6 +26,7 @@ mod defs { pub const MUXER_KILLQ_SIZE: usize = 128; } +/// Vsock backend related errors. #[derive(Debug)] pub enum VsockUnixBackendError { /// Error registering a new epoll-listening FD. diff --git a/src/vmm/src/devices/virtio/vsock/unix/muxer.rs b/src/vmm/src/devices/virtio/vsock/unix/muxer.rs index a23ad77237b6..005df93a7f06 100644 --- a/src/vmm/src/devices/virtio/vsock/unix/muxer.rs +++ b/src/vmm/src/devices/virtio/vsock/unix/muxer.rs @@ -329,6 +329,7 @@ impl VsockMuxer { Ok(muxer) } + /// Return the file system path of the host-side Unix socket. pub fn host_sock_path(&self) -> &str { &self.host_sock_path } From 24adb76b907eb6b2690d5a4da1ced7cdd84d72f5 Mon Sep 17 00:00:00 2001 From: Diana Popa Date: Mon, 14 Nov 2022 16:17:18 +0200 Subject: [PATCH 16/16] doc: final changes for having doc on devices Final changes for having doc on devices Signed-off-by: Diana Popa --- src/vmm/src/device_manager/mmio.rs | 2 +- src/vmm/src/devices/bus.rs | 1 + src/vmm/src/devices/mod.rs | 3 +++ src/vmm/src/devices/virtio/device.rs | 4 ++++ src/vmm/src/devices/virtio/mmio.rs | 3 ++- src/vmm/src/devices/virtio/mod.rs | 11 +++++++++++ src/vmm/src/devices/virtio/persist.rs | 14 ++++++++++++++ src/vmm/src/devices/virtio/queue.rs | 2 ++ 8 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/vmm/src/device_manager/mmio.rs b/src/vmm/src/device_manager/mmio.rs index a9973a11d86d..87a6811e0981 100644 --- a/src/vmm/src/device_manager/mmio.rs +++ b/src/vmm/src/device_manager/mmio.rs @@ -313,7 +313,7 @@ impl MMIODeviceManager { irq_number } - /// Gets the the specified device. + /// Gets the specified device. pub fn get_device( &self, device_type: DeviceType, diff --git a/src/vmm/src/devices/bus.rs b/src/vmm/src/devices/bus.rs index d22e5ef6a5d7..b5d91545d2b7 100644 --- a/src/vmm/src/devices/bus.rs +++ b/src/vmm/src/devices/bus.rs @@ -11,6 +11,7 @@ use std::cmp::{Ord, Ordering, PartialEq, PartialOrd}; use std::collections::btree_map::BTreeMap; use std::sync::{Arc, Mutex}; +/// Errors triggered during bus operations. #[derive(Debug, thiserror::Error)] pub enum BusError { /// The insertion failed because the new device overlapped with an old device. diff --git a/src/vmm/src/devices/mod.rs b/src/vmm/src/devices/mod.rs index e28b97156055..b4e46743db76 100644 --- a/src/vmm/src/devices/mod.rs +++ b/src/vmm/src/devices/mod.rs @@ -4,6 +4,9 @@ // Portions Copyright 2017 The Chromium OS Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the THIRD-PARTY file. + +//! Emulates virtual and hardware devices. + use std::io; pub mod bus; diff --git a/src/vmm/src/devices/virtio/device.rs b/src/vmm/src/devices/virtio/device.rs index 8a0c648816a5..2b68df2530f7 100644 --- a/src/vmm/src/devices/virtio/device.rs +++ b/src/vmm/src/devices/virtio/device.rs @@ -42,9 +42,12 @@ impl DeviceState { } } +/// The 2 types of interrupt sources in MMIO transport. #[derive(Debug)] pub enum IrqType { + /// Interrupt triggered by change in config. Config, + /// Interrupt triggered by used vring buffers. Vring, } @@ -97,6 +100,7 @@ pub trait VirtioDevice: AsAny + Send { /// - self.avail_features() & self.acked_features() = self.get_acked_features() fn set_acked_features(&mut self, acked_features: u64); + /// Check if virtio device has negotiated given feature. fn has_feature(&self, feature: u64) -> bool { (self.acked_features() & 1 << feature) != 0 } diff --git a/src/vmm/src/devices/virtio/mmio.rs b/src/vmm/src/devices/virtio/mmio.rs index 315888fda74a..b7632f88a1f1 100644 --- a/src/vmm/src/devices/virtio/mmio.rs +++ b/src/vmm/src/devices/virtio/mmio.rs @@ -74,11 +74,12 @@ impl MmioTransport { } } + /// Gets the encapsulated locked VirtioDevice. pub fn locked_device(&self) -> MutexGuard { self.device.lock().expect("Poisoned lock") } - // Gets the encapsulated VirtioDevice. + /// Gets the encapsulated VirtioDevice. pub fn device(&self) -> Arc> { self.device.clone() } diff --git a/src/vmm/src/devices/virtio/mod.rs b/src/vmm/src/devices/virtio/mod.rs index 645c9701bb15..79d159ab74c6 100644 --- a/src/vmm/src/devices/virtio/mod.rs +++ b/src/vmm/src/devices/virtio/mod.rs @@ -6,6 +6,7 @@ // found in the THIRD-PARTY file. //! Implements virtio devices, queues, and transport mechanisms. + use std::any::Any; use std::io::Error as IOError; @@ -50,27 +51,37 @@ mod device_status { /// Types taken from linux/virtio_ids.h. /// Type 0 is not used by virtio. Use it as wildcard for non-virtio devices +/// Virtio net device ID. pub const TYPE_NET: u32 = 1; +/// Virtio block device ID. pub const TYPE_BLOCK: u32 = 2; +/// Virtio rng device ID. pub const TYPE_RNG: u32 = 4; +/// Virtio balloon device ID. pub const TYPE_BALLOON: u32 = 5; /// Offset from the base MMIO address of a virtio device used by the guest to notify the device of /// queue events. pub const NOTIFY_REG_OFFSET: u32 = 0x50; +/// Errors triggered when activating a VirtioDevice. #[derive(Debug)] pub enum ActivateError { + /// Epoll error. EpollCtl(IOError), + /// General error at activation. BadActivate, } /// Trait that helps in upcasting an object to Any pub trait AsAny { + /// Return the immutable any encapsulated object. fn as_any(&self) -> &dyn Any; + /// Return the mutable encapsulated any object. fn as_mut_any(&mut self) -> &mut dyn Any; } + impl AsAny for T { fn as_any(&self) -> &dyn Any { self diff --git a/src/vmm/src/devices/virtio/persist.rs b/src/vmm/src/devices/virtio/persist.rs index e11bf0d806f0..ed411dcd05fd 100644 --- a/src/vmm/src/devices/virtio/persist.rs +++ b/src/vmm/src/devices/virtio/persist.rs @@ -18,11 +18,14 @@ use super::device::*; use super::queue::*; use crate::devices::virtio::MmioTransport; +/// Errors thrown during restoring virtio state. #[derive(Debug)] pub enum PersistError { + /// Snapshot state contains invalid queue info. InvalidInput, } +/// Queue information saved in snapshot. #[derive(Clone, Debug, PartialEq, Eq, Versionize)] // NOTICE: Any changes to this structure require a snapshot version bump. pub struct QueueState { @@ -91,15 +94,22 @@ impl Persist<'_> for Queue { #[derive(Clone, Debug, Default, PartialEq, Eq, Versionize)] // NOTICE: Any changes to this structure require a snapshot version bump. pub struct VirtioDeviceState { + /// Device type. pub device_type: u32, + /// Available virtio features. pub avail_features: u64, + /// Negotiated virtio features. pub acked_features: u64, + /// List of queues. pub queues: Vec, + /// The MMIO interrupt status. pub interrupt_status: usize, + /// Flag for activated status. pub activated: bool, } impl VirtioDeviceState { + /// Construct the virtio state of a device. pub fn from_device(device: &dyn VirtioDevice) -> Self { VirtioDeviceState { device_type: device.device_type(), @@ -162,6 +172,7 @@ impl VirtioDeviceState { } } +/// Transport information saved in snapshot. #[derive(Clone, Debug, PartialEq, Eq, Versionize)] // NOTICE: Any changes to this structure require a snapshot version bump. pub struct MmioTransportState { @@ -174,9 +185,12 @@ pub struct MmioTransportState { config_generation: u32, } +/// Auxiliary structure for initializing the transport when resuming from a snapshot. #[derive(Debug)] pub struct MmioTransportConstructorArgs { + /// Pointer to guest memory. pub mem: GuestMemoryMmap, + /// Device associated with the current MMIO state. pub device: Arc>, } diff --git a/src/vmm/src/devices/virtio/queue.rs b/src/vmm/src/devices/virtio/queue.rs index 35ee57fec009..0f45ec41dd58 100644 --- a/src/vmm/src/devices/virtio/queue.rs +++ b/src/vmm/src/devices/virtio/queue.rs @@ -223,6 +223,7 @@ impl Queue { } } + /// Maximum size of the queue. pub fn get_max_size(&self) -> u16 { self.max_size } @@ -233,6 +234,7 @@ impl Queue { min(self.size, self.max_size) } + /// Validates that the queue's representation is correct. pub fn is_valid(&self, mem: &GuestMemoryMmap) -> bool { let queue_size = u64::from(self.actual_size()); let desc_table = self.desc_table;