Change ProcessManager interfaces to return ProcessManagerError.

Propagate the ProcessManagerError enum through the
PackageManagementInterface and ProcessControlInterface so the client
has more information about why a request failed.

Change-Id: Ic2d8fcf1401edd6faff85fe821443f720d0b00c4
GitOrigin-RevId: 91d668fc56a352776803392d89aacc034cee1f1e
This commit is contained in:
Sam Leffler
2021-08-04 18:00:57 -07:00
parent cb99661cd0
commit 69eefbd5c9
7 changed files with 104 additions and 53 deletions

View File

@@ -7,7 +7,7 @@ use log::info;
use kata_io as io;
use kata_line_reader::LineReader;
use kata_proc_common::{Bundle, RawBundleIdData};
use kata_proc_common::{Bundle, ProcessManagerError, RawBundleIdData};
/// Error type indicating why a command line is not runnable.
enum CommandError {
@@ -175,18 +175,18 @@ fn clear_command(output: &mut dyn io::Write) -> Result<(), CommandError> {
fn bundles_command(output: &mut dyn io::Write) -> Result<(), CommandError> {
extern "C" {
fn proc_ctrl_get_running_bundles(c_raw_data: *mut u8) -> bool;
fn proc_ctrl_get_running_bundles(c_raw_data: *mut u8) -> ProcessManagerError;
}
let mut raw_data = RawBundleIdData::new();
if unsafe { proc_ctrl_get_running_bundles(raw_data.as_mut_ptr()) } {
for str_bundle_id in raw_data.iter() {
writeln!(output, "{}", str_bundle_id)?;
match unsafe { proc_ctrl_get_running_bundles(raw_data.as_mut_ptr()) } {
ProcessManagerError::Success => {
for str_bundle_id in raw_data.iter() {
writeln!(output, "{}", str_bundle_id)?;
}
}
status => {
writeln!(output, "get_running_bundles failed: {:?}", status)?;
}
} else {
writeln!(
output,
"ProcessControlInterface::get_running_bundles failed"
)?;
}
Ok(())
}
@@ -196,16 +196,22 @@ fn install_command(
output: &mut dyn io::Write,
) -> Result<(), CommandError> {
extern "C" {
fn pkg_mgmt_install(c_bundle_id: *const cstr_core::c_char, c_bundle: *const u8) -> bool;
fn pkg_mgmt_install(
c_bundle_id: *const cstr_core::c_char,
c_bundle: *const u8,
) -> ProcessManagerError;
}
if let Some(bundle_id) = args.nth(0) {
// TODO(sleffler): supply a real bundle (e.g. from serial)
let bundle = Bundle::new();
let cstr = CString::new(bundle_id).unwrap();
if unsafe { pkg_mgmt_install(cstr.as_ptr(), bundle.as_ptr()) } {
writeln!(output, "Bundle \"{}\" installed.", bundle_id)?;
} else {
writeln!(output, "PackageManagementInterface::install failed")?;
match unsafe { pkg_mgmt_install(cstr.as_ptr(), bundle.as_ptr()) } {
ProcessManagerError::Success => {
writeln!(output, "Bundle \"{}\" installed.", bundle_id)?;
}
status => {
writeln!(output, "install failed: {:?}", status)?;
}
}
Ok(())
} else {
@@ -218,14 +224,17 @@ fn uninstall_command(
output: &mut dyn io::Write,
) -> Result<(), CommandError> {
extern "C" {
fn pkg_mgmt_uninstall(c_bundle_id: *const cstr_core::c_char) -> bool;
fn pkg_mgmt_uninstall(c_bundle_id: *const cstr_core::c_char) -> ProcessManagerError;
}
if let Some(bundle_id) = args.nth(0) {
let cstr = CString::new(bundle_id).unwrap();
if unsafe { pkg_mgmt_uninstall(cstr.as_ptr()) } {
writeln!(output, "Bundle \"{}\" uninstalled.", bundle_id)?;
} else {
writeln!(output, "PackageManagementInterface::uninstall failed")?;
match unsafe { pkg_mgmt_uninstall(cstr.as_ptr()) } {
ProcessManagerError::Success => {
writeln!(output, "Bundle \"{}\" uninstalled.", bundle_id)?;
}
status => {
writeln!(output, "uninstall failed: {:?}", status)?;
}
}
Ok(())
} else {
@@ -238,14 +247,17 @@ fn start_command(
output: &mut dyn io::Write,
) -> Result<(), CommandError> {
extern "C" {
fn proc_ctrl_start(c_bundle_id: *const cstr_core::c_char) -> bool;
fn proc_ctrl_start(c_bundle_id: *const cstr_core::c_char) -> ProcessManagerError;
}
if let Some(bundle_id) = args.nth(0) {
let cstr = CString::new(bundle_id).unwrap();
if unsafe { proc_ctrl_start(cstr.as_ptr()) } {
writeln!(output, "Bundle \"{}\" started.", bundle_id)?;
} else {
writeln!(output, "ProcessControlInterface::start failed")?;
match unsafe { proc_ctrl_start(cstr.as_ptr()) } {
ProcessManagerError::Success => {
writeln!(output, "Bundle \"{}\" started.", bundle_id)?;
}
status => {
writeln!(output, "start failed: {:?}", status)?;
}
}
Ok(())
} else {
@@ -258,14 +270,17 @@ fn stop_command(
output: &mut dyn io::Write,
) -> Result<(), CommandError> {
extern "C" {
fn proc_ctrl_stop(c_bundle_id: *const cstr_core::c_char) -> bool;
fn proc_ctrl_stop(c_bundle_id: *const cstr_core::c_char) -> ProcessManagerError;
}
if let Some(bundle_id) = args.nth(0) {
let cstr = CString::new(bundle_id).unwrap();
if unsafe { proc_ctrl_stop(cstr.as_ptr()) } {
writeln!(output, "Bundle \"{}\" stopped.", bundle_id)?;
} else {
writeln!(output, "ProcessControlInterface::stop failed")?;
match unsafe { proc_ctrl_stop(cstr.as_ptr()) } {
ProcessManagerError::Success => {
writeln!(output, "Bundle \"{}\" stopped.", bundle_id)?;
}
status => {
writeln!(output, "stop failed: {:?}", status)?;
}
}
Ok(())
} else {

View File

@@ -4,4 +4,4 @@ autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't mod
no_includes = true
[export]
include = ["Bundle", "RawBundleIdData"]
include = ["Bundle", "RawBundleIdData", "ProcessManagerError"]

View File

@@ -189,6 +189,7 @@ impl Bundle {
#[repr(C)]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ProcessManagerError {
Success = 0,
BundleNotFound,
BundleFound,
NoSpace,
@@ -197,6 +198,8 @@ pub enum ProcessManagerError {
UninstallFailed,
StartFailed,
StopFailed,
BundleIdInvalid,
BundleDataInvalid,
}
// Interface to underlying facilities (StorageManager, seL4); also

View File

@@ -45,48 +45,63 @@ pub extern "C" fn run() {
// PackageManagerInterface glue stubs.
#[no_mangle]
pub extern "C" fn pkg_mgmt_install(bundle_id: *const cstr_core::c_char, bundle: Bundle) -> bool {
pub extern "C" fn pkg_mgmt_install(
bundle_id: *const cstr_core::c_char,
bundle: Bundle,
) -> ProcessManagerError {
unsafe {
match CStr::from_ptr(bundle_id).to_str() {
Ok(str) => KATA_PROC.install(str, &bundle).is_ok(),
Err(_) => false,
Ok(str) => match KATA_PROC.install(str, &bundle) {
Ok(_) => ProcessManagerError::Success,
Err(e) => e,
},
Err(_) => ProcessManagerError::BundleIdInvalid,
}
}
}
#[no_mangle]
pub extern "C" fn pkg_mgmt_uninstall(bundle_id: *const cstr_core::c_char) -> bool {
pub extern "C" fn pkg_mgmt_uninstall(bundle_id: *const cstr_core::c_char) -> ProcessManagerError {
unsafe {
match CStr::from_ptr(bundle_id).to_str() {
Ok(str) => KATA_PROC.uninstall(str).is_ok(),
Err(_) => false,
Ok(str) => match KATA_PROC.uninstall(str) {
Ok(_) => ProcessManagerError::Success,
Err(e) => e,
},
Err(_) => ProcessManagerError::BundleIdInvalid,
}
}
}
// ProcessControlInterface glue stubs.
#[no_mangle]
pub extern "C" fn proc_ctrl_start(bundle_id: *const cstr_core::c_char) -> bool {
pub extern "C" fn proc_ctrl_start(bundle_id: *const cstr_core::c_char) -> ProcessManagerError {
unsafe {
match CStr::from_ptr(bundle_id).to_str() {
Ok(str) => KATA_PROC.start(str).is_ok(),
Err(_) => false,
Ok(str) => match KATA_PROC.start(str) {
Ok(_) => ProcessManagerError::Success,
Err(e) => e,
},
Err(_) => ProcessManagerError::BundleIdInvalid,
}
}
}
#[no_mangle]
pub extern "C" fn proc_ctrl_stop(bundle_id: *const cstr_core::c_char) -> bool {
pub extern "C" fn proc_ctrl_stop(bundle_id: *const cstr_core::c_char) -> ProcessManagerError {
unsafe {
match CStr::from_ptr(bundle_id).to_str() {
Ok(str) => KATA_PROC.stop(str).is_ok(),
Err(_) => false,
Ok(str) => match KATA_PROC.stop(str) {
Ok(_) => ProcessManagerError::Success,
Err(e) => e,
},
Err(_) => ProcessManagerError::BundleIdInvalid,
}
}
}
#[no_mangle]
pub extern "C" fn proc_ctrl_get_running_bundles(c_raw_data: *mut u8) -> bool {
pub extern "C" fn proc_ctrl_get_running_bundles(c_raw_data: *mut u8) -> ProcessManagerError {
unsafe {
match KATA_PROC.get_running_bundles() {
Ok(bundles) => {
@@ -94,11 +109,16 @@ pub extern "C" fn proc_ctrl_get_running_bundles(c_raw_data: *mut u8) -> bool {
// of <length><value> pairs. If we overflow the buffer, nothing
// is returned (should signal overflow somehow).
// TODO(sleffler): pass buffer size instead of assuming?
RawBundleIdData::from_raw(&mut *(c_raw_data as *mut [u8; RAW_BUNDLE_ID_DATA_SIZE]))
.pack_bundles(&bundles)
.is_ok()
match RawBundleIdData::from_raw(
&mut *(c_raw_data as *mut [u8; RAW_BUNDLE_ID_DATA_SIZE]),
)
.pack_bundles(&bundles)
{
Ok(_) => ProcessManagerError::Success,
Err(_) => ProcessManagerError::BundleDataInvalid,
}
}
Err(_) => false,
Err(e) => e,
}
}
}

View File

@@ -1,6 +1,6 @@
procedure PackageManagementInterface {
include <ProcessManagerBindings.h>;
bool install(in string bundleId, in Bundle bundle);
bool uninstall(in string bundleId);
ProcessManagerError install(in string bundleId, in Bundle bundle);
ProcessManagerError uninstall(in string bundleId);
};

View File

@@ -1,7 +1,7 @@
procedure ProcessControlInterface {
include <ProcessManagerBindings.h>;
bool start(in string bundleId);
bool stop(in string bundleId);
bool get_running_bundles(out RawBundleIdData raw_data);
ProcessManagerError start(in string bundleId);
ProcessManagerError stop(in string bundleId);
ProcessManagerError get_running_bundles(out RawBundleIdData raw_data);
};

View File

@@ -9,6 +9,19 @@
#define RAW_BUNDLE_ID_DATA_SIZE 100
typedef enum ProcessManagerError {
Success = 0,
BundleNotFound,
BundleFound,
NoSpace,
InstallFailed,
UninstallFailed,
StartFailed,
StopFailed,
BundleIdInvalid,
BundleDataInvalid,
} ProcessManagerError;
typedef struct Bundle {
uint8_t data[128];
} Bundle;