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;