vmm: Replace Debug with Display rendering in HTTP error message

Bumping anyhow crate from 1.0.75 to 1.0.79 will cause seccomp
failures through integration tests. Newly added backtrace support
relies on readlink and many other syscalls.

Issue noticed with test_api_http_pause_resume test, where second time
of VM PAUSE or VM RESUME prints error and causes panic.
Noticed that panic message in a thread which is not allowed to write
output triggered the issue.

So implementing Display trait for HttpError and ApiError enums to avoid
adding many syscalls to seccomp filter section.

Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@intel.com>
This commit is contained in:
Ravi kumar Veeramally 2024-01-22 23:09:40 +02:00 committed by Rob Bradford
parent 9cb996db09
commit 895dc12a74
3 changed files with 62 additions and 3 deletions

View File

@ -41,8 +41,8 @@ pub struct DBusApi {
api_sender: futures::lock::Mutex<Sender<ApiRequest>>,
}
fn api_error(error: impl std::fmt::Debug) -> fdo::Error {
fdo::Error::Failed(format!("{error:?}"))
fn api_error(error: impl std::fmt::Debug + std::fmt::Display) -> fdo::Error {
fdo::Error::Failed(format!("{error}"))
}
// This method is intended to ensure that the DBusApi thread has enough time to

View File

@ -14,12 +14,14 @@ use crate::api::{
};
use crate::seccomp_filters::{get_seccomp_filter, Thread};
use crate::{Error as VmmError, Result};
use core::fmt;
use hypervisor::HypervisorType;
use micro_http::{Body, HttpServer, MediaType, Method, Request, Response, StatusCode, Version};
use once_cell::sync::Lazy;
use seccompiler::{apply_filter, SeccompAction};
use serde_json::Error as SerdeError;
use std::collections::BTreeMap;
use std::fmt::Display;
use std::fs::File;
use std::os::unix::io::{IntoRawFd, RawFd};
use std::os::unix::net::UnixListener;
@ -50,6 +52,19 @@ pub enum HttpError {
ApiError(ApiError),
}
impl Display for HttpError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::HttpError::*;
match self {
BadRequest => write!(f, "Bad Request"),
NotFound => write!(f, "Not Found"),
InternalServerError => write!(f, "Internal Server Error"),
SerdeJsonDeserialize(serde_error) => write!(f, "{}", serde_error),
ApiError(api_error) => write!(f, "{}", api_error),
}
}
}
impl From<serde_json::Error> for HttpError {
fn from(e: serde_json::Error) -> Self {
HttpError::SerdeJsonDeserialize(e)
@ -60,7 +75,7 @@ const HTTP_ROOT: &str = "/api/v1";
pub fn error_response(error: HttpError, status: StatusCode) -> Response {
let mut response = Response::new(Version::Http11, status);
response.set_body(Body::new(format!("{error:?}")));
response.set_body(Body::new(format!("{error}")));
response
}

View File

@ -45,8 +45,10 @@ use crate::config::{
use crate::device_tree::DeviceTree;
use crate::vm::{Error as VmError, VmState};
use crate::Error as VmmError;
use core::fmt;
use micro_http::Body;
use serde::{Deserialize, Serialize};
use std::fmt::Display;
use std::io;
use std::sync::mpsc::{channel, RecvError, SendError, Sender};
use std::sync::{Arc, Mutex};
@ -160,6 +162,48 @@ pub enum ApiError {
}
pub type ApiResult<T> = Result<T, ApiError>;
impl Display for ApiError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::ApiError::*;
match self {
EventFdWrite(serde_error) => write!(f, "{}", serde_error),
RequestSend(send_error) => write!(f, "{}", send_error),
ResponsePayloadType => write!(f, "Wrong response payload type"),
ResponseRecv(recv_error) => write!(f, "{}", recv_error),
VmBoot(vm_error) => write!(f, "{}", vm_error),
VmCreate(vm_error) => write!(f, "{}", vm_error),
VmDelete(vm_error) => write!(f, "{}", vm_error),
VmInfo(vm_error) => write!(f, "{}", vm_error),
VmPause(vm_error) => write!(f, "{}", vm_error),
VmResume(vm_error) => write!(f, "{}", vm_error),
VmNotBooted => write!(f, "VM is not booted"),
VmNotCreated => write!(f, "VM is not created"),
VmShutdown(vm_error) => write!(f, "{}", vm_error),
VmReboot(vm_error) => write!(f, "{}", vm_error),
VmSnapshot(vm_error) => write!(f, "{}", vm_error),
VmRestore(vm_error) => write!(f, "{}", vm_error),
VmCoredump(vm_error) => write!(f, "{}", vm_error),
VmmShutdown(vm_error) => write!(f, "{}", vm_error),
VmResize(vm_error) => write!(f, "{}", vm_error),
VmResizeZone(vm_error) => write!(f, "{}", vm_error),
VmAddDevice(vm_error) => write!(f, "{}", vm_error),
VmAddUserDevice(vm_error) => write!(f, "{}", vm_error),
VmRemoveDevice(vm_error) => write!(f, "{}", vm_error),
CreateSeccompFilter(seccomp_error) => write!(f, "{}", seccomp_error),
ApplySeccompFilter(seccomp_error) => write!(f, "{}", seccomp_error),
VmAddDisk(vm_error) => write!(f, "{}", vm_error),
VmAddFs(vm_error) => write!(f, "{}", vm_error),
VmAddPmem(vm_error) => write!(f, "{}", vm_error),
VmAddNet(vm_error) => write!(f, "{}", vm_error),
VmAddVdpa(vm_error) => write!(f, "{}", vm_error),
VmAddVsock(vm_error) => write!(f, "{}", vm_error),
VmReceiveMigration(migratable_error) => write!(f, "{}", migratable_error),
VmSendMigration(migratable_error) => write!(f, "{}", migratable_error),
VmPowerButton(vm_error) => write!(f, "{}", vm_error),
}
}
}
#[derive(Clone, Deserialize, Serialize)]
pub struct VmInfoResponse {
pub config: Arc<Mutex<VmConfig>>,