perf_event_data/records/
namespaces.rs

1use std::borrow::Cow;
2
3use perf_event_open_sys::bindings;
4
5use crate::prelude::*;
6
7/// NAMESPACES records include namespace information of a process.
8///
9/// This struct corresponds to `PERF_RECORD_NAMESPACES`. See the [manpage] for
10/// more documentation.
11///
12/// [manpage]: http://man7.org/linux/man-pages/man2/perf_event_open.2.html
13#[derive(Clone, Debug)]
14pub struct Namespaces<'a> {
15    /// Process ID.
16    pub pid: u32,
17
18    /// Thread ID.
19    pub tid: u32,
20
21    /// Entries for various namespaces.
22    ///
23    /// Specific namespaces have fixed indices within this array. Accessors
24    /// have been provided for some of these. See the [manpage] for the full
25    /// documentation.
26    ///
27    /// [manpage]: http://man7.org/linux/man-pages/man2/perf_event_open.2.html
28    pub namespaces: Cow<'a, [NamespaceEntry]>,
29}
30
31/// An individual namespace entry.
32#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
33#[repr(C)]
34pub struct NamespaceEntry {
35    /// The device ID.
36    pub dev: u64,
37
38    /// The inode number.
39    pub inode: u64,
40}
41
42impl<'a> Namespaces<'a> {
43    /// Network namepsace
44    pub fn network(&self) -> Option<&NamespaceEntry> {
45        self.namespaces.get(bindings::NET_NS_INDEX as usize)
46    }
47
48    /// UTS namespace.
49    pub fn uts(&self) -> Option<&NamespaceEntry> {
50        self.namespaces.get(bindings::USER_NS_INDEX as usize)
51    }
52
53    /// IPC namespace.
54    pub fn ipc(&self) -> Option<&NamespaceEntry> {
55        self.namespaces.get(bindings::IPC_NS_INDEX as usize)
56    }
57
58    /// PID namespace.
59    pub fn pid(&self) -> Option<&NamespaceEntry> {
60        self.namespaces.get(bindings::PID_NS_INDEX as usize)
61    }
62
63    /// User namespace.
64    pub fn user(&self) -> Option<&NamespaceEntry> {
65        self.namespaces.get(bindings::USER_NS_INDEX as usize)
66    }
67
68    /// Cgroup namespace.
69    pub fn cgroup(&self) -> Option<&NamespaceEntry> {
70        self.namespaces.get(bindings::CGROUP_NS_INDEX as usize)
71    }
72}
73
74impl<'p> Parse<'p> for NamespaceEntry {
75    fn parse<B, E>(p: &mut Parser<B, E>) -> ParseResult<Self>
76    where
77        E: Endian,
78        B: ParseBuf<'p>,
79    {
80        Ok(Self {
81            dev: p.parse()?,
82            inode: p.parse()?,
83        })
84    }
85}
86
87impl<'p> Parse<'p> for Namespaces<'p> {
88    fn parse<B, E>(p: &mut Parser<B, E>) -> ParseResult<Self>
89    where
90        E: Endian,
91        B: ParseBuf<'p>,
92    {
93        let pid = p.parse()?;
94        let tid = p.parse()?;
95        let len = p.parse_u64()? as usize;
96        let namespaces = unsafe { p.parse_slice(len)? };
97
98        Ok(Self {
99            pid,
100            tid,
101            namespaces,
102        })
103    }
104}