a653rs_linux_core/
partition.rs

1use std::fs::File;
2use std::io::{Read, Write};
3use std::os::unix::prelude::{IntoRawFd, RawFd};
4use std::time::Duration;
5
6use a653rs::bindings::PortDirection;
7use a653rs::prelude::{PartitionId, StartCondition};
8use memfd::{FileSeal, MemfdOptions};
9use serde::{Deserialize, Serialize};
10
11use crate::error::{ResultExt, SystemError, TypedError, TypedResult};
12
13#[derive(Debug, Serialize, Deserialize, Clone)]
14pub struct PartitionConstants {
15    pub name: String,
16    pub identifier: PartitionId,
17    pub period: Duration,
18    pub duration: Duration,
19    pub start_condition: StartCondition,
20    pub start_time_fd: RawFd,
21    pub partition_mode_fd: RawFd,
22
23    // A UNIX domain sockets, that are used to send file descriptors to the partition.
24    pub udp_io_fd: RawFd,
25    pub tcp_io_fd: RawFd,
26
27    pub sampling: Vec<SamplingConstant>,
28    pub queuing: Vec<QueuingConstant>,
29}
30
31#[derive(Debug, Serialize, Deserialize, Clone)]
32pub struct SamplingConstant {
33    pub name: String,
34    pub dir: PortDirection,
35    pub msg_size: usize,
36    pub fd: RawFd,
37}
38
39#[derive(Debug, Serialize, Deserialize, Clone)]
40pub struct QueuingConstant {
41    pub name: String,
42    pub dir: PortDirection,
43    pub msg_size: usize,
44    pub max_num_msg: usize,
45    pub fd: RawFd,
46}
47
48impl PartitionConstants {
49    pub const PARTITION_CONSTANTS_FD: &'static str = "PARTITION_CONSTANTS_FD";
50    pub const PROCESSES_CGROUP: &'static str = "processes";
51    pub const MAIN_PROCESS_CGROUP: &'static str = "main";
52    pub const APERIODIC_PROCESS_CGROUP: &'static str = "aperiodic";
53    pub const PERIODIC_PROCESS_CGROUP: &'static str = "periodic";
54    pub const IPC_SENDER: &'static str = "/.inner/ipc";
55
56    pub fn open() -> TypedResult<Self> {
57        let fd = std::env::var(Self::PARTITION_CONSTANTS_FD)
58            .typ(SystemError::PartitionInit)?
59            .parse::<RawFd>()
60            .typ(SystemError::PartitionInit)?;
61        PartitionConstants::try_from(fd).typ(SystemError::PartitionInit)
62    }
63}
64
65impl TryFrom<RawFd> for PartitionConstants {
66    type Error = TypedError;
67
68    fn try_from(file: RawFd) -> TypedResult<Self> {
69        let mut file = File::open(format!("/proc/self/fd/{file}")).typ(SystemError::Panic)?;
70        let mut buf = Vec::new();
71        file.read_to_end(&mut buf).typ(SystemError::Panic)?;
72        bincode::deserialize(&buf).typ(SystemError::Panic)
73    }
74}
75
76impl TryFrom<PartitionConstants> for RawFd {
77    type Error = TypedError;
78
79    fn try_from(consts: PartitionConstants) -> TypedResult<Self> {
80        let bytes = bincode::serialize(&consts).typ(SystemError::Panic)?;
81
82        let mem = MemfdOptions::default()
83            .close_on_exec(false)
84            .allow_sealing(true)
85            .create("constants")
86            .typ(SystemError::Panic)?;
87        mem.as_file()
88            .set_len(bytes.len() as u64)
89            .typ(SystemError::Panic)?;
90        mem.as_file().write_all(&bytes).typ(SystemError::Panic)?;
91        mem.add_seals(&[
92            FileSeal::SealShrink,
93            FileSeal::SealGrow,
94            FileSeal::SealWrite,
95            FileSeal::SealSeal,
96        ])
97        .typ(SystemError::Panic)?;
98
99        Ok(mem.into_raw_fd())
100    }
101}