diff --git a/Cargo.lock b/Cargo.lock index f62ab44e4..9fa481e4c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -157,12 +157,12 @@ dependencies = [ [[package]] name = "api_identity" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#dea7eb6f4626c55defe629a4a70a05f7def36182" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#758818aea3f0d375b6bbf9bd87f713a5da09ffbd" dependencies = [ "omicron-workspace-hack", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -197,7 +197,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -219,7 +219,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -230,7 +230,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -307,7 +307,25 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" name = "bhyve_api" version = "0.0.0" dependencies = [ - "bhyve_api_sys", + "bhyve_api_sys 0.0.0", + "libc", + "strum", +] + +[[package]] +name = "bhyve_api" +version = "0.0.0" +source = "git+https://github.com/oxidecomputer/propolis?rev=24a74d0c76b6a63961ecef76acb1516b6e66c5c9#24a74d0c76b6a63961ecef76acb1516b6e66c5c9" +dependencies = [ + "bhyve_api_sys 0.0.0 (git+https://github.com/oxidecomputer/propolis?rev=24a74d0c76b6a63961ecef76acb1516b6e66c5c9)", + "libc", + "strum", +] + +[[package]] +name = "bhyve_api_sys" +version = "0.0.0" +dependencies = [ "libc", "strum", ] @@ -315,6 +333,7 @@ dependencies = [ [[package]] name = "bhyve_api_sys" version = "0.0.0" +source = "git+https://github.com/oxidecomputer/propolis?rev=24a74d0c76b6a63961ecef76acb1516b6e66c5c9#24a74d0c76b6a63961ecef76acb1516b6e66c5c9" dependencies = [ "libc", "strum", @@ -343,9 +362,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" dependencies = [ "serde", ] @@ -439,22 +458,32 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.1" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" dependencies = [ "serde", ] [[package]] name = "camino" -version = "1.1.7" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" dependencies = [ "serde", ] +[[package]] +name = "camino-tempfile" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb905055fa81e4d427f919b2cd0d76a998267de7d225ea767a1894743a5263c2" +dependencies = [ + "camino", + "tempfile", +] + [[package]] name = "cargo-platform" version = "0.1.8" @@ -501,6 +530,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chrono" version = "0.4.38" @@ -558,7 +593,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -567,12 +602,28 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + [[package]] name = "colorchoice" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +[[package]] +name = "colored" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +dependencies = [ + "lazy_static", + "windows-sys 0.48.0", +] + [[package]] name = "console" version = "0.15.8" @@ -612,6 +663,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "time", + "version_check", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -693,7 +754,7 @@ checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "crucible" version = "0.0.1" -source = "git+https://github.com/oxidecomputer/crucible?rev=e58ca3693cb9ce0438947beba10e97ee38a0966b#e58ca3693cb9ce0438947beba10e97ee38a0966b" +source = "git+https://github.com/oxidecomputer/crucible?rev=d037eeb9a56a8a62ff17266f340c011224d15146#d037eeb9a56a8a62ff17266f340c011224d15146" dependencies = [ "aes-gcm-siv", "anyhow", @@ -713,7 +774,7 @@ dependencies = [ "futures-core", "http 0.2.12", "internal-dns", - "itertools", + "itertools 0.13.0", "libc", "nexus-client", "omicron-common", @@ -736,7 +797,7 @@ dependencies = [ "tokio", "tokio-rustls 0.24.1", "tokio-util", - "toml 0.8.15", + "toml 0.8.19", "tracing", "usdt 0.5.0", "uuid", @@ -746,7 +807,7 @@ dependencies = [ [[package]] name = "crucible-client-types" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/crucible?rev=e58ca3693cb9ce0438947beba10e97ee38a0966b#e58ca3693cb9ce0438947beba10e97ee38a0966b" +source = "git+https://github.com/oxidecomputer/crucible?rev=d037eeb9a56a8a62ff17266f340c011224d15146#d037eeb9a56a8a62ff17266f340c011224d15146" dependencies = [ "base64 0.22.1", "crucible-workspace-hack", @@ -759,13 +820,13 @@ dependencies = [ [[package]] name = "crucible-common" version = "0.0.1" -source = "git+https://github.com/oxidecomputer/crucible?rev=e58ca3693cb9ce0438947beba10e97ee38a0966b#e58ca3693cb9ce0438947beba10e97ee38a0966b" +source = "git+https://github.com/oxidecomputer/crucible?rev=d037eeb9a56a8a62ff17266f340c011224d15146#d037eeb9a56a8a62ff17266f340c011224d15146" dependencies = [ "anyhow", "atty", "crucible-workspace-hack", "dropshot", - "nix 0.28.0", + "nix 0.29.0", "rusqlite", "rustls-pemfile 1.0.4", "schemars", @@ -780,7 +841,7 @@ dependencies = [ "thiserror", "tokio", "tokio-rustls 0.24.1", - "toml 0.8.15", + "toml 0.8.19", "twox-hash", "uuid", "vergen", @@ -789,7 +850,7 @@ dependencies = [ [[package]] name = "crucible-protocol" version = "0.0.0" -source = "git+https://github.com/oxidecomputer/crucible?rev=e58ca3693cb9ce0438947beba10e97ee38a0966b#e58ca3693cb9ce0438947beba10e97ee38a0966b" +source = "git+https://github.com/oxidecomputer/crucible?rev=d037eeb9a56a8a62ff17266f340c011224d15146#d037eeb9a56a8a62ff17266f340c011224d15146" dependencies = [ "anyhow", "bincode", @@ -805,6 +866,18 @@ dependencies = [ "uuid", ] +[[package]] +name = "crucible-smf" +version = "0.0.0" +source = "git+https://github.com/oxidecomputer/crucible?rev=e58ca3693cb9ce0438947beba10e97ee38a0966b#e58ca3693cb9ce0438947beba10e97ee38a0966b" +dependencies = [ + "crucible-workspace-hack", + "libc", + "num-derive 0.4.2", + "num-traits", + "thiserror", +] + [[package]] name = "crucible-workspace-hack" version = "0.1.0" @@ -832,6 +905,16 @@ dependencies = [ "phf 0.11.2", ] +[[package]] +name = "cstr-argument" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bd9c8e659a473bce955ae5c35b116af38af11a7acb0b480e01f3ed348aeb40" +dependencies = [ + "cfg-if", + "memchr", +] + [[package]] name = "ctr" version = "0.9.2" @@ -872,7 +955,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -883,7 +966,7 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ "darling_core", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -898,6 +981,38 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffe7ed1d93f4553003e20b629abe9085e1e81b1429520f897f8f8860bc6dfc21" +[[package]] +name = "defmt" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a99dd22262668b887121d4672af5a64b238f026099f1a2a1b322066c9ecfe9e0" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9f309eff1f79b3ebdf252954d90ae440599c26c2c553fe87a2d17195f2dcb" +dependencies = [ + "defmt-parser", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.75", +] + +[[package]] +name = "defmt-parser" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4a5fefe330e8d7f31b16a318f9ce81000d8e35e69b93eae154d16d2278f70f" +dependencies = [ + "thiserror", +] + [[package]] name = "deltae" version = "0.3.2" @@ -922,7 +1037,7 @@ checksum = "62d671cc41a825ebabc75757b62d3d168c577f9149b2d49ece1dad1f72119d25" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -935,7 +1050,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.0", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -1013,7 +1128,20 @@ version = "0.2.0" source = "git+https://github.com/oxidecomputer/dlpi-sys?branch=main#1d587ea98cf2d36f1b1624b0b960559c76d475d2" dependencies = [ "libc", - "libdlpi-sys", + "libdlpi-sys 0.1.0 (git+https://github.com/oxidecomputer/dlpi-sys?branch=main)", + "num_enum 0.5.11", + "pretty-hex 0.2.1", + "thiserror", + "tokio", +] + +[[package]] +name = "dlpi" +version = "0.2.0" +source = "git+https://github.com/oxidecomputer/dlpi-sys#1d587ea98cf2d36f1b1624b0b960559c76d475d2" +dependencies = [ + "libc", + "libdlpi-sys 0.1.0 (git+https://github.com/oxidecomputer/dlpi-sys)", "num_enum 0.5.11", "pretty-hex 0.2.1", "thiserror", @@ -1023,7 +1151,7 @@ dependencies = [ [[package]] name = "dns-service-client" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#dea7eb6f4626c55defe629a4a70a05f7def36182" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#758818aea3f0d375b6bbf9bd87f713a5da09ffbd" dependencies = [ "anyhow", "chrono", @@ -1069,8 +1197,8 @@ checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" [[package]] name = "dropshot" -version = "0.10.2-dev" -source = "git+https://github.com/oxidecomputer/dropshot?branch=main#7b594d01f47ca783c5d4a25ca2b256602580fe92" +version = "0.11.1-dev" +source = "git+https://github.com/oxidecomputer/dropshot?branch=main#a8f3f97a2eec06765893d43ede6f811ccc7949ea" dependencies = [ "async-stream", "async-trait", @@ -1085,13 +1213,13 @@ dependencies = [ "hostname 0.4.0", "http 0.2.12", "hyper", - "indexmap 2.2.6", + "indexmap 2.4.0", "multer", "openapiv3", "paste", "percent-encoding", "rustls 0.22.4", - "rustls-pemfile 2.1.2", + "rustls-pemfile 2.1.3", "schemars", "scopeguard", "serde", @@ -1106,7 +1234,7 @@ dependencies = [ "slog-term", "tokio", "tokio-rustls 0.25.0", - "toml 0.8.15", + "toml 0.8.19", "usdt 0.5.0", "uuid", "version_check", @@ -1115,15 +1243,15 @@ dependencies = [ [[package]] name = "dropshot_endpoint" -version = "0.10.2-dev" -source = "git+https://github.com/oxidecomputer/dropshot?branch=main#7b594d01f47ca783c5d4a25ca2b256602580fe92" +version = "0.11.1-dev" +source = "git+https://github.com/oxidecomputer/dropshot?branch=main#a8f3f97a2eec06765893d43ede6f811ccc7949ea" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", "serde", - "serde_tokenstream 0.2.1", - "syn 2.0.71", + "serde_tokenstream 0.2.2", + "syn 2.0.75", ] [[package]] @@ -1160,6 +1288,18 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + [[package]] name = "encode_unicode" version = "0.3.6" @@ -1177,14 +1317,14 @@ dependencies = [ [[package]] name = "enum-as-inner" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9720bba047d567ffc8a3cba48bf19126600e249ab7f128e9233e6376976a116" +checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.75", ] [[package]] @@ -1359,7 +1499,28 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "foreign-types-shared", + "foreign-types-shared 0.1.1", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared 0.3.1", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.75", ] [[package]] @@ -1368,6 +1529,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -1445,7 +1612,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -1481,7 +1648,7 @@ dependencies = [ [[package]] name = "gateway-client" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#dea7eb6f4626c55defe629a4a70a05f7def36182" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#758818aea3f0d375b6bbf9bd87f713a5da09ffbd" dependencies = [ "base64 0.22.1", "chrono", @@ -1500,9 +1667,9 @@ dependencies = [ [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=c85a4ca043aaa389df12aac5348d8a3feda28762#c85a4ca043aaa389df12aac5348d8a3feda28762" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=319e7b92db69792ab8efa4c68554ad0cf83adf93#319e7b92db69792ab8efa4c68554ad0cf83adf93" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "hubpack", "serde", "serde_repr", @@ -1551,11 +1718,11 @@ checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "git2" -version = "0.18.3" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "232e6a7bfe35766bf715e55a88b39a700596c0ccfd88cd3680b4cdb40d66ef70" +checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "libc", "libgit2-sys", "log", @@ -1578,7 +1745,7 @@ dependencies = [ "bstr", "log", "regex-automata 0.4.6", - "regex-syntax 0.8.3", + "regex-syntax 0.8.4", ] [[package]] @@ -1604,13 +1771,22 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.2.6", + "indexmap 2.4.0", "slab", "tokio", "tokio-util", "tracing", ] +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1636,6 +1812,16 @@ dependencies = [ "hashbrown 0.14.5", ] +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32", + "stable_deref_trait", +] + [[package]] name = "heck" version = "0.4.1" @@ -1672,6 +1858,57 @@ dependencies = [ "serde", ] +[[package]] +name = "hickory-proto" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07698b8420e2f0d6447a436ba999ec85d8fbf2a398bbd737b82cac4a2e96e512" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna 0.4.0", + "ipnet", + "once_cell", + "rand", + "thiserror", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "hickory-resolver" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28757f23aa75c98f254cf0405e6d8c25b831b32921b050a66692427679b1f243" +dependencies = [ + "cfg-if", + "futures-util", + "hickory-proto", + "ipconfig", + "lru-cache", + "once_cell", + "parking_lot", + "rand", + "resolv-conf", + "smallvec", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "highway" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c706f1711006204c2ba8fb1a7bd55f689bbf7feca9ff40325206b5e140cff6df" + [[package]] name = "hostname" version = "0.3.1" @@ -1848,11 +2085,10 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.2.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ - "matches", "unicode-bidi", "unicode-normalization", ] @@ -1867,6 +2103,46 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "illumos-sys-hdrs" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/opte?rev=76878de67229ea113d70503c441eab47ac5dc653#76878de67229ea113d70503c441eab47ac5dc653" + +[[package]] +name = "illumos-utils" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#758818aea3f0d375b6bbf9bd87f713a5da09ffbd" +dependencies = [ + "anyhow", + "async-trait", + "bhyve_api 0.0.0 (git+https://github.com/oxidecomputer/propolis?rev=24a74d0c76b6a63961ecef76acb1516b6e66c5c9)", + "byteorder", + "camino", + "camino-tempfile", + "cfg-if", + "crucible-smf", + "futures", + "ipnetwork", + "libc", + "macaddr", + "omicron-common", + "omicron-uuid-kinds", + "omicron-workspace-hack", + "opte-ioctl", + "oxide-vpc", + "oxlog", + "oxnet", + "schemars", + "serde", + "slog", + "smf", + "thiserror", + "tokio", + "uuid", + "whoami", + "zone", +] + [[package]] name = "image" version = "0.25.1" @@ -1892,9 +2168,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" dependencies = [ "equivalent", "hashbrown 0.14.5", @@ -1935,12 +2211,13 @@ dependencies = [ [[package]] name = "internal-dns" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#dea7eb6f4626c55defe629a4a70a05f7def36182" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#758818aea3f0d375b6bbf9bd87f713a5da09ffbd" dependencies = [ "anyhow", "chrono", "dns-service-client", "futures", + "hickory-resolver", "hyper", "omicron-common", "omicron-uuid-kinds", @@ -1948,7 +2225,6 @@ dependencies = [ "reqwest", "slog", "thiserror", - "trust-dns-resolver", "uuid", ] @@ -2019,9 +2295,18 @@ dependencies = [ [[package]] name = "itertools" -version = "0.12.1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] @@ -2050,6 +2335,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "kstat-macro" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/opte?rev=76878de67229ea113d70503c441eab47ac5dc653#76878de67229ea113d70503c441eab47ac5dc653" +dependencies = [ + "quote", + "syn 2.0.75", +] + [[package]] name = "kstat-rs" version = "0.2.4" @@ -2074,20 +2368,25 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "libdlpi-sys" version = "0.1.0" source = "git+https://github.com/oxidecomputer/dlpi-sys?branch=main#1d587ea98cf2d36f1b1624b0b960559c76d475d2" +[[package]] +name = "libdlpi-sys" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/dlpi-sys#1d587ea98cf2d36f1b1624b0b960559c76d475d2" + [[package]] name = "libgit2-sys" -version = "0.16.2+1.7.2" +version = "0.17.0+1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee4126d8b4ee5c9d9ea891dd875cfdc1e9d0950437179104b183d7d8a74d24e8" +checksum = "10472326a8a6477c3c20a64547b0059e4b0d086869eee31e6d7da728a8eb7224" dependencies = [ "cc", "libc", @@ -2111,13 +2410,35 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +[[package]] +name = "libnet" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/netadm-sys#e07ad76458eb50601e0da4f9da16dbc942bfc2ba" +dependencies = [ + "anyhow", + "cfg-if", + "colored", + "dlpi 0.2.0 (git+https://github.com/oxidecomputer/dlpi-sys)", + "libc", + "num_enum 0.5.11", + "nvpair", + "nvpair-sys", + "oxnet", + "rand", + "rusty-doors", + "socket2", + "thiserror", + "tracing", + "winnow 0.6.18", +] + [[package]] name = "libredox" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "libc", ] @@ -2189,6 +2510,12 @@ dependencies = [ "serde", ] +[[package]] +name = "managed" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d" + [[package]] name = "match_cfg" version = "0.1.0" @@ -2204,12 +2531,6 @@ dependencies = [ "regex-automata 0.1.10", ] -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - [[package]] name = "memchr" version = "2.7.2" @@ -2244,7 +2565,7 @@ dependencies = [ [[package]] name = "mg-admin-client" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/maghemite?rev=220dd026e83142b83bd93123f465a64dd4600201#220dd026e83142b83bd93123f465a64dd4600201" +source = "git+https://github.com/oxidecomputer/maghemite?rev=9e0fe45ca3862176dc31ad8cc83f605f8a7e1a42#9e0fe45ca3862176dc31ad8cc83f605f8a7e1a42" dependencies = [ "anyhow", "chrono", @@ -2275,13 +2596,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.11" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi 0.3.9", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2308,7 +2630,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -2378,10 +2700,11 @@ dependencies = [ [[package]] name = "nexus-client" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#dea7eb6f4626c55defe629a4a70a05f7def36182" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#758818aea3f0d375b6bbf9bd87f713a5da09ffbd" dependencies = [ "chrono", "futures", + "nexus-sled-agent-shared", "nexus-types", "omicron-common", "omicron-passwords", @@ -2398,36 +2721,60 @@ dependencies = [ "uuid", ] +[[package]] +name = "nexus-sled-agent-shared" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#758818aea3f0d375b6bbf9bd87f713a5da09ffbd" +dependencies = [ + "omicron-common", + "omicron-passwords", + "omicron-uuid-kinds", + "omicron-workspace-hack", + "schemars", + "serde", + "serde_json", + "sled-hardware-types", + "strum", + "thiserror", + "uuid", +] + [[package]] name = "nexus-types" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#dea7eb6f4626c55defe629a4a70a05f7def36182" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#758818aea3f0d375b6bbf9bd87f713a5da09ffbd" dependencies = [ "anyhow", "api_identity", + "async-trait", "base64 0.22.1", "chrono", "clap", + "cookie", "derive-where", "derive_more", "dns-service-client", + "dropshot", "futures", "gateway-client", + "http 0.2.12", "humantime", "ipnetwork", "newtype-uuid", + "newtype_derive", + "nexus-sled-agent-shared", "omicron-common", "omicron-passwords", "omicron-uuid-kinds", "omicron-workspace-hack", "openssl", "oxnet", + "oxql-types", "parse-display", "schemars", "serde", "serde_json", "serde_with", - "sled-agent-client", "slog", "slog-error-chain", "steno", @@ -2454,9 +2801,21 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cfg-if", - "cfg_aliases", + "cfg_aliases 0.1.1", + "libc", +] + +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "cfg_aliases 0.2.1", "libc", ] @@ -2532,6 +2891,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.75", +] + [[package]] name = "num-integer" version = "0.1.46" @@ -2574,16 +2944,6 @@ dependencies = [ "libm", ] -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi 0.3.9", - "libc", -] - [[package]] name = "num_enum" version = "0.5.11" @@ -2623,7 +2983,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -2641,6 +3001,21 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" +[[package]] +name = "nvpair" +version = "0.5.0" +source = "git+https://github.com/jmesmon/rust-libzfs?branch=master#ecd5a922247a6c5acef55d76c5b8d115572bc850" +dependencies = [ + "cstr-argument", + "foreign-types 0.5.0", + "nvpair-sys", +] + +[[package]] +name = "nvpair-sys" +version = "0.4.0" +source = "git+https://github.com/jmesmon/rust-libzfs?branch=master#ecd5a922247a6c5acef55d76c5b8d115572bc850" + [[package]] name = "object" version = "0.32.2" @@ -2653,7 +3028,7 @@ dependencies = [ [[package]] name = "omicron-common" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#dea7eb6f4626c55defe629a4a70a05f7def36182" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#758818aea3f0d375b6bbf9bd87f713a5da09ffbd" dependencies = [ "anyhow", "api_identity", @@ -2695,7 +3070,7 @@ dependencies = [ [[package]] name = "omicron-passwords" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#dea7eb6f4626c55defe629a4a70a05f7def36182" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#758818aea3f0d375b6bbf9bd87f713a5da09ffbd" dependencies = [ "argon2", "omicron-workspace-hack", @@ -2709,7 +3084,7 @@ dependencies = [ [[package]] name = "omicron-uuid-kinds" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#dea7eb6f4626c55defe629a4a70a05f7def36182" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#758818aea3f0d375b6bbf9bd87f713a5da09ffbd" dependencies = [ "newtype-uuid", "paste", @@ -2766,7 +3141,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc02deea53ffe807708244e5914f6b099ad7015a207ee24317c22112e17d9c5c" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.4.0", "serde", "serde_json", ] @@ -2777,9 +3152,9 @@ version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cfg-if", - "foreign-types", + "foreign-types 0.3.2", "libc", "once_cell", "openssl-macros", @@ -2794,25 +3169,68 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "opte" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/opte?rev=76878de67229ea113d70503c441eab47ac5dc653#76878de67229ea113d70503c441eab47ac5dc653" +dependencies = [ + "cfg-if", + "dyn-clone", + "illumos-sys-hdrs", + "kstat-macro", + "opte-api", + "postcard", + "serde", + "smoltcp", + "tabwriter", + "version_check", ] [[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +name = "opte-api" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/opte?rev=76878de67229ea113d70503c441eab47ac5dc653#76878de67229ea113d70503c441eab47ac5dc653" +dependencies = [ + "illumos-sys-hdrs", + "ipnetwork", + "postcard", + "serde", + "smoltcp", +] [[package]] -name = "openssl-sys" -version = "0.9.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +name = "opte-ioctl" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/opte?rev=76878de67229ea113d70503c441eab47ac5dc653#76878de67229ea113d70503c441eab47ac5dc653" dependencies = [ - "cc", "libc", - "pkg-config", - "vcpkg", + "libnet", + "opte", + "oxide-vpc", + "postcard", + "serde", + "thiserror", ] [[package]] @@ -2849,55 +3267,43 @@ dependencies = [ ] [[package]] -name = "oximeter" +name = "oxide-vpc" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#dea7eb6f4626c55defe629a4a70a05f7def36182" +source = "git+https://github.com/oxidecomputer/opte?rev=76878de67229ea113d70503c441eab47ac5dc653#76878de67229ea113d70503c441eab47ac5dc653" dependencies = [ - "anyhow", - "chrono", - "clap", - "omicron-workspace-hack", - "oximeter-impl", - "oximeter-macro-impl", - "oximeter-timeseries-macro", - "prettyplease", - "syn 2.0.71", - "toml 0.8.15", - "uuid", + "cfg-if", + "illumos-sys-hdrs", + "opte", + "poptrie", + "serde", + "smoltcp", + "tabwriter", + "zerocopy 0.7.34", ] [[package]] -name = "oximeter-impl" +name = "oximeter" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#dea7eb6f4626c55defe629a4a70a05f7def36182" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#758818aea3f0d375b6bbf9bd87f713a5da09ffbd" dependencies = [ - "bytes", + "anyhow", "chrono", - "float-ord", - "heck 0.5.0", - "num", - "omicron-common", + "clap", "omicron-workspace-hack", "oximeter-macro-impl", + "oximeter-schema", + "oximeter-timeseries-macro", + "oximeter-types", "prettyplease", - "proc-macro2", - "quote", - "regex", - "schemars", - "serde", - "serde_json", - "slog-error-chain", - "strum", - "syn 2.0.71", - "thiserror", - "toml 0.8.15", + "syn 2.0.75", + "toml 0.8.19", "uuid", ] [[package]] name = "oximeter-instruments" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#dea7eb6f4626c55defe629a4a70a05f7def36182" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#758818aea3f0d375b6bbf9bd87f713a5da09ffbd" dependencies = [ "cfg-if", "chrono", @@ -2915,18 +3321,18 @@ dependencies = [ [[package]] name = "oximeter-macro-impl" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#dea7eb6f4626c55defe629a4a70a05f7def36182" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#758818aea3f0d375b6bbf9bd87f713a5da09ffbd" dependencies = [ "omicron-workspace-hack", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] name = "oximeter-producer" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#dea7eb6f4626c55defe629a4a70a05f7def36182" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#758818aea3f0d375b6bbf9bd87f713a5da09ffbd" dependencies = [ "chrono", "dropshot", @@ -2944,16 +3350,71 @@ dependencies = [ "uuid", ] +[[package]] +name = "oximeter-schema" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#758818aea3f0d375b6bbf9bd87f713a5da09ffbd" +dependencies = [ + "anyhow", + "chrono", + "clap", + "heck 0.5.0", + "omicron-workspace-hack", + "oximeter-types", + "prettyplease", + "proc-macro2", + "quote", + "schemars", + "serde", + "slog-error-chain", + "syn 2.0.75", + "toml 0.8.19", +] + [[package]] name = "oximeter-timeseries-macro" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#dea7eb6f4626c55defe629a4a70a05f7def36182" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#758818aea3f0d375b6bbf9bd87f713a5da09ffbd" dependencies = [ "omicron-workspace-hack", - "oximeter-impl", + "oximeter-schema", + "oximeter-types", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", +] + +[[package]] +name = "oximeter-types" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#758818aea3f0d375b6bbf9bd87f713a5da09ffbd" +dependencies = [ + "bytes", + "chrono", + "float-ord", + "num", + "omicron-common", + "omicron-workspace-hack", + "regex", + "schemars", + "serde", + "strum", + "thiserror", + "uuid", +] + +[[package]] +name = "oxlog" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#758818aea3f0d375b6bbf9bd87f713a5da09ffbd" +dependencies = [ + "anyhow", + "camino", + "chrono", + "clap", + "omicron-workspace-hack", + "sigpipe", + "uuid", ] [[package]] @@ -2967,6 +3428,21 @@ dependencies = [ "serde_json", ] +[[package]] +name = "oxql-types" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#758818aea3f0d375b6bbf9bd87f713a5da09ffbd" +dependencies = [ + "anyhow", + "chrono", + "highway", + "num", + "omicron-workspace-hack", + "oximeter-types", + "schemars", + "serde", +] + [[package]] name = "p4rs" version = "0.1.0" @@ -3015,27 +3491,27 @@ dependencies = [ [[package]] name = "parse-display" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914a1c2265c98e2446911282c6ac86d8524f495792c38c5bd884f80499c7538a" +checksum = "287d8d3ebdce117b8539f59411e4ed9ec226e0a4153c7f55495c6070d68e6f72" dependencies = [ "parse-display-derive", "regex", - "regex-syntax 0.8.3", + "regex-syntax 0.8.4", ] [[package]] name = "parse-display-derive" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ae7800a4c974efd12df917266338e79a7a74415173caf7e70aa0a0707345281" +checksum = "7fc048687be30d79502dea2f623d052f3a074012c6eac41726b7ab17213616b1" dependencies = [ "proc-macro2", "quote", "regex", - "regex-syntax 0.8.3", + "regex-syntax 0.8.4", "structmeta", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -3092,7 +3568,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -3113,7 +3589,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.2.6", + "indexmap 2.4.0", "serde", "serde_derive", ] @@ -3125,7 +3601,7 @@ dependencies = [ "anyhow", "backoff", "base64 0.21.7", - "bhyve_api", + "bhyve_api 0.0.0", "bytes", "camino", "cfg-if", @@ -3260,7 +3736,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -3330,12 +3806,29 @@ dependencies = [ "universal-hash", ] +[[package]] +name = "poptrie" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/poptrie?branch=multipath#ca52bef3f87ff1a67d81b3c6e601dcb5fdbcc165" + [[package]] name = "portable-atomic" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" +[[package]] +name = "postcard" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20ee10b999a00ca189ac2cb99f5db1ca71fb7371e3d5f493b879ca95d2a67220" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "serde", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -3393,7 +3886,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -3442,7 +3935,7 @@ dependencies = [ [[package]] name = "progenitor" version = "0.7.0" -source = "git+https://github.com/oxidecomputer/progenitor?branch=main#5fededb4f56191e833cb2263b5c1f99b48a229cc" +source = "git+https://github.com/oxidecomputer/progenitor?branch=main#0a25eb9259216ef4d8de26509c2c11e176149b5b" dependencies = [ "progenitor-client", "progenitor-impl", @@ -3452,7 +3945,7 @@ dependencies = [ [[package]] name = "progenitor-client" version = "0.7.0" -source = "git+https://github.com/oxidecomputer/progenitor?branch=main#5fededb4f56191e833cb2263b5c1f99b48a229cc" +source = "git+https://github.com/oxidecomputer/progenitor?branch=main#0a25eb9259216ef4d8de26509c2c11e176149b5b" dependencies = [ "bytes", "futures-core", @@ -3466,11 +3959,11 @@ dependencies = [ [[package]] name = "progenitor-impl" version = "0.7.0" -source = "git+https://github.com/oxidecomputer/progenitor?branch=main#5fededb4f56191e833cb2263b5c1f99b48a229cc" +source = "git+https://github.com/oxidecomputer/progenitor?branch=main#0a25eb9259216ef4d8de26509c2c11e176149b5b" dependencies = [ "heck 0.5.0", "http 0.2.12", - "indexmap 2.2.6", + "indexmap 2.4.0", "openapiv3", "proc-macro2", "quote", @@ -3478,7 +3971,7 @@ dependencies = [ "schemars", "serde", "serde_json", - "syn 2.0.71", + "syn 2.0.75", "thiserror", "typify", "unicode-ident", @@ -3487,7 +3980,7 @@ dependencies = [ [[package]] name = "progenitor-macro" version = "0.7.0" -source = "git+https://github.com/oxidecomputer/progenitor?branch=main#5fededb4f56191e833cb2263b5c1f99b48a229cc" +source = "git+https://github.com/oxidecomputer/progenitor?branch=main#0a25eb9259216ef4d8de26509c2c11e176149b5b" dependencies = [ "openapiv3", "proc-macro2", @@ -3496,9 +3989,9 @@ dependencies = [ "schemars", "serde", "serde_json", - "serde_tokenstream 0.2.1", + "serde_tokenstream 0.2.2", "serde_yaml", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -3507,15 +4000,15 @@ version = "0.1.0" dependencies = [ "anyhow", "async-trait", - "bhyve_api", - "bitflags 2.5.0", + "bhyve_api 0.0.0", + "bitflags 2.6.0", "bitstruct", "byteorder", "crossbeam-channel", "crucible", "crucible-client-types", "dladm", - "dlpi", + "dlpi 0.2.0 (git+https://github.com/oxidecomputer/dlpi-sys?branch=main)", "erased-serde", "futures", "ispf", @@ -3703,7 +4196,7 @@ version = "0.1.0" dependencies = [ "anyhow", "atty", - "bhyve_api", + "bhyve_api 0.0.0", "clap", "cpuid_profile_config", "crucible-client-types", @@ -3732,7 +4225,7 @@ name = "propolis-utils" version = "0.0.0" dependencies = [ "anyhow", - "bhyve_api", + "bhyve_api 0.0.0", "clap", "libc", "propolis", @@ -3847,7 +4340,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", ] [[package]] @@ -3863,14 +4356,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.5" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", "regex-automata 0.4.6", - "regex-syntax 0.8.3", + "regex-syntax 0.8.4", ] [[package]] @@ -3890,7 +4383,7 @@ checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.3", + "regex-syntax 0.8.4", ] [[package]] @@ -3901,9 +4394,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "regress" @@ -3987,7 +4480,7 @@ version = "0.0.0" dependencies = [ "anyhow", "ascii", - "bitflags 2.5.0", + "bitflags 2.6.0", "clap", "dropshot", "futures", @@ -4054,7 +4547,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ "base64 0.21.7", - "bitflags 2.5.0", + "bitflags 2.6.0", "serde", "serde_derive", ] @@ -4065,7 +4558,7 @@ version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b838eba278d213a8beaf485bd313fd580ca4505a00d5871caeb1457c55322cae" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -4103,7 +4596,7 @@ version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno 0.3.9", "libc", "linux-raw-sys", @@ -4147,9 +4640,9 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" dependencies = [ "base64 0.22.1", "rustls-pki-types", @@ -4188,6 +4681,24 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +[[package]] +name = "rusty-doors" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/rusty-doors#0e3a1495dcf8b7b5e11a6921c2cf1cf957c5a5bf" +dependencies = [ + "libc", + "rusty-doors-macros", +] + +[[package]] +name = "rusty-doors-macros" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/rusty-doors#0e3a1495dcf8b7b5e11a6921c2cf1cf957c5a5bf" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "ryu" version = "1.0.18" @@ -4236,7 +4747,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -4262,7 +4773,7 @@ checksum = "7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -4281,7 +4792,7 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "core-foundation", "core-foundation-sys", "libc", @@ -4333,9 +4844,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.204" +version = "1.0.208" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" dependencies = [ "serde_derive", ] @@ -4351,13 +4862,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.204" +version = "1.0.208" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -4368,7 +4879,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -4382,11 +4893,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.120" +version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -4409,14 +4921,14 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] name = "serde_spanned" -version = "0.6.6" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" dependencies = [ "serde", ] @@ -4443,14 +4955,14 @@ dependencies = [ [[package]] name = "serde_tokenstream" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8790a7c3fe883e443eaa2af6f705952bc5d6e8671a220b9335c8cae92c037e74" +checksum = "64060d864397305347a78851c51588fd283767e7e7589829e8121d65512340f1" dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -4475,7 +4987,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.2.6", + "indexmap 2.4.0", "serde", "serde_derive", "serde_json", @@ -4492,7 +5004,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -4501,7 +5013,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.4.0", "itoa", "ryu", "serde", @@ -4571,6 +5083,15 @@ dependencies = [ "libc", ] +[[package]] +name = "sigpipe" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5584bfb3e0d348139d8210285e39f6d2f8a1902ac06de343e06357d1d763d8e6" +dependencies = [ + "libc", +] + [[package]] name = "simd-adler32" version = "0.3.7" @@ -4599,25 +5120,15 @@ dependencies = [ ] [[package]] -name = "sled-agent-client" +name = "sled-hardware-types" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#dea7eb6f4626c55defe629a4a70a05f7def36182" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#758818aea3f0d375b6bbf9bd87f713a5da09ffbd" dependencies = [ - "anyhow", - "async-trait", - "chrono", + "illumos-utils", "omicron-common", - "omicron-uuid-kinds", "omicron-workspace-hack", - "oxnet", - "progenitor", - "regress 0.9.1", - "reqwest", "schemars", "serde", - "serde_json", - "slog", - "uuid", ] [[package]] @@ -4695,7 +5206,7 @@ source = "git+https://github.com/oxidecomputer/slog-error-chain?branch=main#15f6 dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -4751,6 +5262,29 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +[[package]] +name = "smf" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a491bfc47dffa70a3c267bc379e9de9f4b0a7195e474a94498189b177f8d18c" +dependencies = [ + "thiserror", +] + +[[package]] +name = "smoltcp" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a1a996951e50b5971a2c8c0fa05a381480d70a933064245c4a223ddc87ccc97" +dependencies = [ + "bitflags 1.3.2", + "byteorder", + "cfg-if", + "defmt", + "heapless", + "managed", +] + [[package]] name = "socket2" version = "0.5.7" @@ -4784,6 +5318,12 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "static_assertions" version = "1.1.0" @@ -4833,7 +5373,7 @@ dependencies = [ "proc-macro2", "quote", "structmeta-derive", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -4844,7 +5384,7 @@ checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -4866,7 +5406,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -4879,7 +5419,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -4911,9 +5451,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.71" +version = "2.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" +checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9" dependencies = [ "proc-macro2", "quote", @@ -4959,6 +5499,15 @@ dependencies = [ "libc", ] +[[package]] +name = "tabwriter" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a327282c4f64f6dc37e3bba4c2b6842cc3a992f204fa58d917696a89f691e5f6" +dependencies = [ + "unicode-width", +] + [[package]] name = "take_mut" version = "0.2.2" @@ -5061,7 +5610,7 @@ dependencies = [ "log", "memmem", "nix 0.24.3", - "num-derive", + "num-derive 0.3.3", "num-traits", "ordered-float 3.9.2", "pest", @@ -5101,7 +5650,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -5174,32 +5723,31 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.38.1" +version = "1.39.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df" +checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -5272,21 +5820,21 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.15" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac2caab0bf757388c6c0ae23b3293fdb463fee59434529014f85e3263b995c28" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.16", + "toml_edit 0.22.20", ] [[package]] name = "toml_datetime" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] @@ -5297,7 +5845,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.4.0", "serde", "serde_spanned", "toml_datetime", @@ -5306,15 +5854,15 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.16" +version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "278f3d518e152219c994ce877758516bca5e118eaed6996192a774fb9fbf0788" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.4.0", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.8", + "winnow 0.6.18", ] [[package]] @@ -5355,7 +5903,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -5426,51 +5974,6 @@ dependencies = [ "tracing-log 0.2.0", ] -[[package]] -name = "trust-dns-proto" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f7f83d1e4a0e4358ac54c5c3681e5d7da5efc5a7a632c90bb6d6669ddd9bc26" -dependencies = [ - "async-trait", - "cfg-if", - "data-encoding", - "enum-as-inner", - "futures-channel", - "futures-io", - "futures-util", - "idna 0.2.3", - "ipnet", - "lazy_static", - "rand", - "smallvec", - "thiserror", - "tinyvec", - "tokio", - "tracing", - "url", -] - -[[package]] -name = "trust-dns-resolver" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aff21aa4dcefb0a1afbfac26deb0adc93888c7d295fb63ab273ef276ba2b7cfe" -dependencies = [ - "cfg-if", - "futures-util", - "ipconfig", - "lazy_static", - "lru-cache", - "parking_lot", - "resolv-conf", - "smallvec", - "thiserror", - "tokio", - "tracing", - "trust-dns-proto", -] - [[package]] name = "try-lock" version = "0.2.5" @@ -5522,7 +6025,7 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "typify" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/typify#e1ef79f972152355ba80a255d6086d1ad3404815" +source = "git+https://github.com/oxidecomputer/typify#ebdee8c4a68dbe9351c58614330724e8ced1fda8" dependencies = [ "typify-impl", "typify-macro", @@ -5531,7 +6034,7 @@ dependencies = [ [[package]] name = "typify-impl" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/typify#e1ef79f972152355ba80a255d6086d1ad3404815" +source = "git+https://github.com/oxidecomputer/typify#ebdee8c4a68dbe9351c58614330724e8ced1fda8" dependencies = [ "heck 0.5.0", "log", @@ -5542,7 +6045,7 @@ dependencies = [ "semver 1.0.23", "serde", "serde_json", - "syn 2.0.71", + "syn 2.0.75", "thiserror", "unicode-ident", ] @@ -5550,7 +6053,7 @@ dependencies = [ [[package]] name = "typify-macro" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/typify#e1ef79f972152355ba80a255d6086d1ad3404815" +source = "git+https://github.com/oxidecomputer/typify#ebdee8c4a68dbe9351c58614330724e8ced1fda8" dependencies = [ "proc-macro2", "quote", @@ -5558,8 +6061,8 @@ dependencies = [ "semver 1.0.23", "serde", "serde_json", - "serde_tokenstream 0.2.1", - "syn 2.0.71", + "serde_tokenstream 0.2.2", + "syn 2.0.75", "typify-impl", ] @@ -5699,8 +6202,8 @@ dependencies = [ "dtrace-parser 0.2.0", "proc-macro2", "quote", - "serde_tokenstream 0.2.1", - "syn 2.0.71", + "serde_tokenstream 0.2.2", + "syn 2.0.75", "usdt-impl 0.5.0", ] @@ -5738,7 +6241,7 @@ dependencies = [ "quote", "serde", "serde_json", - "syn 2.0.71", + "syn 2.0.75", "thiserror", "thread-id", "version_check", @@ -5767,8 +6270,8 @@ dependencies = [ "dtrace-parser 0.2.0", "proc-macro2", "quote", - "serde_tokenstream 0.2.1", - "syn 2.0.71", + "serde_tokenstream 0.2.2", + "syn 2.0.75", "usdt-impl 0.5.0", ] @@ -5808,9 +6311,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "vergen" -version = "8.3.1" +version = "8.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e27d6bdd219887a9eadd19e1c34f32e47fa332301184935c6d9bca26f3cca525" +checksum = "2990d9ea5967266ea0ccf413a4aa5c42a93dbcfda9cb49a97de6931726b12566" dependencies = [ "anyhow", "cargo_metadata", @@ -5824,9 +6327,9 @@ dependencies = [ [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "viona_api" @@ -5886,6 +6389,12 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + [[package]] name = "wasm-bindgen" version = "0.2.92" @@ -5907,7 +6416,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", "wasm-bindgen-shared", ] @@ -5941,7 +6450,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6040,6 +6549,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "whoami" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" +dependencies = [ + "redox_syscall 0.4.1", + "wasite", + "web-sys", +] + [[package]] name = "widestring" version = "1.1.0" @@ -6246,9 +6766,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.8" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" dependencies = [ "memchr", ] @@ -6349,7 +6869,7 @@ checksum = "125139de3f6b9d625c39e2efdd73d41bdac468ccd556556440e322be0e1bbd91" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -6360,7 +6880,7 @@ checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -6368,3 +6888,28 @@ name = "zeroize" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" + +[[package]] +name = "zone" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62a428a79ea2224ce8ab05d6d8a21bdd7b4b68a8dbc1230511677a56e72ef22" +dependencies = [ + "itertools 0.10.5", + "thiserror", + "tokio", + "zone_cfg_derive", +] + +[[package]] +name = "zone_cfg_derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5c4f01d3785e222d5aca11c9813e9c46b69abfe258756c99c9b628683626cc8" +dependencies = [ + "heck 0.4.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] diff --git a/Cargo.toml b/Cargo.toml index 63d6293df..3ddad0bb7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -81,8 +81,8 @@ oximeter = { git = "https://github.com/oxidecomputer/omicron", branch = "main" } sled-agent-client = { git = "https://github.com/oxidecomputer/omicron", branch = "main" } # Crucible -crucible = { git = "https://github.com/oxidecomputer/crucible", rev = "e58ca3693cb9ce0438947beba10e97ee38a0966b" } -crucible-client-types = { git = "https://github.com/oxidecomputer/crucible", rev = "e58ca3693cb9ce0438947beba10e97ee38a0966b" } +crucible = { git = "https://github.com/oxidecomputer/crucible", rev = "d037eeb9a56a8a62ff17266f340c011224d15146" } +crucible-client-types = { git = "https://github.com/oxidecomputer/crucible", rev = "d037eeb9a56a8a62ff17266f340c011224d15146" } # External dependencies anyhow = "1.0" @@ -120,7 +120,7 @@ http = "0.2.9" hyper = "0.14" indicatif = "0.17.3" inventory = "0.3.0" -kstat-rs = "0.2.3" +kstat-rs = "0.2.4" lazy_static = "1.4" libc = "0.2" mockall = "0.12" diff --git a/bin/propolis-server/src/lib/initializer.rs b/bin/propolis-server/src/lib/initializer.rs index 060934d74..5fd311f52 100644 --- a/bin/propolis-server/src/lib/initializer.rs +++ b/bin/propolis-server/src/lib/initializer.rs @@ -11,13 +11,17 @@ use std::sync::Arc; use std::time::{SystemTime, UNIX_EPOCH}; use crate::serial::Serial; -use crate::stats::virtual_machine::VirtualMachine; +use crate::stats::{ + create_kstat_sampler, track_vcpu_kstats, virtual_disk::VirtualDiskProducer, + virtual_machine::VirtualMachine, +}; use crate::vm::{BlockBackendMap, CrucibleBackendMap, DeviceMap}; use anyhow::{Context, Result}; use crucible_client_types::VolumeConstructionRequest; pub use nexus_client::Client as NexusClient; use oximeter::types::ProducerRegistry; +use oximeter_instruments::kstat::KstatSampler; use propolis::block; use propolis::chardev::{self, BlockingSource, Source}; use propolis::common::{Lifecycle, GB, MB, PAGE_SIZE}; @@ -491,7 +495,8 @@ impl<'a> MachineInitializer<'a> { Nvme, } - for (name, device_spec) in &self.spec.devices.storage_devices { + 'devloop: for (name, device_spec) in &self.spec.devices.storage_devices + { info!( self.log, "Creating storage device {} with properties {:?}", @@ -542,14 +547,15 @@ impl<'a> MachineInitializer<'a> { .await?; self.block_backends.insert(backend_name.clone(), backend.clone()); - match device_interface { + let block_dev: Arc = match device_interface { DeviceInterface::Virtio => { let vioblk = virtio::PciVirtioBlock::new(0x100); self.devices .insert(format!("pci-virtio-{}", bdf), vioblk.clone()); block::attach(vioblk.clone(), backend).unwrap(); - chipset.pci_attach(bdf, vioblk); + chipset.pci_attach(bdf, vioblk.clone()); + vioblk } DeviceInterface::Nvme => { // Limit data transfers to 1MiB (2^8 * 4k) in size @@ -564,18 +570,59 @@ impl<'a> MachineInitializer<'a> { self.devices .insert(format!("pci-nvme-{bdf}"), nvme.clone()); block::attach(nvme.clone(), backend).unwrap(); - chipset.pci_attach(bdf, nvme); + chipset.pci_attach(bdf, nvme.clone()); + nvme } }; - if let Some((id, backend)) = crucible { - let prev = self.crucible_backends.insert(id, backend); + if let Some((disk_id, backend)) = crucible { + let block_size = backend.block_size().await; + let prev = self.crucible_backends.insert(disk_id, backend); if prev.is_some() { return Err(Error::new( ErrorKind::InvalidInput, - format!("multiple disks with id {}", id), + format!("multiple disks with id {}", disk_id), )); } + + let Some(block_size) = block_size else { + slog::error!( + self.log, + "Could not get Crucible backend block size, \ + virtual disk metrics can't be reported for it"; + "disk_id" => %disk_id, + ); + continue 'devloop; + }; + + // Register the block device as a metric producer, if we've been + // setup to do so. Note we currently only do this for the Crucible + // backend, in which case we have the disk ID. + if let Some(registry) = &self.producer_registry { + let stats = VirtualDiskProducer::new( + block_size, + self.properties.id, + disk_id, + &self.properties.metadata, + ); + if let Err(e) = registry.register_producer(stats.clone()) { + slog::error!( + self.log, + "Could not register virtual disk producer, \ + metrics will not be produced"; + "disk_id" => %disk_id, + "error" => ?e, + ); + continue 'devloop; + }; + + // Set the on-completion callback for the block device, to + // update stats. + let callback = move |op, result, duration| { + stats.on_completion(op, result, duration); + }; + block_dev.on_completion(Box::new(callback)); + }; } } Ok(()) @@ -1041,13 +1088,40 @@ impl<'a> MachineInitializer<'a> { Ok(ramfb) } - pub fn initialize_cpus(&mut self) -> Result<(), Error> { + pub async fn initialize_cpus( + &mut self, + kstat_sampler: &Option, + ) -> Result<(), Error> { for vcpu in self.machine.vcpus.iter() { vcpu.set_default_capabs().unwrap(); // The vCPUs behave like devices, so add them to the list as well self.devices.insert(format!("vcpu-{}", vcpu.id), vcpu.clone()); } + if let Some(sampler) = kstat_sampler.as_ref() { + track_vcpu_kstats(&self.log, sampler, self.properties).await; + } Ok(()) } + + /// Create an object used to sample kstats. + pub(crate) fn create_kstat_sampler(&self) -> Option { + let Some(registry) = &self.producer_registry else { + return None; + }; + let sampler = + create_kstat_sampler(&self.log, u32::from(self.properties.vcpus))?; + match registry.register_producer(sampler.clone()) { + Ok(_) => Some(sampler), + Err(e) => { + slog::error!( + self.log, + "Failed to register kstat sampler in producer \ + registry, no kstat-based metrics will be produced"; + "error" => ?e, + ); + None + } + } + } } diff --git a/bin/propolis-server/src/lib/stats.rs b/bin/propolis-server/src/lib/stats.rs index 326dfd76b..a93d00963 100644 --- a/bin/propolis-server/src/lib/stats.rs +++ b/bin/propolis-server/src/lib/stats.rs @@ -7,10 +7,11 @@ use omicron_common::api::internal::nexus::ProducerEndpoint; use omicron_common::api::internal::nexus::ProducerKind; use oximeter::{ - types::{Cumulative, ProducerRegistry, Sample}, - Metric, MetricsError, Producer, + types::{ProducerRegistry, Sample}, + MetricsError, Producer, }; use oximeter_producer::{Config, Error, Server}; +use propolis_api_types::InstanceProperties; use slog::Logger; use std::net::SocketAddr; @@ -18,21 +19,25 @@ use std::sync::{Arc, Mutex}; use uuid::Uuid; use crate::server::MetricsEndpointConfig; -use crate::stats::virtual_machine::VirtualMachine; - -// Propolis is built and some tests are run on non-illumos systems. The real -// `kstat` infrastructure cannot be built there, so some conditional compilation -// tricks are needed -#[cfg(all(not(test), target_os = "illumos"))] +use crate::stats::virtual_machine::{Reset, VirtualMachine}; use oximeter_instruments::kstat::KstatSampler; mod pvpanic; +pub(crate) mod virtual_disk; pub(crate) mod virtual_machine; pub use self::pvpanic::PvpanicProducer; // Interval on which we ask `oximeter` to poll us for metric data. -const OXIMETER_STAT_INTERVAL: tokio::time::Duration = - tokio::time::Duration::from_secs(30); +// +// Note that some statistics, like those based on kstats, are sampled more +// densely than this proactively. Their sampling rate is decoupled from this +// poll interval. Others, like the virtual disk stats, are updated all the time, +// but we only generate _samples_ from that when `oximeter` comes polling. +// +// In short, set this to the minimum interval on which you'd like those +// statistics to be sampled. +const OXIMETER_COLLECTION_INTERVAL: tokio::time::Duration = + tokio::time::Duration::from_secs(10); // Interval on which we produce vCPU metrics. #[cfg(all(not(test), target_os = "illumos"))] @@ -46,24 +51,12 @@ const VCPU_KSTAT_INTERVAL: std::time::Duration = // // This limit provides extra space for up to 64 samples per vCPU per microstate, // to ensure we don't throw away too much data if oximeter cannot reach us. -#[cfg(all(not(test), target_os = "illumos"))] const KSTAT_LIMIT_PER_VCPU: u32 = crate::stats::virtual_machine::N_VCPU_MICROSTATES * 64; -/// An Oximeter `Metric` that specifies the number of times an instance was -/// reset via the server API. -#[derive(Debug, Default, Copy, Clone, Metric)] -struct Reset { - /// The number of times this instance was reset via the API. - #[datum] - pub count: Cumulative, -} - -/// The full set of server-level metrics, collated by -/// [`ServerStatsOuter::produce`] into the types needed to relay these -/// statistics to Oximeter. +/// Shared type for tracking metrics about the Propolis API server itself. #[derive(Clone, Debug)] -struct ServerStats { +struct ServerStatsInner { /// The oximeter Target identifying this instance as the source of metric /// data. virtual_machine: VirtualMachine, @@ -72,45 +65,48 @@ struct ServerStats { run_count: Reset, } -impl ServerStats { +impl ServerStatsInner { pub fn new(virtual_machine: VirtualMachine) -> Self { - ServerStats { virtual_machine, run_count: Default::default() } + ServerStatsInner { + virtual_machine, + run_count: Reset { datum: Default::default() }, + } } } -/// The public wrapper for server-level metrics. +/// Type publishing metrics about the Propolis API server itself. +// +// NOTE: This type is shared with the server and the oximeter producer. The +// former updates stats as API requests are handled or other actions taken, and +// the latter collects the stats when oximeter requests them. #[derive(Clone, Debug)] -pub struct ServerStatsOuter { - server_stats_wrapped: Arc>, - #[cfg(all(not(test), target_os = "illumos"))] - kstat_sampler: Option, +pub struct ServerStats { + inner: Arc>, } -impl ServerStatsOuter { - /// Increments the number of times the instance was reset. +impl ServerStats { + /// Create new server stats, representing the provided instance. + pub fn new(vm: VirtualMachine) -> Self { + Self { inner: Arc::new(Mutex::new(ServerStatsInner::new(vm))) } + } + + /// Increments the number of times the managed instance was reset. pub fn count_reset(&self) { - let mut inner = self.server_stats_wrapped.lock().unwrap(); - let datum = inner.run_count.datum_mut(); - *datum += 1; + self.inner.lock().unwrap().run_count.datum.increment(); } } -impl Producer for ServerStatsOuter { +impl Producer for ServerStats { fn produce( &mut self, ) -> Result + 'static>, MetricsError> { let run_count = { - let inner = self.server_stats_wrapped.lock().unwrap(); + let inner = self.inner.lock().unwrap(); std::iter::once(Sample::new( &inner.virtual_machine, &inner.run_count, )?) }; - #[cfg(all(not(test), target_os = "illumos"))] - if let Some(sampler) = self.kstat_sampler.as_mut() { - let samples = sampler.produce()?; - return Ok(Box::new(run_count.chain(samples))); - } Ok(Box::new(run_count)) } } @@ -145,7 +141,7 @@ pub fn start_oximeter_server( id, kind: ProducerKind::Instance, address: producer_address, - interval: OXIMETER_STAT_INTERVAL, + interval: OXIMETER_COLLECTION_INTERVAL, }; // Create a child logger, to avoid intermingling the producer server output @@ -171,64 +167,53 @@ pub fn start_oximeter_server( Server::with_registry(registry.clone(), &config) } -/// Creates and registers a set of server-level metrics for an instance. -/// -/// This attempts to initialize kstat-based metrics for vCPU usage data. This -/// may fail, in which case those metrics will be unavailable. -// -// NOTE: The logger is unused if we don't pass it to `setup_kstat_tracking` -// internally, so ignore that clippy lint. -#[cfg_attr(not(all(not(test), target_os = "illumos")), allow(unused_variables))] -pub async fn register_server_metrics( - registry: &ProducerRegistry, - virtual_machine: VirtualMachine, +/// Create an object that can be used to sample kstat-based metrics. +pub(crate) fn create_kstat_sampler( log: &Logger, -) -> anyhow::Result { - let stats = ServerStats::new(virtual_machine.clone()); - - let stats_outer = ServerStatsOuter { - server_stats_wrapped: Arc::new(Mutex::new(stats)), - // Setup the collection of kstats for this instance. - #[cfg(all(not(test), target_os = "illumos"))] - kstat_sampler: setup_kstat_tracking(log, virtual_machine).await, - }; - - registry.register_producer(stats_outer.clone())?; - - Ok(stats_outer) -} - -#[cfg(all(not(test), target_os = "illumos"))] -async fn setup_kstat_tracking( - log: &Logger, - virtual_machine: VirtualMachine, + n_vcpus: u32, ) -> Option { - let kstat_limit = - usize::try_from(virtual_machine.n_vcpus() * KSTAT_LIMIT_PER_VCPU) - .unwrap(); + let kstat_limit = usize::try_from(n_vcpus * KSTAT_LIMIT_PER_VCPU).unwrap(); match KstatSampler::with_sample_limit(log, kstat_limit) { - Ok(sampler) => { - let details = oximeter_instruments::kstat::CollectionDetails::never( - VCPU_KSTAT_INTERVAL, - ); - if let Err(e) = sampler.add_target(virtual_machine, details).await { - slog::error!( - log, - "failed to add VirtualMachine target, \ - vCPU stats will be unavailable"; - "error" => ?e, - ); - } - Some(sampler) - } + Ok(sampler) => Some(sampler), Err(e) => { slog::error!( log, "failed to create KstatSampler, \ - vCPU stats will be unavailable"; + kstat-based stats will be unavailable"; "error" => ?e, ); None } } } + +/// Track kstats required to publish vCPU metrics for this instance. +#[cfg(any(test, not(target_os = "illumos")))] +pub(crate) async fn track_vcpu_kstats( + log: &Logger, + _: &KstatSampler, + _: &InstanceProperties, +) { + slog::error!(log, "vCPU stats are not supported on this platform"); +} + +/// Track kstats required to publish vCPU metrics for this instance. +#[cfg(all(not(test), target_os = "illumos"))] +pub(crate) async fn track_vcpu_kstats( + log: &Logger, + sampler: &KstatSampler, + properties: &InstanceProperties, +) { + let virtual_machine = VirtualMachine::from(properties); + let details = oximeter_instruments::kstat::CollectionDetails::never( + VCPU_KSTAT_INTERVAL, + ); + if let Err(e) = sampler.add_target(virtual_machine, details).await { + slog::error!( + log, + "failed to add VirtualMachine target, \ + vCPU stats will be unavailable"; + "error" => ?e, + ); + } +} diff --git a/bin/propolis-server/src/lib/stats/virtual_disk.rs b/bin/propolis-server/src/lib/stats/virtual_disk.rs new file mode 100644 index 000000000..a9e4114d4 --- /dev/null +++ b/bin/propolis-server/src/lib/stats/virtual_disk.rs @@ -0,0 +1,380 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// Copyright 2024 Oxide Computer Company + +//! Types for tracking statistics about virtual disks. + +use std::{ + sync::{Arc, Mutex}, + time::Duration, +}; + +// NOTE: TOML definitions of timeseries are centralized in Omicron, so this file +// lives in that repo, at +// `./omicron/oximeter/oximeter/schema/virtual-machine.toml`. +oximeter::use_timeseries!("virtual-disk.toml"); +use chrono::Utc; +use oximeter::{ + histogram::{Histogram, Record as _}, + types::Cumulative, + MetricsError, Producer, Sample, +}; +use propolis::block::{self, Operation}; +use propolis_api_types::InstanceMetadata; +use uuid::Uuid; + +use self::virtual_disk::{ + BytesRead, BytesWritten, FailedFlushes, FailedReads, FailedWrites, Flushes, + IoLatency, IoSize, Reads, VirtualDisk, Writes, +}; + +/// Type for tracking virtual disk stats. +/// +/// This is shared between the oximeter producer registry and the actual block +/// device that implements the I/O processing. As I/Os are completed, this is +/// called back into in order to update the stats. Note that the actual shared +/// type is an Arc+Mutex around this, the [`VirtualDiskProducer`]. +#[derive(Debug)] +struct VirtualDiskStats { + /// The oximeter::Target representing this disk. + disk: VirtualDisk, + /// Cumulative number of reads. + reads: Reads, + /// Cumulative number of bytes read. + bytes_read: BytesRead, + /// Cumulative number of failed reads, by failure reason. + failed_reads: [FailedReads; N_FAILURE_KINDS], + /// Cumulative number of writes. + writes: Writes, + /// Cumulative number of bytes written. + bytes_written: BytesWritten, + /// Cumulative number of failed writes, by failure reason. + failed_writes: [FailedWrites; N_FAILURE_KINDS], + /// Cumulative number of flushes. + flushes: Flushes, + /// Cumulative number of failed flushes, by failure reason. + failed_flushes: [FailedFlushes; N_FAILURE_KINDS], + /// Histogram tracking I/O latency, by the I/O kind. + io_latency: [IoLatency; N_IO_KINDS], + /// Histogram tracking I/O sizes, by the I/O kind. + /// + /// Note that we have 1 fewer histogram here, since flush operations do not + /// have a size. + io_size: [IoSize; N_IO_KINDS - 1], +} + +impl VirtualDiskStats { + /// Update the tracked statistics with the result of an I/O completion. + fn on_completion( + &mut self, + op: block::Operation, + result: block::Result, + duration: Duration, + ) { + match op { + Operation::Read(_, len) => { + self.on_read_completion(result, len, duration) + } + Operation::Write(_, len) => { + self.on_write_completion(result, len, duration) + } + Operation::Flush => self.on_flush_completion(result, duration), + } + } + + fn on_read_completion( + &mut self, + result: block::Result, + len: usize, + duration: Duration, + ) { + let index = match result { + block::Result::Success => { + let _ = self.io_latency[READ_INDEX] + .datum + .sample(duration.as_nanos() as u64); + let _ = self.io_size[READ_INDEX].datum.sample(len as u64); + self.reads.datum += 1; + self.bytes_read.datum += len as u64; + return; + } + block::Result::Failure => FAILURE_INDEX, + block::Result::ReadOnly => READONLY_INDEX, + block::Result::Unsupported => UNSUPPORTED_INDEX, + }; + self.failed_reads[index].datum.increment(); + } + + fn on_write_completion( + &mut self, + result: block::Result, + len: usize, + duration: Duration, + ) { + let index = match result { + block::Result::Success => { + let _ = self.io_latency[WRITE_INDEX] + .datum + .sample(duration.as_nanos() as u64); + let _ = self.io_size[WRITE_INDEX].datum.sample(len as u64); + self.writes.datum += 1; + self.bytes_written.datum += len as u64; + return; + } + block::Result::Failure => FAILURE_INDEX, + block::Result::ReadOnly => READONLY_INDEX, + block::Result::Unsupported => UNSUPPORTED_INDEX, + }; + self.failed_writes[index].datum.increment(); + } + + fn on_flush_completion( + &mut self, + result: block::Result, + duration: Duration, + ) { + let index = match result { + block::Result::Success => { + let _ = self.io_latency[FLUSH_INDEX] + .datum + .sample(duration.as_nanos() as u64); + self.flushes.datum += 1; + return; + } + block::Result::Failure => FAILURE_INDEX, + block::Result::ReadOnly => READONLY_INDEX, + block::Result::Unsupported => UNSUPPORTED_INDEX, + }; + self.failed_flushes[index].datum.increment(); + } +} + +/// Number of I/O kinds we track. +const N_IO_KINDS: usize = 3; + +/// Indices into arrays tracking operations broken out by I/O kind. +const READ_INDEX: usize = 0; +const WRITE_INDEX: usize = 1; +const FLUSH_INDEX: usize = 2; + +/// String representations of I/O kinds we report to Oximeter. +const READ_KIND: &str = "read"; +const WRITE_KIND: &str = "write"; +const FLUSH_KIND: &str = "flush"; + +/// Number of failure kinds we track. +const N_FAILURE_KINDS: usize = 3; + +/// Indices into arrays tracking operations broken out by failure kind. +const FAILURE_INDEX: usize = 0; +const READONLY_INDEX: usize = 1; +const UNSUPPORTED_INDEX: usize = 2; + +/// String representations of failure kinds we report to Oximeter. +const FAILURE_KIND: &str = "failed"; +const READONLY_KIND: &str = "read-only"; +const UNSUPPORTED_KIND: &str = "unsupported"; + +/// Latency is measured in nanoseconds. We want to track between 1 microsecond, +/// which is 10 ** 3 nanos, and 10s, which is 10 * 1e9 == 10 ** 10 nanoseconds. +const LATENCY_POWERS: (u16, u16) = (3, 10); + +/// Sizes are measured in powers of 2 from 512B to 1GiB. +/// +/// We use 512B as the minimum since that is the minimum supported block size. +const SIZE_POWERS: (u16, u16) = (9, 30); + +/// A [`Producer`] that emits statistics about virtual disks. +/// +/// This type is shared between the block devie that handles guest I/Os, and the +/// oximeter producer server, which publishes data to oximeter when it polls us. +/// As I/Os are completed, the [`VirtualDiskProducer::on_completion()`] method +/// is called, to update stats with the results of the I/O operation. +/// +/// As oximeter polls us, the producer server also collects these updated +/// statistics. +#[derive(Clone, Debug)] +pub struct VirtualDiskProducer { + // Shareable inner type actually managing the stats. + inner: Arc>, +} + +impl VirtualDiskProducer { + /// Create a producer to track a virtual disk. + pub fn new( + block_size: u32, + instance_id: Uuid, + disk_id: Uuid, + metadata: &InstanceMetadata, + ) -> Self { + let disk = VirtualDisk { + attached_instance_id: instance_id, + block_size, + disk_id, + project_id: metadata.project_id, + silo_id: metadata.silo_id, + }; + let now = Utc::now(); + let datum = Cumulative::with_start_time(now, 0); + let latency_histogram = Self::latency_histogram(); + let size_histogram = Self::size_histogram(); + let inner = VirtualDiskStats { + disk, + reads: Reads { datum }, + bytes_read: BytesRead { datum }, + failed_reads: [ + FailedReads { failure_reason: FAILURE_KIND.into(), datum }, + FailedReads { failure_reason: READONLY_KIND.into(), datum }, + FailedReads { failure_reason: UNSUPPORTED_KIND.into(), datum }, + ], + writes: Writes { datum }, + bytes_written: BytesWritten { datum }, + failed_writes: [ + FailedWrites { failure_reason: FAILURE_KIND.into(), datum }, + FailedWrites { failure_reason: READONLY_KIND.into(), datum }, + FailedWrites { failure_reason: UNSUPPORTED_KIND.into(), datum }, + ], + flushes: Flushes { datum }, + failed_flushes: [ + FailedFlushes { failure_reason: FAILURE_KIND.into(), datum }, + FailedFlushes { failure_reason: READONLY_KIND.into(), datum }, + FailedFlushes { + failure_reason: UNSUPPORTED_KIND.into(), + datum, + }, + ], + io_latency: [ + IoLatency { + io_kind: READ_KIND.into(), + datum: latency_histogram.clone(), + }, + IoLatency { + io_kind: WRITE_KIND.into(), + datum: latency_histogram.clone(), + }, + IoLatency { + io_kind: FLUSH_KIND.into(), + datum: latency_histogram.clone(), + }, + ], + io_size: [ + IoSize { + io_kind: READ_KIND.into(), + datum: size_histogram.clone(), + }, + IoSize { + io_kind: WRITE_KIND.into(), + datum: size_histogram.clone(), + }, + ], + }; + Self { inner: Arc::new(Mutex::new(inner)) } + } + + /// A callback that updates statistics with the result of a completed I/O. + pub fn on_completion( + &self, + op: block::Operation, + result: block::Result, + duration: Duration, + ) { + self.inner.lock().unwrap().on_completion(op, result, duration); + } + + /// Construct a histogram for tracking I/O latencies. + /// + /// This builds a "log-linear" histogram, which has 10 bins for each power + /// of 10, spaced between 1 microsecond and 10s inclusive. + fn latency_histogram() -> Histogram { + // Safety: This only fails if the bins are not valid. + Histogram::span_decades(LATENCY_POWERS.0, LATENCY_POWERS.1).unwrap() + } + + /// Construct a histogram for tracking I/O sizes. + /// + /// This creates a power-of-2 histogram for tracking I/O sizes between 512B + /// and 1GiB. + fn size_histogram() -> Histogram { + let bins: Vec<_> = + (SIZE_POWERS.0..=SIZE_POWERS.1).map(|p| 1u64 << p).collect(); + + // Safety: This only fails if the bins are not valid. + Histogram::new(&bins).unwrap() + } +} + +impl Producer for VirtualDiskProducer { + fn produce( + &mut self, + ) -> Result>, MetricsError> { + // 5 scalar samples (reads, writes, flushes, bytes read / written) + // 3 scalars broken out by failure kind + // 2 histograms broken out by I/O kind + const N_SAMPLES: usize = 5 + 3 * N_FAILURE_KINDS + 2 * N_IO_KINDS; + let mut out = Vec::with_capacity(N_SAMPLES); + let inner = self.inner.lock().unwrap(); + + // Read statistics. + out.push(Sample::new(&inner.disk, &inner.reads)?); + out.push(Sample::new(&inner.disk, &inner.bytes_read)?); + for failed in inner.failed_reads.iter() { + out.push(Sample::new(&inner.disk, failed)?); + } + + // Write statistics. + out.push(Sample::new(&inner.disk, &inner.writes)?); + out.push(Sample::new(&inner.disk, &inner.bytes_written)?); + for failed in inner.failed_writes.iter() { + out.push(Sample::new(&inner.disk, failed)?); + } + + // Flushes + out.push(Sample::new(&inner.disk, &inner.flushes)?); + for failed in inner.failed_flushes.iter() { + out.push(Sample::new(&inner.disk, failed)?); + } + + // Histograms for latency and size. + for hist in inner.io_latency.iter() { + out.push(Sample::new(&inner.disk, hist)?); + } + for hist in inner.io_size.iter() { + out.push(Sample::new(&inner.disk, hist)?); + } + drop(inner); + Ok(Box::new(out.into_iter())) + } +} + +#[cfg(test)] +mod test { + use super::VirtualDiskProducer; + use super::LATENCY_POWERS; + use super::SIZE_POWERS; + + #[test] + fn test_latency_histogram() { + let hist = VirtualDiskProducer::latency_histogram(); + println!("{:#?}", hist.iter().map(|bin| bin.range).collect::>()); + // The math here is a bit silly, but we end up with 9 bins in each + // "interior" power of 10, plus one more bin on the right and left for + // the bins from [0, 1us) and [10s, inf) + assert_eq!( + hist.n_bins(), + (LATENCY_POWERS.1 - LATENCY_POWERS.0) as usize * 9 + 1 + 1 + ); + } + + #[test] + fn test_size_histogram() { + let hist = VirtualDiskProducer::size_histogram(); + println!("{:#?}", hist.iter().map(|bin| bin.range).collect::>()); + // 1 extra left bin for [0, 512), and 1 because the range is inclusive. + assert_eq!( + hist.n_bins(), + (SIZE_POWERS.1 - SIZE_POWERS.0) as usize + 1 + 1 + ); + } +} diff --git a/bin/propolis-server/src/lib/stats/virtual_machine.rs b/bin/propolis-server/src/lib/stats/virtual_machine.rs index 7dea2eeec..2e80c7458 100644 --- a/bin/propolis-server/src/lib/stats/virtual_machine.rs +++ b/bin/propolis-server/src/lib/stats/virtual_machine.rs @@ -22,6 +22,7 @@ use std::collections::BTreeMap; // lives in that repo, at // `./omicron/oximeter/oximeter/schema/virtual-machine.toml`. oximeter::use_timeseries!("virtual-machine.toml"); +pub use self::virtual_machine::Reset; use self::virtual_machine::{ VcpuUsage, VirtualMachine as VirtualMachineTarget, }; @@ -147,14 +148,6 @@ pub struct VirtualMachine { vm_name: String, } -impl VirtualMachine { - /// Return the number of vCPUs in this VM. - #[cfg_attr(test, allow(dead_code))] - pub(crate) fn n_vcpus(&self) -> u32 { - self.n_vcpus - } -} - impl From<&propolis_api_types::InstanceProperties> for VirtualMachine { fn from(properties: &propolis_api_types::InstanceProperties) -> Self { Self { diff --git a/bin/propolis-server/src/lib/vm/ensure.rs b/bin/propolis-server/src/lib/vm/ensure.rs index 75232e9f7..b0e4317a0 100644 --- a/bin/propolis-server/src/lib/vm/ensure.rs +++ b/bin/propolis-server/src/lib/vm/ensure.rs @@ -180,6 +180,12 @@ impl<'a> VmEnsureNotStarted<'a> { state: MachineInitializerState::default(), }; + // If we are publishing metrics to oximeter, then create a kstat-sampler + // now. This is used to track the vCPUs today, but will soon be used to + // track instance datalink stats as well. It can be provided to + // `initialize_network_devices()` at that time. + let maybe_kstat_sampler = init.create_kstat_sampler(); + init.initialize_rom(options.toml_config.bootrom.as_path())?; let chipset = init.initialize_chipset( &(event_queue.clone() @@ -213,7 +219,7 @@ impl<'a> VmEnsureNotStarted<'a> { .await?; let ramfb = init.initialize_fwcfg(v0_spec.devices.board.cpus)?; - init.initialize_cpus()?; + init.initialize_cpus(&maybe_kstat_sampler).await?; let vcpu_tasks = Box::new(crate::vcpu_tasks::VcpuTasks::new( &machine, event_queue.clone() diff --git a/bin/propolis-server/src/lib/vm/services.rs b/bin/propolis-server/src/lib/vm/services.rs index fb60c6fe7..5a51770c3 100644 --- a/bin/propolis-server/src/lib/vm/services.rs +++ b/bin/propolis-server/src/lib/vm/services.rs @@ -12,8 +12,10 @@ use propolis_api_types::InstanceProperties; use slog::{error, info, Logger}; use crate::{ - serial::SerialTaskControlMessage, server::MetricsEndpointConfig, - stats::virtual_machine::VirtualMachine, vnc::VncServer, + serial::SerialTaskControlMessage, + server::MetricsEndpointConfig, + stats::{virtual_machine::VirtualMachine, ServerStats}, + vnc::VncServer, }; use super::objects::{VmObjects, VmObjectsShared}; @@ -26,7 +28,7 @@ pub(crate) struct OximeterState { server: Option, /// The statistics object used by the API layer to record its metrics. - pub stats: Option, + pub stats: Option, } /// A collection of services visible to consumers outside this Propolis that @@ -35,7 +37,10 @@ pub(crate) struct VmServices { /// A VM's serial console handler task. pub serial_task: tokio::sync::Mutex>, - /// A VM's Oximeter server. + /// A VM's Oximeter state. + /// + /// This mostly contains the actual producer server, though the + /// "server-level stats" are also included here. pub oximeter: tokio::sync::Mutex, /// A reference to the VM's host process's VNC server. @@ -138,26 +143,16 @@ async fn register_oximeter_producer( // Assign our own metrics production for this VM instance to the // registry, letting the server actually return them to oximeter when // polled. - oximeter_state.stats = match crate::stats::register_server_metrics( - registry, - virtual_machine, - log, - ) - .await - { - Ok(stats) => Some(stats), - Err(e) => { - error!( - log, - "failed to register our server metrics with \ - the ProducerRegistry, no server stats will \ - be produced"; - "error" => ?e, - ); - - None - } - }; + let stats = ServerStats::new(virtual_machine); + if let Err(e) = registry.register_producer(stats.clone()) { + error!( + log, + "failed to register our server metrics with \ + the ProducerRegistry, no server stats will \ + be produced"; + "error" => ?e, + ); + } oximeter_state } diff --git a/lib/propolis/src/block/crucible.rs b/lib/propolis/src/block/crucible.rs index e7c19ea51..8383044b5 100644 --- a/lib/propolis/src/block/crucible.rs +++ b/lib/propolis/src/block/crucible.rs @@ -154,6 +154,16 @@ impl CrucibleBackend { })) } + /// Return the block size of this Crucible backend, if it can be determined. + pub async fn block_size(&self) -> Option { + self.state + .volume + .get_block_size() + .await + .ok() + .and_then(|sz| sz.try_into().ok()) + } + /// Create Crucible backend using the in-memory volume backend, rather than /// "real" Crucible downstairs instances. pub async fn create_mem( diff --git a/lib/propolis/src/block/mod.rs b/lib/propolis/src/block/mod.rs index 5e838e62d..cd210ed25 100644 --- a/lib/propolis/src/block/mod.rs +++ b/lib/propolis/src/block/mod.rs @@ -13,6 +13,7 @@ use crate::vmm::{MemCtx, SubMapping}; mod file; pub use file::FileBackend; +use tracking::CompletionCallback; #[cfg(feature = "crucible")] mod crucible; @@ -224,6 +225,11 @@ pub trait Device: Send + Sync + 'static { /// Complete processing of result fn complete(&self, res: Result, id: ReqId); + /// Attach a callback to be run on completion of I/Os. + /// + /// Returns whether there was a previously-registered callback. + fn on_completion(&self, _cb: Box) -> bool; + /// Get an accessor to guest memory via the underlying device fn accessor_mem(&self) -> MemAccessor; diff --git a/lib/propolis/src/block/tracking.rs b/lib/propolis/src/block/tracking.rs index 478a8b652..437a034cb 100644 --- a/lib/propolis/src/block/tracking.rs +++ b/lib/propolis/src/block/tracking.rs @@ -10,12 +10,23 @@ use std::pin::Pin; use std::sync::atomic::{AtomicU64, Ordering}; use std::sync::{Arc, Mutex, Weak}; use std::task::{Context, Poll, Waker}; -use std::time::Instant; +use std::time::{Duration, Instant}; use crate::block::{self, probes, Device, Operation, ReqId, Request}; static NEXT_DEVICE_ID: AtomicU64 = AtomicU64::new(1); +/// A function that is called when a block operation completes. +pub trait CompletionCallback: + Fn(Operation, block::Result, Duration) + Send + Sync + 'static +{ +} + +impl CompletionCallback for T where + T: Fn(Operation, block::Result, Duration) + Send + Sync + 'static +{ +} + /// Tracking structure for outstanding block [`Request`]s. /// /// As requests are emitted to the associated backend, the corresponding data @@ -26,6 +37,11 @@ static NEXT_DEVICE_ID: AtomicU64 = AtomicU64::new(1); /// Although use of [`Tracking`] is not required by the block abstraction, it is /// here where the general USDT probes are attached. A device which eschews its /// use will be missing calls into those probes. +/// +/// Each [`Tracking`] also allows one optional callback that it will call +/// whenever an I/O is completed. This can be set in the +/// [`Tracking::with_completion_callback()`] constructor, or with +/// [`Tracking::set_completion_callback()`]. pub struct Tracking { inner: Mutex>, wait: Arc>, @@ -35,6 +51,7 @@ struct TrackingInner { next_id: ReqId, dev: Weak, outstanding: BTreeMap>, + on_completion: Option>, } struct TrackingEntry { op: Operation, @@ -45,6 +62,10 @@ struct TrackingEntry { /// Track device-specific data for outstanding block [Request]s. impl Tracking { + /// Create a new block tracking object. + /// + /// NOTE: This does not set the completion callback, use + /// [`Self::set_completion_callback()`] to do so. pub fn new(dev: Weak) -> Self { let device_id = NEXT_DEVICE_ID.fetch_add(1, Ordering::Relaxed); Self { @@ -53,11 +74,22 @@ impl Tracking { next_id: ReqId::START, dev, outstanding: BTreeMap::new(), + on_completion: None, }), wait: Arc::new(Mutex::new(TrackingWait::new())), } } + /// Set or overwrite the completion callback. + /// + /// Returns true if there was a previous callback. + pub fn set_completion_callback( + &self, + cb: Box, + ) -> bool { + self.inner.lock().unwrap().on_completion.replace(cb).is_some() + } + /// Record tracking in an [`Request`] prior to passing it to the associated /// [`block::Backend`]. The request will be assigned a unique [`ReqId`] /// which can be used to a later call to [`Tracking::complete()`] to @@ -116,8 +148,8 @@ impl Tracking { .expect("tracked request should be present"); let devid = guard.device_id; - let proc_ns = - now.duration_since(entry.time_submitted).as_nanos() as u64; + let elapsed = now.duration_since(entry.time_submitted); + let proc_ns = elapsed.as_nanos() as u64; // TODO: calculate queued time let queue_ns = 0; let rescode = res as u8; @@ -139,6 +171,10 @@ impl Tracking { } } + if let Some(cb) = guard.on_completion.as_ref() { + cb(entry.op, res, elapsed); + } + if guard.outstanding.is_empty() { self.wait.lock().unwrap().set_empty(); } diff --git a/lib/propolis/src/hw/nvme/requests.rs b/lib/propolis/src/hw/nvme/requests.rs index 6f4de820a..0ff12a82f 100644 --- a/lib/propolis/src/hw/nvme/requests.rs +++ b/lib/propolis/src/hw/nvme/requests.rs @@ -4,7 +4,10 @@ use crate::{ accessors::MemAccessor, - block::{self, Operation, Request, Result as BlockResult}, + block::{ + self, tracking::CompletionCallback, Operation, Request, + Result as BlockResult, + }, hw::nvme::{bits, cmds::Completion}, vmm::mem::MemCtx, }; @@ -51,6 +54,10 @@ impl block::Device for PciNvme { self.complete_req(op, res, permit); } + fn on_completion(&self, cb: Box) -> bool { + self.block_tracking.set_completion_callback(cb) + } + fn accessor_mem(&self) -> MemAccessor { self.pci_state.acc_mem.child(Some("block backend".to_string())) } diff --git a/lib/propolis/src/hw/virtio/block.rs b/lib/propolis/src/hw/virtio/block.rs index d1e7fb5ab..79d3076c5 100644 --- a/lib/propolis/src/hw/virtio/block.rs +++ b/lib/propolis/src/hw/virtio/block.rs @@ -7,6 +7,7 @@ use std::sync::{Arc, Weak}; use crate::accessors::MemAccessor; use crate::block; +use crate::block::tracking::CompletionCallback; use crate::common::*; use crate::hw::pci; use crate::migrate::*; @@ -250,6 +251,10 @@ impl block::Device for PciVirtioBlock { self.complete_req(rid, op, res, chain); } + fn on_completion(&self, cb: Box) -> bool { + self.block_tracking.set_completion_callback(cb) + } + fn accessor_mem(&self) -> MemAccessor { self.pci_state.acc_mem.child(Some("block backend".to_string())) }