From 8dbc358e3f58d9fd56067a4d0f8535fa50283b38 Mon Sep 17 00:00:00 2001 From: Mike Zeller Date: Mon, 20 Nov 2023 21:19:25 +0000 Subject: [PATCH 01/18] Use libipcc lib instead of raw ioctl calls --- Cargo.lock | 6 +- Cargo.toml | 6 +- gateway/Cargo.toml | 2 +- gateway/src/http_entrypoints.rs | 13 +- gateway/src/http_entrypoints/conversions.rs | 2 +- installinator/Cargo.toml | 2 +- installinator/src/artifact.rs | 4 +- ipcc-key-value/src/ioctl.rs | 126 -------------------- ipcc-key-value/src/ioctl_common.rs | 57 --------- ipcc-key-value/src/ioctl_stub.rs | 32 ----- {ipcc-key-value => ipcc}/Cargo.toml | 2 +- ipcc/build.rs | 9 ++ ipcc/src/ffi.rs | 62 ++++++++++ ipcc/src/ipcc.rs | 109 +++++++++++++++++ ipcc/src/ipcc_common.rs | 60 ++++++++++ {ipcc-key-value => ipcc}/src/lib.rs | 15 +-- 16 files changed, 264 insertions(+), 243 deletions(-) delete mode 100644 ipcc-key-value/src/ioctl.rs delete mode 100644 ipcc-key-value/src/ioctl_common.rs delete mode 100644 ipcc-key-value/src/ioctl_stub.rs rename {ipcc-key-value => ipcc}/Cargo.toml (94%) create mode 100644 ipcc/build.rs create mode 100644 ipcc/src/ffi.rs create mode 100644 ipcc/src/ipcc.rs create mode 100644 ipcc/src/ipcc_common.rs rename {ipcc-key-value => ipcc}/src/lib.rs (98%) diff --git a/Cargo.lock b/Cargo.lock index 113bc6f003..4fe5c8e29a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3174,7 +3174,7 @@ dependencies = [ "illumos-utils", "installinator-artifact-client", "installinator-common", - "ipcc-key-value", + "ipcc", "itertools 0.12.0", "libc", "omicron-common", @@ -3323,7 +3323,7 @@ dependencies = [ ] [[package]] -name = "ipcc-key-value" +name = "ipcc" version = "0.1.0" dependencies = [ "ciborium", @@ -4544,7 +4544,7 @@ dependencies = [ "http", "hyper", "illumos-utils", - "ipcc-key-value", + "ipcc", "omicron-common", "omicron-test-utils", "omicron-workspace-hack", diff --git a/Cargo.toml b/Cargo.toml index b55c4fca6a..75c0eae33e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ members = [ "installinator", "internal-dns-cli", "internal-dns", - "ipcc-key-value", + "ipcc", "key-manager", "nexus", "nexus/authz-macros", @@ -102,7 +102,7 @@ default-members = [ "installinator", "internal-dns-cli", "internal-dns", - "ipcc-key-value", + "ipcc", "key-manager", "nexus", "nexus/authz-macros", @@ -221,7 +221,7 @@ installinator-artifactd = { path = "installinator-artifactd" } installinator-artifact-client = { path = "clients/installinator-artifact-client" } installinator-common = { path = "installinator-common" } internal-dns = { path = "internal-dns" } -ipcc-key-value = { path = "ipcc-key-value" } +ipcc = { path = "ipcc" } ipnetwork = { version = "0.20", features = ["schemars"] } itertools = "0.12.0" key-manager = { path = "key-manager" } diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index 75c31e9977..8151ee593e 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -16,7 +16,7 @@ hex.workspace = true http.workspace = true hyper.workspace = true illumos-utils.workspace = true -ipcc-key-value.workspace = true +ipcc.workspace = true omicron-common.workspace = true once_cell.workspace = true schemars.workspace = true diff --git a/gateway/src/http_entrypoints.rs b/gateway/src/http_entrypoints.rs index 2db6121f1d..1dd069621d 100644 --- a/gateway/src/http_entrypoints.rs +++ b/gateway/src/http_entrypoints.rs @@ -443,11 +443,11 @@ pub struct ImageVersion { pub version: u32, } -// This type is a duplicate of the type in `ipcc-key-value`, and we provide a +// This type is a duplicate of the type in `ipcc`, and we provide a // `From<_>` impl to convert to it. We keep these types distinct to allow us to // choose different representations for MGS's HTTP API (this type) and the wire // format passed through the SP to installinator -// (`ipcc_key_value::InstallinatorImageId`), although _currently_ they happen to +// (`ipcc::InstallinatorImageId`), although _currently_ they happen to // be defined identically. #[derive( Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema, @@ -1228,7 +1228,7 @@ async fn sp_power_state_set( /// Set the installinator image ID the sled should use for recovery. /// -/// This value can be read by the host via IPCC; see the `ipcc-key-value` crate. +/// This value can be read by the host via IPCC; see the `ipcc` crate. #[endpoint { method = PUT, path = "/sp/{type}/{slot}/ipcc/installinator-image-id", @@ -1238,13 +1238,12 @@ async fn sp_installinator_image_id_set( path: Path, body: TypedBody, ) -> Result { - use ipcc_key_value::Key; + use ipcc::Key; let apictx = rqctx.context(); let sp = apictx.mgmt_switch.sp(path.into_inner().sp.into())?; - let image_id = - ipcc_key_value::InstallinatorImageId::from(body.into_inner()); + let image_id = ipcc::InstallinatorImageId::from(body.into_inner()); sp.set_ipcc_key_lookup_value( Key::InstallinatorImageId as u8, @@ -1265,7 +1264,7 @@ async fn sp_installinator_image_id_delete( rqctx: RequestContext>, path: Path, ) -> Result { - use ipcc_key_value::Key; + use ipcc::Key; let apictx = rqctx.context(); let sp = apictx.mgmt_switch.sp(path.into_inner().sp.into())?; diff --git a/gateway/src/http_entrypoints/conversions.rs b/gateway/src/http_entrypoints/conversions.rs index 1182163bcc..a4aef7425e 100644 --- a/gateway/src/http_entrypoints/conversions.rs +++ b/gateway/src/http_entrypoints/conversions.rs @@ -397,7 +397,7 @@ impl From for HostStartupOptions { } } -impl From for ipcc_key_value::InstallinatorImageId { +impl From for ipcc::InstallinatorImageId { fn from(id: InstallinatorImageId) -> Self { Self { update_id: id.update_id, diff --git a/installinator/Cargo.toml b/installinator/Cargo.toml index d489e73ec1..43966d1202 100644 --- a/installinator/Cargo.toml +++ b/installinator/Cargo.toml @@ -20,7 +20,7 @@ http.workspace = true illumos-utils.workspace = true installinator-artifact-client.workspace = true installinator-common.workspace = true -ipcc-key-value.workspace = true +ipcc.workspace = true itertools.workspace = true libc.workspace = true omicron-common.workspace = true diff --git a/installinator/src/artifact.rs b/installinator/src/artifact.rs index f74d7b7f06..734759a2c2 100644 --- a/installinator/src/artifact.rs +++ b/installinator/src/artifact.rs @@ -9,7 +9,7 @@ use clap::Args; use futures::StreamExt; use installinator_artifact_client::ClientError; use installinator_common::EventReport; -use ipcc_key_value::{InstallinatorImageId, Ipcc}; +use ipcc::{InstallinatorImageId, Ipcc}; use omicron_common::update::{ArtifactHash, ArtifactHashId}; use tokio::sync::mpsc; use uuid::Uuid; @@ -47,7 +47,7 @@ pub(crate) struct ArtifactIdOpts { impl ArtifactIdOpts { pub(crate) fn resolve(&self) -> Result { if self.from_ipcc { - let ipcc = Ipcc::open().context("error opening IPCC")?; + let ipcc = Ipcc::new().context("error opening IPCC")?; ipcc.installinator_image_id() .context("error retrieving installinator image ID") } else { diff --git a/ipcc-key-value/src/ioctl.rs b/ipcc-key-value/src/ioctl.rs deleted file mode 100644 index b0524e973f..0000000000 --- a/ipcc-key-value/src/ioctl.rs +++ /dev/null @@ -1,126 +0,0 @@ -// 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 2023 Oxide Computer Company - -//! IPCC `ioctl` interface. -//! -//! This module is tightly-coupled to the host OS image, and should only be used -//! by services bundled with it (e.g., sled-agent and installinator). - -use crate::InstallinatorImageId; -use crate::InstallinatorImageIdError; -use crate::IpccKey; -use crate::IpccKeyLookupError; -use crate::PingError; -use crate::Pong; -use libc::c_int; -use std::fs::File; -use std::io; -use std::os::unix::prelude::AsRawFd; - -pub struct Ipcc { - file: File, -} - -impl Ipcc { - pub fn open() -> io::Result { - let file = File::options().read(true).write(true).open(IPCC_DEV)?; - Ok(Self { file }) - } - - pub fn ping(&self) -> Result { - const EXPECTED_REPLY: &[u8] = b"pong"; - - let mut buf = [0; EXPECTED_REPLY.len()]; - let n = self.key_lookup(IpccKey::Ping, &mut buf)?; - let buf = &buf[..n]; - - if buf == EXPECTED_REPLY { - Ok(Pong) - } else { - Err(PingError::UnexpectedReply(buf.to_vec())) - } - } - - pub fn installinator_image_id( - &self, - ) -> Result { - let mut buf = [0; InstallinatorImageId::CBOR_SERIALIZED_SIZE]; - let n = self.key_lookup(IpccKey::InstallinatorImageId, &mut buf)?; - let id = InstallinatorImageId::deserialize(&buf[..n]) - .map_err(InstallinatorImageIdError::DeserializationFailed)?; - Ok(id) - } - - fn key_lookup( - &self, - key: IpccKey, - buf: &mut [u8], - ) -> Result { - let mut kl = IpccKeyLookup { - key: key as u8, - buflen: u16::try_from(buf.len()).unwrap_or(u16::MAX), - result: 0, - datalen: 0, - buf: buf.as_mut_ptr(), - }; - - let result = unsafe { - libc::ioctl( - self.file.as_raw_fd(), - IPCC_KEYLOOKUP, - &mut kl as *mut IpccKeyLookup, - ) - }; - - if result != 0 { - let error = io::Error::last_os_error(); - return Err(IpccKeyLookupError::IoctlFailed { key, error }); - } - - match kl.result { - IPCC_KEYLOOKUP_SUCCESS => Ok(usize::from(kl.datalen)), - IPCC_KEYLOOKUP_UNKNOWN_KEY => { - Err(IpccKeyLookupError::UnknownKey { key }) - } - IPCC_KEYLOOKUP_NO_VALUE => { - Err(IpccKeyLookupError::NoValueForKey { key }) - } - IPCC_KEYLOOKUP_BUFFER_TOO_SMALL => { - Err(IpccKeyLookupError::BufferTooSmallForValue { key }) - } - _ => Err(IpccKeyLookupError::UnknownResultValue { - key, - result: kl.result, - }), - } - } -} - -// -------------------------------------------------------------------- -// Constants and structures from stlouis `usr/src/uts/oxide/sys/ipcc.h` -// -------------------------------------------------------------------- - -const IPCC_DEV: &str = "/dev/ipcc"; - -const IPCC_IOC: c_int = - ((b'i' as c_int) << 24) | ((b'c' as c_int) << 16) | ((b'c' as c_int) << 8); - -const IPCC_KEYLOOKUP: c_int = IPCC_IOC | 4; - -const IPCC_KEYLOOKUP_SUCCESS: u8 = 0; -const IPCC_KEYLOOKUP_UNKNOWN_KEY: u8 = 1; -const IPCC_KEYLOOKUP_NO_VALUE: u8 = 2; -const IPCC_KEYLOOKUP_BUFFER_TOO_SMALL: u8 = 3; - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -struct IpccKeyLookup { - key: u8, - buflen: u16, - result: u8, - datalen: u16, - buf: *mut u8, -} diff --git a/ipcc-key-value/src/ioctl_common.rs b/ipcc-key-value/src/ioctl_common.rs deleted file mode 100644 index 670cc7bff2..0000000000 --- a/ipcc-key-value/src/ioctl_common.rs +++ /dev/null @@ -1,57 +0,0 @@ -// 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 2023 Oxide Computer Company - -//! This module contains types shared between the real (illumos-only) -//! `crate::ioctl` module and the generic `crate::ioctl_stub` module. - -use std::io; -use thiserror::Error; - -/// IPCC keys; the source of truth for these is RFD 316 + the -/// `host-sp-messages` crate in hubris. -#[derive(Debug, Clone, Copy)] -#[repr(u8)] -pub enum IpccKey { - Ping = 0, - InstallinatorImageId = 1, -} - -#[derive(Debug, Error)] -pub enum IpccKeyLookupError { - #[error("IPCC key lookup ioctl failed for key {key:?}: {error}")] - IoctlFailed { key: IpccKey, error: io::Error }, - #[error("IPCC key lookup failed for key {key:?}: unknown key")] - UnknownKey { key: IpccKey }, - #[error("IPCC key lookup failed for key {key:?}: no value for key")] - NoValueForKey { key: IpccKey }, - #[error( - "IPCC key lookup failed for key {key:?}: buffer too small for value" - )] - BufferTooSmallForValue { key: IpccKey }, - #[error( - "IPCC key lookup failed for key {key:?}: unknown result value {result}" - )] - UnknownResultValue { key: IpccKey, result: u8 }, -} - -#[derive(Debug, Error)] -pub enum InstallinatorImageIdError { - #[error(transparent)] - IpccKeyLookupError(#[from] IpccKeyLookupError), - #[error("deserializing installinator image ID failed: {0}")] - DeserializationFailed(String), -} - -#[derive(Debug, Error)] -pub enum PingError { - #[error(transparent)] - IpccKeyLookupError(#[from] IpccKeyLookupError), - #[error("unexpected reply from SP (expected `pong`: {0:?})")] - UnexpectedReply(Vec), -} - -#[derive(Debug, Clone, Copy)] -pub struct Pong; diff --git a/ipcc-key-value/src/ioctl_stub.rs b/ipcc-key-value/src/ioctl_stub.rs deleted file mode 100644 index cbf54b3eb4..0000000000 --- a/ipcc-key-value/src/ioctl_stub.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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 2023 Oxide Computer Company - -//! Stub definition of the `Ipcc` type for compiling (but not running) on -//! non-Oxide systems. - -use crate::InstallinatorImageId; -use crate::InstallinatorImageIdError; -use crate::PingError; -use crate::Pong; -use std::io; - -pub struct Ipcc {} - -impl Ipcc { - pub fn open() -> io::Result { - panic!("ipcc unavailable on this platform") - } - - pub fn ping(&self) -> Result { - panic!("ipcc unavailable on this platform") - } - - pub fn installinator_image_id( - &self, - ) -> Result { - panic!("ipcc unavailable on this platform") - } -} diff --git a/ipcc-key-value/Cargo.toml b/ipcc/Cargo.toml similarity index 94% rename from ipcc-key-value/Cargo.toml rename to ipcc/Cargo.toml index 04aea9f939..3c060c8b64 100644 --- a/ipcc-key-value/Cargo.toml +++ b/ipcc/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "ipcc-key-value" +name = "ipcc" version = "0.1.0" edition = "2021" license = "MPL-2.0" diff --git a/ipcc/build.rs b/ipcc/build.rs new file mode 100644 index 0000000000..10ae655e79 --- /dev/null +++ b/ipcc/build.rs @@ -0,0 +1,9 @@ +fn main() { + #[cfg(target_os = "illumos")] + { + println!( + "cargo:rustc-link-arg=-Wl,-rpath,/usr/platform/oxide/lib/amd64" + ); + println!(r"cargo:rustc-link-search=/usr/platform/oxide/lib/amd64"); + } +} diff --git a/ipcc/src/ffi.rs b/ipcc/src/ffi.rs new file mode 100644 index 0000000000..edcab069cc --- /dev/null +++ b/ipcc/src/ffi.rs @@ -0,0 +1,62 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +use std::ffi::{c_char, c_int, c_uint}; + +/// Opaque libipcc handle +#[repr(C)] +pub(crate) struct libipcc_handle_t { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +pub(crate) const LIBIPCC_ERR_OK: libipcc_err_t = 0; +/// Indicates that there was a memory allocation error. The system error +/// contains the specific errno. +pub(crate) const LIBIPCC_ERR_NO_MEM: libipcc_err_t = 1; +/// One of the function parameters does not pass validation. There will be more +/// detail available via libipcc_errmsg(). +pub(crate) const LIBIPCC_ERR_INVALID_PARAM: libipcc_err_t = 2; +/// An internal error occurred. There will be more detail available via +/// libipcc_errmsg() and libipcc_syserr(). +pub(crate) const LIBIPCC_ERR_INTERNAL: libipcc_err_t = 3; +/// The requested lookup key was not known to the SP. +pub(crate) const LIBIPCC_ERR_KEY_UNKNOWN: libipcc_err_t = 4; +/// The value for the requested lookup key was too large for the +/// supplied buffer. +pub(crate) const LIBIPCC_ERR_KEY_BUFTOOSMALL: libipcc_err_t = 5; +/// An attempt to write to a key failed because the key is read-only. +pub(crate) const LIBIPCC_ERR_KEY_READONLY: libipcc_err_t = 6; +/// An attempt to write to a key failed because the passed value is too +/// long. +pub(crate) const LIBIPCC_ERR_KEY_VALTOOLONG: libipcc_err_t = 7; +/// Compression or decompression failed. If appropriate, libipcc_syserr() will +/// return the Z_ error from zlib. +pub(crate) const LIBIPCC_ERR_KEY_ZERR: libipcc_err_t = 8; +pub(crate) type libipcc_err_t = c_uint; + +// pub const libipcc_key_flag_t_LIBIPCC_KEYF_COMPRESSED: libipcc_key_flag_t = 1; +pub type libipcc_key_flag_t = ::std::os::raw::c_uint; + +#[link(name = "ipcc")] +extern "C" { + pub(crate) fn libipcc_init( + lihp: *mut *mut libipcc_handle_t, + libipcc_errp: *mut libipcc_err_t, + syserrp: *mut c_int, + errmsg: *const c_char, + errlen: usize, + ) -> bool; + pub(crate) fn libipcc_fini(lih: *mut libipcc_handle_t); + pub(crate) fn libipcc_err(lih: *mut libipcc_handle_t) -> libipcc_err_t; + pub(crate) fn libipcc_syserr(lih: *mut libipcc_handle_t) -> c_int; + pub(crate) fn libipcc_errmsg(lih: *mut libipcc_handle_t) -> *const c_char; + pub(crate) fn libipcc_keylookup( + lih: *mut libipcc_handle_t, + key: u8, + bufp: *mut *mut u8, + lenp: *mut usize, + flags: libipcc_key_flag_t, + ) -> bool; +} diff --git a/ipcc/src/ipcc.rs b/ipcc/src/ipcc.rs new file mode 100644 index 0000000000..14204618a0 --- /dev/null +++ b/ipcc/src/ipcc.rs @@ -0,0 +1,109 @@ +use std::{ + ffi::{c_int, CStr, CString}, + ptr, +}; + +use crate::ipcc_common::*; +use crate::{ffi::*, InstallinatorImageId, InstallinatorImageIdError, IpccKey}; + +pub struct Ipcc(*mut libipcc_handle_t); + +impl Drop for Ipcc { + fn drop(&mut self) { + unsafe { + libipcc_fini(self.0); + } + } +} +fn ipcc_fatal_error>( + context: C, + lerr: libipcc_err_t, + syserr: c_int, + errmsg: CString, +) -> IpccError { + let context = context.into(); + let syserr = if syserr == 0 { + "no system errno".to_string() + } else { + let syserr = unsafe { libc::strerror(syserr) }; + unsafe { CStr::from_ptr(syserr) }.to_string_lossy().into_owned() + }; + let inner = IpccErrorInner { + context, + errmsg: errmsg.to_string_lossy().into_owned(), + syserr, + }; + match lerr { + LIBIPCC_ERR_OK => panic!("called fatal on LIBIPCC_ERR_OK"), + LIBIPCC_ERR_NO_MEM => IpccError::NoMem(inner), + LIBIPCC_ERR_INVALID_PARAM => IpccError::InvalidParam(inner), + LIBIPCC_ERR_INTERNAL => IpccError::Internal(inner), + LIBIPCC_ERR_KEY_UNKNOWN => IpccError::Internal(inner), + LIBIPCC_ERR_KEY_BUFTOOSMALL => IpccError::KeyBufTooSmall(inner), + LIBIPCC_ERR_KEY_READONLY => IpccError::KeyReadonly(inner), + LIBIPCC_ERR_KEY_VALTOOLONG => IpccError::KeyValTooLong(inner), + LIBIPCC_ERR_KEY_ZERR => IpccError::KeyZerr(inner), + _ => IpccError::UnknownErr(inner), + } +} + +impl Ipcc { + pub fn new() -> Result { + let mut ipcc_handle: *mut libipcc_handle_t = ptr::null_mut(); + let errmsg = CString::new(vec![1; 1024]).unwrap(); + let errmsg_len = errmsg.as_bytes().len(); + let errmsg_ptr = errmsg.into_raw(); + let mut lerr = LIBIPCC_ERR_OK; + let mut syserr = 0; + if !unsafe { + libipcc_init( + &mut ipcc_handle, + &mut lerr, + &mut syserr, + errmsg_ptr, + errmsg_len, + ) + } { + let errmsg = unsafe { CString::from_raw(errmsg_ptr) }; + return Err(ipcc_fatal_error( + "Could not init libipcc handle", + lerr, + syserr, + errmsg, + )); + } + + Ok(Ipcc(ipcc_handle)) + } + + fn fatal>(&self, context: C) -> IpccError { + let lerr = unsafe { libipcc_err(self.0) }; + let errmsg = unsafe { libipcc_errmsg(self.0) }; + let errmsg = unsafe { CStr::from_ptr(errmsg) }.to_owned(); + let syserr = unsafe { libipcc_syserr(self.0) }; + ipcc_fatal_error(context, lerr, syserr, errmsg) + } + + fn key_lookup(&self, key: u8, buf: &mut [u8]) -> Result { + let mut lenp = buf.len(); + + if !unsafe { + libipcc_keylookup(self.0, key, &mut buf.as_mut_ptr(), &mut lenp, 0) + } { + return Err(self.fatal(format!("lookup of key {key} failed"))); + } + + Ok(lenp) + } + + pub fn installinator_image_id( + &self, + ) -> Result { + let mut buf = [0; InstallinatorImageId::CBOR_SERIALIZED_SIZE]; + let n = + self.key_lookup(IpccKey::InstallinatorImageId as u8, &mut buf)?; + let id = InstallinatorImageId::deserialize(&buf[..n]) + .map_err(InstallinatorImageIdError::DeserializationFailed)?; + Ok(id) + } +} diff --git a/ipcc/src/ipcc_common.rs b/ipcc/src/ipcc_common.rs new file mode 100644 index 0000000000..2facbfd505 --- /dev/null +++ b/ipcc/src/ipcc_common.rs @@ -0,0 +1,60 @@ +// 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 2023 Oxide Computer Company + +//! This module contains types shared between the real (illumos-only) +//! `crate::ioctl` module and the generic `crate::ioctl_stub` module. + +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum IpccError { + #[error("Memory allocation error")] + NoMem(#[source] IpccErrorInner), + #[error("Invalid parameter")] + InvalidParam(#[source] IpccErrorInner), + #[error("Internal error occurred")] + Internal(#[source] IpccErrorInner), + #[error("Requested lookup key was not known to the SP")] + KeyUnknown(#[source] IpccErrorInner), + #[error("Value for the requested lookup key was too large for the supplied buffer")] + KeyBufTooSmall(#[source] IpccErrorInner), + #[error("Attempted to write to read-only key")] + KeyReadonly(#[source] IpccErrorInner), + #[error("Attempted write to key failed because the value is too long")] + KeyValTooLong(#[source] IpccErrorInner), + #[error("Compression or decompression failed")] + KeyZerr(#[source] IpccErrorInner), + #[error("Unknown library error")] + UnknownErr(#[source] IpccErrorInner), +} + +#[derive(Error, Debug)] +#[error("{context}: {errmsg} ({syserr})")] +pub struct IpccErrorInner { + pub(crate) context: String, + pub(crate) errmsg: String, + pub(crate) syserr: String, +} + +/// IPCC keys; the source of truth for these is RFD 316 + the +/// `host-sp-messages` crate in hubris. +#[derive(Debug, Clone, Copy)] +#[repr(u8)] +pub enum IpccKey { + Ping = 0, + InstallinatorImageId = 1, + Inventory = 2, + System = 3, + Dtrace = 4, +} + +#[derive(Debug, Error)] +pub enum InstallinatorImageIdError { + #[error(transparent)] + Ipcc(#[from] IpccError), + #[error("deserializing installinator image ID failed: {0}")] + DeserializationFailed(String), +} diff --git a/ipcc-key-value/src/lib.rs b/ipcc/src/lib.rs similarity index 98% rename from ipcc-key-value/src/lib.rs rename to ipcc/src/lib.rs index 16e6685018..d58c178c01 100644 --- a/ipcc-key-value/src/lib.rs +++ b/ipcc/src/lib.rs @@ -12,18 +12,15 @@ use serde::Deserialize; use serde::Serialize; use uuid::Uuid; -mod ioctl_common; -pub use ioctl_common::*; +mod ipcc_common; +pub use ipcc_common::*; #[cfg(target_os = "illumos")] -mod ioctl; +mod ffi; #[cfg(target_os = "illumos")] -pub use ioctl::Ipcc; - -#[cfg(not(target_os = "illumos"))] -mod ioctl_stub; -#[cfg(not(target_os = "illumos"))] -pub use ioctl_stub::Ipcc; +pub mod ipcc; +#[cfg(target_os = "illumos")] +pub use ipcc::Ipcc; #[cfg(test)] use proptest::arbitrary::any; From c45227e2ab2d15cd22ad83bcd23c334e7fcece86 Mon Sep 17 00:00:00 2001 From: Mike Zeller Date: Mon, 20 Nov 2023 23:25:59 +0000 Subject: [PATCH 02/18] Support non illumos systems & minor cleanup --- Cargo.lock | 1 + ipcc/Cargo.toml | 1 + ipcc/src/ffi.rs | 1 - ipcc/src/{ipcc.rs => handle.rs} | 29 ++++----- ipcc/src/handle_stub.rs | 23 +++++++ ipcc/src/ipcc_common.rs | 60 ------------------- ipcc/src/lib.rs | 103 +++++++++++++++++++++++++++----- 7 files changed, 124 insertions(+), 94 deletions(-) rename ipcc/src/{ipcc.rs => handle.rs} (79%) create mode 100644 ipcc/src/handle_stub.rs delete mode 100644 ipcc/src/ipcc_common.rs diff --git a/Cargo.lock b/Cargo.lock index 4fe5c8e29a..39857def92 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3326,6 +3326,7 @@ dependencies = [ name = "ipcc" version = "0.1.0" dependencies = [ + "cfg-if 1.0.0", "ciborium", "libc", "omicron-common", diff --git a/ipcc/Cargo.toml b/ipcc/Cargo.toml index 3c060c8b64..98a781ab86 100644 --- a/ipcc/Cargo.toml +++ b/ipcc/Cargo.toml @@ -12,6 +12,7 @@ serde.workspace = true thiserror.workspace = true uuid.workspace = true omicron-workspace-hack.workspace = true +cfg-if.workspace = true [dev-dependencies] omicron-common = { workspace = true, features = ["testing"] } diff --git a/ipcc/src/ffi.rs b/ipcc/src/ffi.rs index edcab069cc..6dadf8cba0 100644 --- a/ipcc/src/ffi.rs +++ b/ipcc/src/ffi.rs @@ -36,7 +36,6 @@ pub(crate) const LIBIPCC_ERR_KEY_VALTOOLONG: libipcc_err_t = 7; pub(crate) const LIBIPCC_ERR_KEY_ZERR: libipcc_err_t = 8; pub(crate) type libipcc_err_t = c_uint; -// pub const libipcc_key_flag_t_LIBIPCC_KEYF_COMPRESSED: libipcc_key_flag_t = 1; pub type libipcc_key_flag_t = ::std::os::raw::c_uint; #[link(name = "ipcc")] diff --git a/ipcc/src/ipcc.rs b/ipcc/src/handle.rs similarity index 79% rename from ipcc/src/ipcc.rs rename to ipcc/src/handle.rs index 14204618a0..b0631b5f0d 100644 --- a/ipcc/src/ipcc.rs +++ b/ipcc/src/handle.rs @@ -3,12 +3,12 @@ use std::{ ptr, }; -use crate::ipcc_common::*; -use crate::{ffi::*, InstallinatorImageId, InstallinatorImageIdError, IpccKey}; +use crate::IpccError; +use crate::{ffi::*, IpccErrorInner}; -pub struct Ipcc(*mut libipcc_handle_t); +pub struct IpccHandle(*mut libipcc_handle_t); -impl Drop for Ipcc { +impl Drop for IpccHandle { fn drop(&mut self) { unsafe { libipcc_fini(self.0); @@ -47,7 +47,7 @@ fn ipcc_fatal_error>( } } -impl Ipcc { +impl IpccHandle { pub fn new() -> Result { let mut ipcc_handle: *mut libipcc_handle_t = ptr::null_mut(); let errmsg = CString::new(vec![1; 1024]).unwrap(); @@ -73,7 +73,7 @@ impl Ipcc { )); } - Ok(Ipcc(ipcc_handle)) + Ok(IpccHandle(ipcc_handle)) } fn fatal>(&self, context: C) -> IpccError { @@ -84,7 +84,11 @@ impl Ipcc { ipcc_fatal_error(context, lerr, syserr, errmsg) } - fn key_lookup(&self, key: u8, buf: &mut [u8]) -> Result { + pub(crate) fn key_lookup( + &self, + key: u8, + buf: &mut [u8], + ) -> Result { let mut lenp = buf.len(); if !unsafe { @@ -95,15 +99,4 @@ impl Ipcc { Ok(lenp) } - - pub fn installinator_image_id( - &self, - ) -> Result { - let mut buf = [0; InstallinatorImageId::CBOR_SERIALIZED_SIZE]; - let n = - self.key_lookup(IpccKey::InstallinatorImageId as u8, &mut buf)?; - let id = InstallinatorImageId::deserialize(&buf[..n]) - .map_err(InstallinatorImageIdError::DeserializationFailed)?; - Ok(id) - } } diff --git a/ipcc/src/handle_stub.rs b/ipcc/src/handle_stub.rs new file mode 100644 index 0000000000..f45b02d0f1 --- /dev/null +++ b/ipcc/src/handle_stub.rs @@ -0,0 +1,23 @@ +use std::{ + ffi::{c_int, CStr, CString}, + ptr, +}; + +use crate::ffi::*; +use crate::ipcc_common::*; + +pub struct IpccHandle; + +impl IpccHandle { + pub fn new() -> Result { + panic!("ipcc unavailable on this platform") + } + + pub(crate) fn key_lookup( + &self, + key: u8, + buf: &mut [u8], + ) -> Result { + panic!("ipcc unavailable on this platform") + } +} diff --git a/ipcc/src/ipcc_common.rs b/ipcc/src/ipcc_common.rs deleted file mode 100644 index 2facbfd505..0000000000 --- a/ipcc/src/ipcc_common.rs +++ /dev/null @@ -1,60 +0,0 @@ -// 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 2023 Oxide Computer Company - -//! This module contains types shared between the real (illumos-only) -//! `crate::ioctl` module and the generic `crate::ioctl_stub` module. - -use thiserror::Error; - -#[derive(Error, Debug)] -pub enum IpccError { - #[error("Memory allocation error")] - NoMem(#[source] IpccErrorInner), - #[error("Invalid parameter")] - InvalidParam(#[source] IpccErrorInner), - #[error("Internal error occurred")] - Internal(#[source] IpccErrorInner), - #[error("Requested lookup key was not known to the SP")] - KeyUnknown(#[source] IpccErrorInner), - #[error("Value for the requested lookup key was too large for the supplied buffer")] - KeyBufTooSmall(#[source] IpccErrorInner), - #[error("Attempted to write to read-only key")] - KeyReadonly(#[source] IpccErrorInner), - #[error("Attempted write to key failed because the value is too long")] - KeyValTooLong(#[source] IpccErrorInner), - #[error("Compression or decompression failed")] - KeyZerr(#[source] IpccErrorInner), - #[error("Unknown library error")] - UnknownErr(#[source] IpccErrorInner), -} - -#[derive(Error, Debug)] -#[error("{context}: {errmsg} ({syserr})")] -pub struct IpccErrorInner { - pub(crate) context: String, - pub(crate) errmsg: String, - pub(crate) syserr: String, -} - -/// IPCC keys; the source of truth for these is RFD 316 + the -/// `host-sp-messages` crate in hubris. -#[derive(Debug, Clone, Copy)] -#[repr(u8)] -pub enum IpccKey { - Ping = 0, - InstallinatorImageId = 1, - Inventory = 2, - System = 3, - Dtrace = 4, -} - -#[derive(Debug, Error)] -pub enum InstallinatorImageIdError { - #[error(transparent)] - Ipcc(#[from] IpccError), - #[error("deserializing installinator image ID failed: {0}")] - DeserializationFailed(String), -} diff --git a/ipcc/src/lib.rs b/ipcc/src/lib.rs index d58c178c01..6a8c51adc6 100644 --- a/ipcc/src/lib.rs +++ b/ipcc/src/lib.rs @@ -7,20 +7,23 @@ //! Utilities for key/value pairs passed from the control plane to the SP //! (through MGS) to the host (through the host/SP uart) via IPCC. +use cfg_if::cfg_if; use omicron_common::update::ArtifactHash; use serde::Deserialize; use serde::Serialize; +use thiserror::Error; use uuid::Uuid; -mod ipcc_common; -pub use ipcc_common::*; - -#[cfg(target_os = "illumos")] -mod ffi; -#[cfg(target_os = "illumos")] -pub mod ipcc; -#[cfg(target_os = "illumos")] -pub use ipcc::Ipcc; +cfg_if! { + if #[cfg(target_os = "illumos")] { + mod ffi; + mod handle; + use handle::IpccHandle; + } else { + mod handle_stub; + use handle_stub::IpccHandle; + } +} #[cfg(test)] use proptest::arbitrary::any; @@ -35,9 +38,9 @@ use proptest::strategy::Strategy; #[repr(u8)] pub enum Key { /// Always responds `"pong"`. - Ping = 0, + Ping = IpccKey::Ping as u8, /// The value should be an encoded [`InstallinatorImageId`]. - InstallinatorImageId = 1, + InstallinatorImageId = IpccKey::InstallinatorImageId as u8, } /// Description of the images `installinator` needs to fetch from a peer on the @@ -132,10 +135,80 @@ impl InstallinatorImageId { } } -// TODO Add ioctl wrappers? `installinator` is the only client for -// `Key::InstallinatorImageId`, but we might grow other keys for other clients, -// at which point we probably want all the ioctl wrapping to happen in one -// place. +#[derive(Debug, Error)] +pub enum InstallinatorImageIdError { + #[error(transparent)] + Ipcc(#[from] IpccError), + #[error("deserializing installinator image ID failed: {0}")] + DeserializationFailed(String), +} + +#[derive(Error, Debug)] +pub enum IpccError { + #[error("Memory allocation error")] + NoMem(#[source] IpccErrorInner), + #[error("Invalid parameter")] + InvalidParam(#[source] IpccErrorInner), + #[error("Internal error occurred")] + Internal(#[source] IpccErrorInner), + #[error("Requested lookup key was not known to the SP")] + KeyUnknown(#[source] IpccErrorInner), + #[error("Value for the requested lookup key was too large for the supplied buffer")] + KeyBufTooSmall(#[source] IpccErrorInner), + #[error("Attempted to write to read-only key")] + KeyReadonly(#[source] IpccErrorInner), + #[error("Attempted write to key failed because the value is too long")] + KeyValTooLong(#[source] IpccErrorInner), + #[error("Compression or decompression failed")] + KeyZerr(#[source] IpccErrorInner), + #[error("Unknown libipcc error")] + UnknownErr(#[source] IpccErrorInner), +} + +#[derive(Error, Debug)] +#[error("{context}: {errmsg} ({syserr})")] +pub struct IpccErrorInner { + pub context: String, + pub errmsg: String, + pub syserr: String, +} + +/// These are the IPCC keys we can lookup. +/// NB: These keys match the definitions found in libipcc (RFD 316) and should +/// match the values in `[ipcc::Key]` one-to-one. +#[derive(Debug, Clone, Copy)] +#[allow(dead_code)] +#[repr(u8)] +enum IpccKey { + Ping = 0, + InstallinatorImageId = 1, + Inventory = 2, + System = 3, + Dtrace = 4, +} + +pub struct Ipcc { + handle: IpccHandle, +} + +impl Ipcc { + pub fn new() -> Result { + let handle = IpccHandle::new()?; + Ok(Self { handle }) + } + + pub fn installinator_image_id( + &self, + ) -> Result { + let mut buf = [0; InstallinatorImageId::CBOR_SERIALIZED_SIZE]; + let n = self + .handle + .key_lookup(IpccKey::InstallinatorImageId as u8, &mut buf)?; + let id = InstallinatorImageId::deserialize(&buf[..n]) + .map_err(InstallinatorImageIdError::DeserializationFailed)?; + Ok(id) + } +} #[cfg(test)] mod tests { From 724ed2263d7e07ef0d74f4a0491ef8b138695c6a Mon Sep 17 00:00:00 2001 From: Mike Zeller Date: Tue, 21 Nov 2023 03:11:55 +0000 Subject: [PATCH 03/18] Temporary workaround for ipcc runtime path --- .cargo/config | 2 +- ipcc/build.rs | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.cargo/config b/.cargo/config index 6794e988ad..3f99418434 100644 --- a/.cargo/config +++ b/.cargo/config @@ -13,7 +13,7 @@ rustdocflags = "--document-private-items" # things critical to correctness probably don't belong here. [target.x86_64-unknown-illumos] rustflags = [ - "-C", "link-arg=-Wl,-znocompstrtab" + "-C", "link-arg=-Wl,-znocompstrtab,-R/usr/platform/oxide/lib/amd64" ] # Set up `cargo xtask`. diff --git a/ipcc/build.rs b/ipcc/build.rs index 10ae655e79..3bb051d36f 100644 --- a/ipcc/build.rs +++ b/ipcc/build.rs @@ -1,9 +1,14 @@ +// 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/. + +static OXIDE_PLATFORM: &str = "/usr/platform/oxide/lib/amd64/"; + fn main() { + println!("cargo:rerun-if-changed=build.rs"); #[cfg(target_os = "illumos")] { - println!( - "cargo:rustc-link-arg=-Wl,-rpath,/usr/platform/oxide/lib/amd64" - ); - println!(r"cargo:rustc-link-search=/usr/platform/oxide/lib/amd64"); + println!("cargo:rustc-link-arg=-Wl,-R{}", OXIDE_PLATFORM); + println!("cargo:rustc-link-search={}", OXIDE_PLATFORM); } } From b32d21bae51a7b3df965cc45179b65685f31bfaa Mon Sep 17 00:00:00 2001 From: Mike Zeller Date: Tue, 21 Nov 2023 03:14:01 +0000 Subject: [PATCH 04/18] Add MPL --- ipcc/src/ffi.rs | 6 ++++++ ipcc/src/handle.rs | 6 ++++++ ipcc/src/handle_stub.rs | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/ipcc/src/ffi.rs b/ipcc/src/ffi.rs index 6dadf8cba0..a96d6986ac 100644 --- a/ipcc/src/ffi.rs +++ b/ipcc/src/ffi.rs @@ -1,3 +1,9 @@ +// 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 2023 Oxide Computer Company + #![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] #![allow(non_snake_case)] diff --git a/ipcc/src/handle.rs b/ipcc/src/handle.rs index b0631b5f0d..d5f47d436d 100644 --- a/ipcc/src/handle.rs +++ b/ipcc/src/handle.rs @@ -1,3 +1,9 @@ +// 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 2023 Oxide Computer Company + use std::{ ffi::{c_int, CStr, CString}, ptr, diff --git a/ipcc/src/handle_stub.rs b/ipcc/src/handle_stub.rs index f45b02d0f1..64685d25dc 100644 --- a/ipcc/src/handle_stub.rs +++ b/ipcc/src/handle_stub.rs @@ -1,3 +1,9 @@ +// 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 2023 Oxide Computer Company + use std::{ ffi::{c_int, CStr, CString}, ptr, From cbcee086f0ef80c5b1ae5ae241a952a0c2d50fba Mon Sep 17 00:00:00 2001 From: Mike Zeller Date: Mon, 20 Nov 2023 22:38:09 -0500 Subject: [PATCH 05/18] Fix up libipcc handle stub --- ipcc/build.rs | 1 + ipcc/src/handle_stub.rs | 12 +++--------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/ipcc/build.rs b/ipcc/build.rs index 3bb051d36f..25a113394d 100644 --- a/ipcc/build.rs +++ b/ipcc/build.rs @@ -2,6 +2,7 @@ // 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/. +#[cfg(target_os = "illumos")] static OXIDE_PLATFORM: &str = "/usr/platform/oxide/lib/amd64/"; fn main() { diff --git a/ipcc/src/handle_stub.rs b/ipcc/src/handle_stub.rs index 64685d25dc..cff51aa177 100644 --- a/ipcc/src/handle_stub.rs +++ b/ipcc/src/handle_stub.rs @@ -4,13 +4,7 @@ // Copyright 2023 Oxide Computer Company -use std::{ - ffi::{c_int, CStr, CString}, - ptr, -}; - -use crate::ffi::*; -use crate::ipcc_common::*; +use crate::IpccError; pub struct IpccHandle; @@ -21,8 +15,8 @@ impl IpccHandle { pub(crate) fn key_lookup( &self, - key: u8, - buf: &mut [u8], + _key: u8, + _buf: &mut [u8], ) -> Result { panic!("ipcc unavailable on this platform") } From 279673c25f30aacb4ffc2dca2104422b7db66a3b Mon Sep 17 00:00:00 2001 From: Mike Zeller Date: Tue, 21 Nov 2023 15:32:45 +0000 Subject: [PATCH 06/18] Fix gateway.json openapi --- openapi/gateway.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi/gateway.json b/openapi/gateway.json index 9eacbe122d..5961b670ed 100644 --- a/openapi/gateway.json +++ b/openapi/gateway.json @@ -1129,7 +1129,7 @@ "/sp/{type}/{slot}/ipcc/installinator-image-id": { "put": { "summary": "Set the installinator image ID the sled should use for recovery.", - "description": "This value can be read by the host via IPCC; see the `ipcc-key-value` crate.", + "description": "This value can be read by the host via IPCC; see the `ipcc` crate.", "operationId": "sp_installinator_image_id_set", "parameters": [ { From 2e25d56f3459d7cfcbea9e0f97512ff4f09c7fbb Mon Sep 17 00:00:00 2001 From: Mike Zeller Date: Tue, 21 Nov 2023 21:48:06 +0000 Subject: [PATCH 07/18] Address andy's feedback --- ipcc/src/ffi.rs | 5 ++++- ipcc/src/handle.rs | 5 ++--- ipcc/src/lib.rs | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ipcc/src/ffi.rs b/ipcc/src/ffi.rs index a96d6986ac..1d228ee877 100644 --- a/ipcc/src/ffi.rs +++ b/ipcc/src/ffi.rs @@ -42,7 +42,10 @@ pub(crate) const LIBIPCC_ERR_KEY_VALTOOLONG: libipcc_err_t = 7; pub(crate) const LIBIPCC_ERR_KEY_ZERR: libipcc_err_t = 8; pub(crate) type libipcc_err_t = c_uint; -pub type libipcc_key_flag_t = ::std::os::raw::c_uint; +/// Maxium length of an error message retrieved by libipcc_errmsg(). +pub(crate) const LIBIPCC_ERR_LEN: usize = 1024; + +pub(crate) type libipcc_key_flag_t = ::std::os::raw::c_uint; #[link(name = "ipcc")] extern "C" { diff --git a/ipcc/src/handle.rs b/ipcc/src/handle.rs index d5f47d436d..26f9e830bb 100644 --- a/ipcc/src/handle.rs +++ b/ipcc/src/handle.rs @@ -31,8 +31,7 @@ fn ipcc_fatal_error>( let syserr = if syserr == 0 { "no system errno".to_string() } else { - let syserr = unsafe { libc::strerror(syserr) }; - unsafe { CStr::from_ptr(syserr) }.to_string_lossy().into_owned() + std::io::Error::from_raw_os_error(syserr).to_string() }; let inner = IpccErrorInner { context, @@ -56,7 +55,7 @@ fn ipcc_fatal_error>( impl IpccHandle { pub fn new() -> Result { let mut ipcc_handle: *mut libipcc_handle_t = ptr::null_mut(); - let errmsg = CString::new(vec![1; 1024]).unwrap(); + let errmsg = CString::new(vec![1; LIBIPCC_ERR_LEN]).unwrap(); let errmsg_len = errmsg.as_bytes().len(); let errmsg_ptr = errmsg.into_raw(); let mut lerr = LIBIPCC_ERR_OK; diff --git a/ipcc/src/lib.rs b/ipcc/src/lib.rs index 6a8c51adc6..d00cf71770 100644 --- a/ipcc/src/lib.rs +++ b/ipcc/src/lib.rs @@ -173,7 +173,7 @@ pub struct IpccErrorInner { pub syserr: String, } -/// These are the IPCC keys we can lookup. +/// These are the IPCC keys we can look up. /// NB: These keys match the definitions found in libipcc (RFD 316) and should /// match the values in `[ipcc::Key]` one-to-one. #[derive(Debug, Clone, Copy)] From a7aa5c66167c4103ef2bf891274a6de62d414dd7 Mon Sep 17 00:00:00 2001 From: Mike Zeller Date: Wed, 22 Nov 2023 20:07:42 +0000 Subject: [PATCH 08/18] Add some documentation --- ipcc/src/lib.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ipcc/src/lib.rs b/ipcc/src/lib.rs index d00cf71770..d3660682a5 100644 --- a/ipcc/src/lib.rs +++ b/ipcc/src/lib.rs @@ -4,8 +4,10 @@ // Copyright 2023 Oxide Computer Company -//! Utilities for key/value pairs passed from the control plane to the SP -//! (through MGS) to the host (through the host/SP uart) via IPCC. +//! An interface to libipcc (inter-processor communications channel) which +//! currently supports looking up values stored in the SP by key. These +//! values are passed from the control plane to the SP (through MGS) or +//! are maniuplated through the `ipcc` command found on Helios. use cfg_if::cfg_if; use omicron_common::update::ArtifactHash; @@ -187,16 +189,20 @@ enum IpccKey { Dtrace = 4, } +/// Interface to the inter-processor communications channel. +/// For more information see rfd 316. pub struct Ipcc { handle: IpccHandle, } impl Ipcc { + /// Creates a new `Ipcc` instance. pub fn new() -> Result { let handle = IpccHandle::new()?; Ok(Self { handle }) } + /// Returns the current `InstallinatorImageId`. pub fn installinator_image_id( &self, ) -> Result { From e50589dc0cbdce846cd18b71ffad3176e284b5bb Mon Sep 17 00:00:00 2001 From: Michael Zeller Date: Mon, 11 Dec 2023 14:51:25 -0500 Subject: [PATCH 09/18] Apply Andy's suggestion Co-authored-by: Andy Fiddaman --- ipcc/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ipcc/src/lib.rs b/ipcc/src/lib.rs index d3660682a5..e997c51230 100644 --- a/ipcc/src/lib.rs +++ b/ipcc/src/lib.rs @@ -6,8 +6,8 @@ //! An interface to libipcc (inter-processor communications channel) which //! currently supports looking up values stored in the SP by key. These -//! values are passed from the control plane to the SP (through MGS) or -//! are maniuplated through the `ipcc` command found on Helios. +//! values are variously static, passed from the control plane to the SP +//! (through MGS) or set from userland via libipcc. use cfg_if::cfg_if; use omicron_common::update::ArtifactHash; From 77bd06500ee9514a28bc915b0bd0c0a2feec1eab Mon Sep 17 00:00:00 2001 From: Mike Zeller Date: Mon, 11 Dec 2023 20:48:17 +0000 Subject: [PATCH 10/18] Addres Jordan's feedback --- ipcc/build.rs | 1 + ipcc/src/ffi.rs | 13 +++++++++++++ ipcc/src/handle.rs | 22 +++++++++++++++++++++- ipcc/src/handle_stub.rs | 2 ++ 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/ipcc/build.rs b/ipcc/build.rs index 25a113394d..a64133dac2 100644 --- a/ipcc/build.rs +++ b/ipcc/build.rs @@ -2,6 +2,7 @@ // 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/. +/// This path is where Oxide specific libraries live on helios systems. #[cfg(target_os = "illumos")] static OXIDE_PLATFORM: &str = "/usr/platform/oxide/lib/amd64/"; diff --git a/ipcc/src/ffi.rs b/ipcc/src/ffi.rs index 1d228ee877..420c1ddcde 100644 --- a/ipcc/src/ffi.rs +++ b/ipcc/src/ffi.rs @@ -17,26 +17,36 @@ pub(crate) struct libipcc_handle_t { _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, } +/// Indicates that there was no error. Used as the initialized value when +/// calling into libipcc. pub(crate) const LIBIPCC_ERR_OK: libipcc_err_t = 0; + /// Indicates that there was a memory allocation error. The system error /// contains the specific errno. pub(crate) const LIBIPCC_ERR_NO_MEM: libipcc_err_t = 1; + /// One of the function parameters does not pass validation. There will be more /// detail available via libipcc_errmsg(). pub(crate) const LIBIPCC_ERR_INVALID_PARAM: libipcc_err_t = 2; + /// An internal error occurred. There will be more detail available via /// libipcc_errmsg() and libipcc_syserr(). pub(crate) const LIBIPCC_ERR_INTERNAL: libipcc_err_t = 3; + /// The requested lookup key was not known to the SP. pub(crate) const LIBIPCC_ERR_KEY_UNKNOWN: libipcc_err_t = 4; + /// The value for the requested lookup key was too large for the /// supplied buffer. pub(crate) const LIBIPCC_ERR_KEY_BUFTOOSMALL: libipcc_err_t = 5; + /// An attempt to write to a key failed because the key is read-only. pub(crate) const LIBIPCC_ERR_KEY_READONLY: libipcc_err_t = 6; + /// An attempt to write to a key failed because the passed value is too /// long. pub(crate) const LIBIPCC_ERR_KEY_VALTOOLONG: libipcc_err_t = 7; + /// Compression or decompression failed. If appropriate, libipcc_syserr() will /// return the Z_ error from zlib. pub(crate) const LIBIPCC_ERR_KEY_ZERR: libipcc_err_t = 8; @@ -45,6 +55,9 @@ pub(crate) type libipcc_err_t = c_uint; /// Maxium length of an error message retrieved by libipcc_errmsg(). pub(crate) const LIBIPCC_ERR_LEN: usize = 1024; +/// Flags that can be passed to libipcc when looking up a key. Today this is +/// used for looking up a compressed key, however nothing in the public API of +/// this crate takes advantage of this. pub(crate) type libipcc_key_flag_t = ::std::os::raw::c_uint; #[link(name = "ipcc")] diff --git a/ipcc/src/handle.rs b/ipcc/src/handle.rs index 26f9e830bb..bf65ab03fb 100644 --- a/ipcc/src/handle.rs +++ b/ipcc/src/handle.rs @@ -43,7 +43,7 @@ fn ipcc_fatal_error>( LIBIPCC_ERR_NO_MEM => IpccError::NoMem(inner), LIBIPCC_ERR_INVALID_PARAM => IpccError::InvalidParam(inner), LIBIPCC_ERR_INTERNAL => IpccError::Internal(inner), - LIBIPCC_ERR_KEY_UNKNOWN => IpccError::Internal(inner), + LIBIPCC_ERR_KEY_UNKNOWN => IpccError::KeyUnknown(inner), LIBIPCC_ERR_KEY_BUFTOOSMALL => IpccError::KeyBufTooSmall(inner), LIBIPCC_ERR_KEY_READONLY => IpccError::KeyReadonly(inner), LIBIPCC_ERR_KEY_VALTOOLONG => IpccError::KeyValTooLong(inner), @@ -55,6 +55,8 @@ fn ipcc_fatal_error>( impl IpccHandle { pub fn new() -> Result { let mut ipcc_handle: *mut libipcc_handle_t = ptr::null_mut(); + // Safety: Unwrapped because we guarantee that the supplied bytes + // contain no 0 bytes up front. let errmsg = CString::new(vec![1; LIBIPCC_ERR_LEN]).unwrap(); let errmsg_len = errmsg.as_bytes().len(); let errmsg_ptr = errmsg.into_raw(); @@ -69,6 +71,9 @@ impl IpccHandle { errmsg_len, ) } { + // Safety: CString::from_raw retakes ownership of a CString + // transferred to C via CString::into_raw. We are calling into_raw() + // above so it is safe to turn this back into it's owned variant. let errmsg = unsafe { CString::from_raw(errmsg_ptr) }; return Err(ipcc_fatal_error( "Could not init libipcc handle", @@ -84,6 +89,21 @@ impl IpccHandle { fn fatal>(&self, context: C) -> IpccError { let lerr = unsafe { libipcc_err(self.0) }; let errmsg = unsafe { libipcc_errmsg(self.0) }; + // Safety: CStr::from_ptr is documented as safe if: + // 1. The pointer contains a valid null terminator at the end of + // the string + // 2. The pointer is valid for reads of bytes up to and including + // the null terminator + // 3. The memory referenced by the return CStr is not mutated for + // the duration of lifetime 'a + // + // (1) is true because this crate initializes space for an error message + // via CString::new which adds a terminator on our behalf. + // (2) should be guaranteed by libipcc itself since it is writing error + // messages into the CString backed buffer that we gave it. + // (3) We aren't currently mutating the memory referenced by the + // CStr, and we are creating an owned copy of the data immediately so + // that it can outlive the lifetime of the libipcc handle if needed. let errmsg = unsafe { CStr::from_ptr(errmsg) }.to_owned(); let syserr = unsafe { libipcc_syserr(self.0) }; ipcc_fatal_error(context, lerr, syserr, errmsg) diff --git a/ipcc/src/handle_stub.rs b/ipcc/src/handle_stub.rs index cff51aa177..bc4b84b7fe 100644 --- a/ipcc/src/handle_stub.rs +++ b/ipcc/src/handle_stub.rs @@ -6,6 +6,8 @@ use crate::IpccError; +/// This stub and it's implementation are used for non-illumos platforms which +/// lack libipcc. pub struct IpccHandle; impl IpccHandle { From be7931de941c4a387dbe35f30963568ef37852db Mon Sep 17 00:00:00 2001 From: Mike Zeller Date: Mon, 11 Dec 2023 23:05:08 +0000 Subject: [PATCH 11/18] Update documentation found in .cargo/config --- .cargo/config | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/.cargo/config b/.cargo/config index 3f99418434..72a9ee9ac1 100644 --- a/.cargo/config +++ b/.cargo/config @@ -7,10 +7,28 @@ [build] rustdocflags = "--document-private-items" -# On illumos, use `-znocompstrtab` to reduce link time. +# On illumos, use `-znocompstrtab` to reduce link time. We also add the Oxide +# specific platform directory to the RPATH where additional libraries can be +# found such as libipcc. # -# Note that these flags are overridden by a user's environment variable, so -# things critical to correctness probably don't belong here. +# As documented at: +# https://doc.rust-lang.org/cargo/reference/config.html#buildrustflags +# +# There are four mutually exclusive sources of extra flags. They are checked in +# order, with the first one being used: +# 1. `CARGO_ENCODED_RUSTFLAGS` environment variable. +# 2. `RUSTFLAGS` environment variable. +# 3. All matching target..rustflags and target..rustflags config +# entries joined together. +# 4. build.rustflags config value. +# +# When overriding the defaults in this config by environment variable the user +# may need to manually pass the additional options found below. +# +# Note that other runtime paths should not be added here, but should instead +# reuse the infrastructure found in the `rpaths` crate which can be found in +# this repo. Those paths are usually platform specific and will vary based on +# variety of things such as host OS. [target.x86_64-unknown-illumos] rustflags = [ "-C", "link-arg=-Wl,-znocompstrtab,-R/usr/platform/oxide/lib/amd64" From a6a4e148feafd445751045ef68dca7b4413233cd Mon Sep 17 00:00:00 2001 From: Mike Zeller Date: Mon, 11 Dec 2023 23:10:30 +0000 Subject: [PATCH 12/18] grammar --- .cargo/config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cargo/config b/.cargo/config index 72a9ee9ac1..d8f3e09e7f 100644 --- a/.cargo/config +++ b/.cargo/config @@ -27,7 +27,7 @@ rustdocflags = "--document-private-items" # # Note that other runtime paths should not be added here, but should instead # reuse the infrastructure found in the `rpaths` crate which can be found in -# this repo. Those paths are usually platform specific and will vary based on +# this repo. Those paths are usually platform specific and will vary based on a # variety of things such as host OS. [target.x86_64-unknown-illumos] rustflags = [ From ef49d98c16812c2428806d30e4531433765aded7 Mon Sep 17 00:00:00 2001 From: Mike Zeller Date: Tue, 12 Dec 2023 20:40:49 +0000 Subject: [PATCH 13/18] Enforce the actual errmsg length --- ipcc/src/handle.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ipcc/src/handle.rs b/ipcc/src/handle.rs index bf65ab03fb..91b71a6ce3 100644 --- a/ipcc/src/handle.rs +++ b/ipcc/src/handle.rs @@ -55,9 +55,11 @@ fn ipcc_fatal_error>( impl IpccHandle { pub fn new() -> Result { let mut ipcc_handle: *mut libipcc_handle_t = ptr::null_mut(); + // We subtract 1 from the length of the inital vector since CString::new + // will append a nul for us. // Safety: Unwrapped because we guarantee that the supplied bytes // contain no 0 bytes up front. - let errmsg = CString::new(vec![1; LIBIPCC_ERR_LEN]).unwrap(); + let errmsg = CString::new(vec![1; LIBIPCC_ERR_LEN - 1]).unwrap(); let errmsg_len = errmsg.as_bytes().len(); let errmsg_ptr = errmsg.into_raw(); let mut lerr = LIBIPCC_ERR_OK; From 78a9777625851fcdc74860006d9c3fc6516326f5 Mon Sep 17 00:00:00 2001 From: Mike Zeller Date: Tue, 12 Dec 2023 21:28:03 +0000 Subject: [PATCH 14/18] Address rain's feedback --- .cargo/config | 19 +++++++++++++++++++ Cargo.lock | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/.cargo/config b/.cargo/config index d8f3e09e7f..f658f146c9 100644 --- a/.cargo/config +++ b/.cargo/config @@ -11,6 +11,25 @@ rustdocflags = "--document-private-items" # specific platform directory to the RPATH where additional libraries can be # found such as libipcc. # +# Our reasoning for including `-R/usr/platform/oxide/lib/amd64` here: +# - Oxide specific features - This path contains Oxide specific libraries such +# as libipcc and will likely grow over time to include more functionality. +# - Avoid the rpaths crate - The rpaths crate was built to deal with runtime +# paths that are dynamic such as with libraries like libpq which can live in +# different locations based on OS. This path will only ever be found on +# illumos and will be tied directly to the Oxide platform. +# - Less developer burden - Having something like the ipcc crate emit +# `DEP_IPCC_LIBDIRS` means that we end up littering the repo with Cargo.toml +# and build.rs changes whenever ipcc shows up somewhere in the dependency +# tree. While initially exploring that path we ran into a significant number +# of tests failing due to not being able to find libipcc in the runtime path +# which can be confusing or surprising to someone doing work on omicron. +# +# We could also update Helios so that a symlink is created from +# /usr/platform/oxide/lib/amd64 into /usr/lib/64 but we opted to not take +# this route forward as it meant waiting for another round of updates on +# shared build machines and to buildomat itself. +# # As documented at: # https://doc.rust-lang.org/cargo/reference/config.html#buildrustflags # diff --git a/Cargo.lock b/Cargo.lock index 6143b84056..77c0dbe4df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3427,7 +3427,7 @@ dependencies = [ name = "ipcc" version = "0.1.0" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "ciborium", "libc", "omicron-common", From 9b673a70e0af06e0d986ffee705809ad05e27030 Mon Sep 17 00:00:00 2001 From: Mike Zeller Date: Wed, 27 Dec 2023 17:28:53 +0000 Subject: [PATCH 15/18] Test new buildomat image --- .github/buildomat/jobs/build-and-test-helios.sh | 2 +- .github/buildomat/jobs/ci-tools.sh | 2 +- .github/buildomat/jobs/clippy.sh | 2 +- .github/buildomat/jobs/host-image.sh | 2 +- .github/buildomat/jobs/package.sh | 2 +- .github/buildomat/jobs/tuf-repo.sh | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/buildomat/jobs/build-and-test-helios.sh b/.github/buildomat/jobs/build-and-test-helios.sh index f9722a2b92..67b4a2d4ea 100755 --- a/.github/buildomat/jobs/build-and-test-helios.sh +++ b/.github/buildomat/jobs/build-and-test-helios.sh @@ -2,7 +2,7 @@ #: #: name = "build-and-test (helios)" #: variety = "basic" -#: target = "helios-2.0" +#: target = "helios-2.0-20231220" #: rust_toolchain = "1.72.1" #: output_rules = [ #: "/var/tmp/omicron_tmp/*", diff --git a/.github/buildomat/jobs/ci-tools.sh b/.github/buildomat/jobs/ci-tools.sh index 07a63af30c..5673d1c357 100755 --- a/.github/buildomat/jobs/ci-tools.sh +++ b/.github/buildomat/jobs/ci-tools.sh @@ -2,7 +2,7 @@ #: #: name = "helios / CI tools" #: variety = "basic" -#: target = "helios-2.0" +#: target = "helios-2.0-20231220" #: rust_toolchain = "1.72.1" #: output_rules = [ #: "=/work/end-to-end-tests/*.gz", diff --git a/.github/buildomat/jobs/clippy.sh b/.github/buildomat/jobs/clippy.sh index abbcda2150..f6cbcbd23c 100755 --- a/.github/buildomat/jobs/clippy.sh +++ b/.github/buildomat/jobs/clippy.sh @@ -2,7 +2,7 @@ #: #: name = "clippy (helios)" #: variety = "basic" -#: target = "helios-2.0" +#: target = "helios-2.0-20231220" #: rust_toolchain = "1.72.1" #: output_rules = [] diff --git a/.github/buildomat/jobs/host-image.sh b/.github/buildomat/jobs/host-image.sh index 2f4d146a48..7267847681 100755 --- a/.github/buildomat/jobs/host-image.sh +++ b/.github/buildomat/jobs/host-image.sh @@ -2,7 +2,7 @@ #: #: name = "helios / build OS images" #: variety = "basic" -#: target = "helios-2.0" +#: target = "helios-2.0-20231220" #: rust_toolchain = "1.72.1" #: output_rules = [ #: "=/work/helios/upload/os-host.tar.gz", diff --git a/.github/buildomat/jobs/package.sh b/.github/buildomat/jobs/package.sh index 350ab37233..700e8a392c 100755 --- a/.github/buildomat/jobs/package.sh +++ b/.github/buildomat/jobs/package.sh @@ -2,7 +2,7 @@ #: #: name = "helios / package" #: variety = "basic" -#: target = "helios-2.0" +#: target = "helios-2.0-20231220" #: rust_toolchain = "1.72.1" #: output_rules = [ #: "=/work/version.txt", diff --git a/.github/buildomat/jobs/tuf-repo.sh b/.github/buildomat/jobs/tuf-repo.sh index 5e7a2d4a91..6dff9eba78 100644 --- a/.github/buildomat/jobs/tuf-repo.sh +++ b/.github/buildomat/jobs/tuf-repo.sh @@ -2,7 +2,7 @@ #: #: name = "helios / build TUF repo" #: variety = "basic" -#: target = "helios-2.0" +#: target = "helios-2.0-20231220" #: output_rules = [ #: "=/work/manifest*.toml", #: "=/work/repo-*.zip.part*", From 25f9b6e2106a6546a6d4b60500da7a19d7e5ca4b Mon Sep 17 00:00:00 2001 From: Mike Zeller Date: Thu, 28 Dec 2023 20:16:19 +0000 Subject: [PATCH 16/18] Make sure the oxide library runpath is passed through to tests --- .github/buildomat/build-and-test.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/buildomat/build-and-test.sh b/.github/buildomat/build-and-test.sh index 34f81bab68..30d98df934 100755 --- a/.github/buildomat/build-and-test.sh +++ b/.github/buildomat/build-and-test.sh @@ -4,6 +4,8 @@ set -o errexit set -o pipefail set -o xtrace +target_os=$1 + # NOTE: This version should be in sync with the recommended version in # .config/nextest.toml. (Maybe build an automated way to pull the recommended # version in the future.) @@ -48,6 +50,13 @@ ptime -m bash ./tools/install_builder_prerequisites.sh -y # banner build export RUSTFLAGS="-D warnings" +# When running on illumos we need to pass an additional runpath that is +# usually configured via ".cargo/config" but the `RUSTFLAGS` env variable +# takes precedence. This path contains oxide specific libraries such as +# libipcc. +if [[ $target_os == "illumos" ]]; then + RUSTFLAGS="-D warnings,-R/usr/platform/oxide/lib/amd64" +fi export RUSTDOCFLAGS="-D warnings" export TMPDIR=$TEST_TMPDIR export RUST_BACKTRACE=1 From a99a8c20e68cf1847a5cb0889ecd390f712aba4b Mon Sep 17 00:00:00 2001 From: Mike Zeller Date: Wed, 10 Jan 2024 15:28:06 +0000 Subject: [PATCH 17/18] Actually specify link args for buildomat test --- .github/buildomat/build-and-test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/buildomat/build-and-test.sh b/.github/buildomat/build-and-test.sh index 30d98df934..d08237f66d 100755 --- a/.github/buildomat/build-and-test.sh +++ b/.github/buildomat/build-and-test.sh @@ -55,7 +55,7 @@ export RUSTFLAGS="-D warnings" # takes precedence. This path contains oxide specific libraries such as # libipcc. if [[ $target_os == "illumos" ]]; then - RUSTFLAGS="-D warnings,-R/usr/platform/oxide/lib/amd64" + RUSTFLAGS="-D warnings -C link-arg=-R/usr/platform/oxide/lib/amd64" fi export RUSTDOCFLAGS="-D warnings" export TMPDIR=$TEST_TMPDIR From 861aa768f4ddac9842a9be7947505bc3d2a67f45 Mon Sep 17 00:00:00 2001 From: Mike Zeller Date: Wed, 10 Jan 2024 22:53:02 +0000 Subject: [PATCH 18/18] Move omicron back to helios-2.0 buildomat targets --- .github/buildomat/jobs/build-and-test-helios.sh | 2 +- .github/buildomat/jobs/ci-tools.sh | 2 +- .github/buildomat/jobs/clippy.sh | 2 +- .github/buildomat/jobs/host-image.sh | 2 +- .github/buildomat/jobs/package.sh | 2 +- .github/buildomat/jobs/tuf-repo.sh | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/buildomat/jobs/build-and-test-helios.sh b/.github/buildomat/jobs/build-and-test-helios.sh index 67b4a2d4ea..f9722a2b92 100755 --- a/.github/buildomat/jobs/build-and-test-helios.sh +++ b/.github/buildomat/jobs/build-and-test-helios.sh @@ -2,7 +2,7 @@ #: #: name = "build-and-test (helios)" #: variety = "basic" -#: target = "helios-2.0-20231220" +#: target = "helios-2.0" #: rust_toolchain = "1.72.1" #: output_rules = [ #: "/var/tmp/omicron_tmp/*", diff --git a/.github/buildomat/jobs/ci-tools.sh b/.github/buildomat/jobs/ci-tools.sh index 5673d1c357..07a63af30c 100755 --- a/.github/buildomat/jobs/ci-tools.sh +++ b/.github/buildomat/jobs/ci-tools.sh @@ -2,7 +2,7 @@ #: #: name = "helios / CI tools" #: variety = "basic" -#: target = "helios-2.0-20231220" +#: target = "helios-2.0" #: rust_toolchain = "1.72.1" #: output_rules = [ #: "=/work/end-to-end-tests/*.gz", diff --git a/.github/buildomat/jobs/clippy.sh b/.github/buildomat/jobs/clippy.sh index f6cbcbd23c..abbcda2150 100755 --- a/.github/buildomat/jobs/clippy.sh +++ b/.github/buildomat/jobs/clippy.sh @@ -2,7 +2,7 @@ #: #: name = "clippy (helios)" #: variety = "basic" -#: target = "helios-2.0-20231220" +#: target = "helios-2.0" #: rust_toolchain = "1.72.1" #: output_rules = [] diff --git a/.github/buildomat/jobs/host-image.sh b/.github/buildomat/jobs/host-image.sh index 7267847681..2f4d146a48 100755 --- a/.github/buildomat/jobs/host-image.sh +++ b/.github/buildomat/jobs/host-image.sh @@ -2,7 +2,7 @@ #: #: name = "helios / build OS images" #: variety = "basic" -#: target = "helios-2.0-20231220" +#: target = "helios-2.0" #: rust_toolchain = "1.72.1" #: output_rules = [ #: "=/work/helios/upload/os-host.tar.gz", diff --git a/.github/buildomat/jobs/package.sh b/.github/buildomat/jobs/package.sh index 700e8a392c..350ab37233 100755 --- a/.github/buildomat/jobs/package.sh +++ b/.github/buildomat/jobs/package.sh @@ -2,7 +2,7 @@ #: #: name = "helios / package" #: variety = "basic" -#: target = "helios-2.0-20231220" +#: target = "helios-2.0" #: rust_toolchain = "1.72.1" #: output_rules = [ #: "=/work/version.txt", diff --git a/.github/buildomat/jobs/tuf-repo.sh b/.github/buildomat/jobs/tuf-repo.sh index 6dff9eba78..5e7a2d4a91 100644 --- a/.github/buildomat/jobs/tuf-repo.sh +++ b/.github/buildomat/jobs/tuf-repo.sh @@ -2,7 +2,7 @@ #: #: name = "helios / build TUF repo" #: variety = "basic" -#: target = "helios-2.0-20231220" +#: target = "helios-2.0" #: output_rules = [ #: "=/work/manifest*.toml", #: "=/work/repo-*.zip.part*",