Skip to content

Commit

Permalink
[sled-diagnostics] Add pfiles output (#7258)
Browse files Browse the repository at this point in the history
This PR adds support for gathering `pfiles` output for all Oxide
processes on a sled.

This is on top of:
- #7228 
- #7194
  • Loading branch information
papertigers authored Jan 8, 2025
1 parent 322e15b commit f460a3c
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 0 deletions.
27 changes: 27 additions & 0 deletions openapi/sled-agent.json
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,33 @@
}
}
},
"/support/pfiles-info": {
"get": {
"operationId": "support_pfiles_info",
"responses": {
"200": {
"description": "successful operation",
"content": {
"application/json": {
"schema": {
"title": "Array_of_SledDiagnosticsQueryOutput",
"type": "array",
"items": {
"$ref": "#/components/schemas/SledDiagnosticsQueryOutput"
}
}
}
}
},
"4XX": {
"$ref": "#/components/responses/Error"
},
"5XX": {
"$ref": "#/components/responses/Error"
}
}
}
},
"/support/pstack-info": {
"get": {
"operationId": "support_pstack_info",
Expand Down
8 changes: 8 additions & 0 deletions sled-agent/api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,14 @@ pub trait SledAgentApi {
async fn support_pstack_info(
request_context: RequestContext<Self::Context>,
) -> Result<HttpResponseOk<Vec<SledDiagnosticsQueryOutput>>, HttpError>;

#[endpoint {
method = GET,
path = "/support/pfiles-info",
}]
async fn support_pfiles_info(
request_context: RequestContext<Self::Context>,
) -> Result<HttpResponseOk<Vec<SledDiagnosticsQueryOutput>>, HttpError>;
}

#[derive(Clone, Debug, Deserialize, JsonSchema, Serialize)]
Expand Down
14 changes: 14 additions & 0 deletions sled-agent/src/http_entrypoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1027,4 +1027,18 @@ impl SledAgentApi for SledAgentImpl {
.collect::<Vec<_>>(),
))
}

async fn support_pfiles_info(
request_context: RequestContext<Self::Context>,
) -> Result<HttpResponseOk<Vec<SledDiagnosticsQueryOutput>>, HttpError>
{
let sa = request_context.context();
Ok(HttpResponseOk(
sa.support_pfiles_info()
.await
.into_iter()
.map(|cmd| cmd.get_output())
.collect::<Vec<_>>(),
))
}
}
7 changes: 7 additions & 0 deletions sled-agent/src/sim/http_entrypoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,13 @@ impl SledAgentApi for SledAgentSimImpl {
{
method_unimplemented()
}

async fn support_pfiles_info(
_request_context: RequestContext<Self::Context>,
) -> Result<HttpResponseOk<Vec<SledDiagnosticsQueryOutput>>, HttpError>
{
method_unimplemented()
}
}

fn method_unimplemented<T>() -> Result<T, HttpError> {
Expand Down
6 changes: 6 additions & 0 deletions sled-agent/src/sled_agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1400,6 +1400,12 @@ impl SledAgent {
) -> Vec<Result<SledDiagnosticsCmdOutput, SledDiagnosticsCmdError>> {
sled_diagnostics::pstack_oxide_processes(&self.log).await
}

pub(crate) async fn support_pfiles_info(
&self,
) -> Vec<Result<SledDiagnosticsCmdOutput, SledDiagnosticsCmdError>> {
sled_diagnostics::pfiles_oxide_processes(&self.log).await
}
}

#[derive(From, thiserror::Error, Debug)]
Expand Down
21 changes: 21 additions & 0 deletions sled-diagnostics/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,24 @@ pub async fn pstack_oxide_processes(
.collect::<Vec<Result<_, _>>>()
.await
}

pub async fn pfiles_oxide_processes(
log: &Logger,
) -> Vec<Result<SledDiagnosticsCmdOutput, SledDiagnosticsCmdError>> {
// In a diagnostics context we care about looping over every pid we find,
// but on failure we should just return a single error in a vec that
// represents the entire failed operation.
let pids = match contract::find_oxide_pids(log) {
Ok(pids) => pids,
Err(e) => return vec![Err(e.into())],
};

pids.iter()
.map(|pid| pfiles_process(*pid))
.map(|c| async move {
execute_command_with_timeout(c, DEFAULT_TIMEOUT).await
})
.collect::<FuturesUnordered<_>>()
.collect::<Vec<Result<_, _>>>()
.await
}
7 changes: 7 additions & 0 deletions sled-diagnostics/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use crate::contract_stub::ContractError;
const DLADM: &str = "/usr/sbin/dladm";
const IPADM: &str = "/usr/sbin/ipadm";
const PFEXEC: &str = "/usr/bin/pfexec";
const PFILES: &str = "/usr/bin/pfiles";
const PSTACK: &str = "/usr/bin/pstack";
const PARGS: &str = "/usr/bin/pargs";
const ZONEADM: &str = "/usr/sbin/zoneadm";
Expand Down Expand Up @@ -247,6 +248,12 @@ pub fn pstack_process(pid: i32) -> Command {
cmd
}

pub fn pfiles_process(pid: i32) -> Command {
let mut cmd = std::process::Command::new(PFEXEC);
cmd.env_clear().arg(PFILES).arg(pid.to_string());
cmd
}

#[cfg(test)]
mod test {
use super::*;
Expand Down

0 comments on commit f460a3c

Please sign in to comment.