#[derive(Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct Diagnostics
{
pub file_system_layout: FileSystemLayout,
pub defaults: DiagnosticUnobtainableResult<DefaultHugePageSizes>,
pub users_and_groups: UsersAndGroupsDiagnostics,
pub current_thread: CurrentThreadDiagnostic,
pub threads: DiagnosticUnobtainableResult<HashMap<ThreadIdentifier, ThreadDiagnostic>>,
pub swap: SwapDiagnostics,
pub scheduling: SchedulingDiagnostics,
pub current_process_diagnostics: CurrentProcessDiagnostics,
pub process_diagnostics: ProcessDiagnostics,
pub primary_pci_buses: DiagnosticUnobtainableResult<HashMap<PrimaryPciBusAddress, DiagnosticUnobtainableResult<PciBusDetails>>>,
pub pci_devices: DiagnosticUnobtainableResult<HashMap<PciDeviceAddress, PciDeviceDiagnostics>>,
pub receive_flow_steering_flow_count: DiagnosticUnobtainableResult<ReceiveFlowSteeringFlowCount>,
pub network_devices: DiagnosticUnobtainableResult<NetworkDeviceDiagnostics>,
pub internet_protocol_version_4_addresses: DiagnosticUnobtainableResult<InternetProtocolVersion4AddressesDiagnostic>,
pub internet_protocol_version_6_addresses: DiagnosticUnobtainableResult<InternetProtocolVersion6AddressesDiagnostic>,
pub environment: EnvironmentDiagnostic,
pub linux_kernel: LinuxKernelDiagnostic,
pub interrupt_requests: InterruptRequestDiagnostics,
pub inode: DiagnosticUnobtainableResult<InodeDiagnostics>,
pub extended_berkeley_packet_filter: ExtendedBerkeleyPacketFilterDiagnostics,
pub express_data_path_diagnostics: DiagnosticUnobtainableResult<Vec<GetExpressDataPathDiagnosticsMessageData>>,
pub cgroup_version2: Option<RootCgroupVersion2Diagnostics>,
pub file_systems: FileSystemsDiagnostics,
pub file_handle: FileHandleDiagnostics,
pub memory: MemoryDiagnostics,
pub hyper_threads: HyperThreadsDiagnostics,
#[cfg(target_arch = "x86_64")] pub cpu_information: CpuInformationDiagnostics,
pub proc_sys: BTreeMap<PathBuf, ProcSysFileDiagnostic>,
}
impl Diagnostics
{
pub fn gather(file_system_layout: &FileSystemLayout) -> DiagnosticUnobtainableResult<Self>
{
catch_unwind(AssertUnwindSafe(||
{
let process_identifier = ProcessIdentifierChoice::Current;
let (sys_path, proc_path, _dev_path, etc_path) = file_system_layout.paths();
let defaults = file_system_layout.defaults().map_err(DiagnosticUnobtainable::from);
let file_systems = FileSystemsDiagnostics::gather(proc_path, process_identifier);
let supported_huge_page_sizes = match defaults
{
Err(_) => Cow::Owned(BTreeSet::new()),
Ok(ref defaults) => Cow::Borrowed(defaults.supported_huge_page_sizes())
};
let process_diagnostics = ProcessDiagnostics::gather(sys_path, proc_path, process_identifier);
let process_group_identifier = process_diagnostics.process_group_identifier.as_ref().map(|process_group_identifier| ProcessGroupIdentifierChoice::Other(*process_group_identifier)).unwrap_or(ProcessGroupIdentifierChoice::Current);
Self
{
file_system_layout: file_system_layout.clone(),
users_and_groups: UsersAndGroupsDiagnostics::gather(proc_path, etc_path, process_identifier),
current_thread: CurrentThreadDiagnostic::gather(),
threads: match ThreadIdentifier::for_process(proc_path, process_identifier)
{
Err(error) => Err(DiagnosticUnobtainable::from(error)),
Ok(thread_identifiers) =>
{
let mut thread_diagnostics = HashMap::new();
for thread_identifier in thread_identifiers
{
thread_diagnostics.insert(thread_identifier, ThreadDiagnostic::gather(proc_path, process_identifier, thread_identifier));
}
Ok(thread_diagnostics)
}
},
swap: SwapDiagnostics::gather(proc_path),
scheduling: SchedulingDiagnostics::gather(sys_path, proc_path, process_group_identifier, process_identifier),
current_process_diagnostics: CurrentProcessDiagnostics::gather(),
process_diagnostics,
primary_pci_buses:
{
match PciBusAddress::primary(sys_path)
{
Err(error) => Err(DiagnosticUnobtainable::from(error)),
Ok(primary_pci_buses) =>
{
let mut details = HashMap::with_capacity(primary_pci_buses.len());
for primary_pci_bus in primary_pci_buses
{
let bus = match primary_pci_bus.bus(sys_path)
{
Err(error) => Err(DiagnosticUnobtainable::from(error)),
Ok(bus) => bus.details().map_err(DiagnosticUnobtainable::from),
};
details.insert(primary_pci_bus, bus);
}
Ok(details)
}
}
},
pci_devices: match PciDeviceAddress::all(sys_path)
{
Err(error) => Err(DiagnosticUnobtainable::from(error)),
Ok(pci_device_addresses) =>
{
let mut pci_devices = HashMap::new();
for pci_device_address in pci_device_addresses
{
pci_devices.insert(pci_device_address, PciDeviceDiagnostics::gather(sys_path, pci_device_address));
}
Ok(pci_devices)
}
},
receive_flow_steering_flow_count: ReceiveFlowSteeringFlowCount::global_maximum(proc_path).map_err(DiagnosticUnobtainable::from),
network_devices: NetworkDeviceDiagnostics::gather(sys_path),
internet_protocol_version_4_addresses: InternetProtocolVersion4AddressesDiagnostic::gather(),
internet_protocol_version_6_addresses: InternetProtocolVersion6AddressesDiagnostic::gather(),
environment: EnvironmentDiagnostic::gather(),
linux_kernel: LinuxKernelDiagnostic::gather(sys_path, proc_path),
interrupt_requests: InterruptRequestDiagnostics::gather(sys_path, proc_path),
inode: InodeDiagnostics::gather(proc_path),
extended_berkeley_packet_filter: ExtendedBerkeleyPacketFilterDiagnostics::gather(proc_path, &file_systems),
express_data_path_diagnostics: Self::express_data_path_diagnostics(),
cgroup_version2: RootCgroupVersion2Diagnostics::gather(&file_systems, &supported_huge_page_sizes),
file_handle: FileHandleDiagnostics::gather(proc_path),
memory: MemoryDiagnostics::gather(sys_path, proc_path, &supported_huge_page_sizes),
hyper_threads: HyperThreadsDiagnostics::gather(sys_path, proc_path),
#[cfg(target_arch = "x86_64")] cpu_information: CpuInformationDiagnostics::gather(),
proc_sys: ProcSysFileDiagnostic::gather(proc_path),
defaults,
file_systems,
}
})).map_err(|_| DiagnosticUnobtainable(format!("Panicked")))
}
#[inline(always)]
fn express_data_path_diagnostics() -> DiagnosticUnobtainableResult<Vec<GetExpressDataPathDiagnosticsMessageData>>
{
let mut netlink_socket_file_descriptor = NetlinkSocketFileDescriptor::open().map_err(DiagnosticUnobtainable::from)?;
RouteNetlinkProtocol::get_express_data_path_diagnostics(&mut netlink_socket_file_descriptor).map_err(DiagnosticUnobtainable)
}
}