1use log::error;
3use serde::{Deserialize, Serialize};
4use std::io;
5
6use rd_util::*;
7
8pub mod args;
9pub mod bandit_report;
10pub mod bench;
11pub mod cmd;
12pub mod cmd_ack;
13pub mod index;
14pub mod oomd;
15pub mod report;
16pub mod side_defs;
17pub mod slices;
18pub mod sysreqs;
19
20pub use args::{Args, Bandit, BanditMemHogArgs, EnforceConfig};
21pub use bandit_report::BanditMemHogReport;
22pub use bench::{BenchKnobs, HashdKnobs, IoCostKnobs, BENCH_FILENAME};
23pub use cmd::{Cmd, HashdCmd, SideloaderCmd};
24pub use cmd_ack::CmdAck;
25pub use index::Index;
26pub use oomd::{OomdKnobs, OomdSliceMemPressureKnobs, OomdSliceSenpaiKnobs};
27pub use report::{
28 BenchHashdReport, BenchIoCostReport, HashdReport, IoCostModelReport, IoCostQoSReport,
29 IoCostReport, IoLatReport, OomdReport, Report, ReportIter, ReportPathIter, ResCtlReport,
30 SideloadReport, SideloaderReport, StatMap, SvcReport, SvcStateReport, SysloadReport,
31 UsageReport,
32};
33pub use side_defs::{SideloadDefs, SideloadSpec};
34pub use slices::{DisableSeqKnobs, MemoryKnob, Slice, SliceConfig, SliceKnobs, ROOT_SLICE};
35pub use sysreqs::{MissedSysReqs, SysReq, SysReqsReport, ALL_SYSREQS_SET};
36
37lazy_static::lazy_static! {
38 pub static ref VERSION: &'static str = env!("CARGO_PKG_VERSION");
39 pub static ref FULL_VERSION: String = full_version(*VERSION);
40}
41
42#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
43pub enum RunnerState {
44 Idle,
45 Running,
46 BenchHashd,
47 BenchIoCost,
48}
49
50pub const AGENT_SVC_NAME: &str = "rd-agent.service";
51pub const HASHD_BENCH_SVC_NAME: &str = "rd-hashd-bench.service";
52pub const IOCOST_BENCH_SVC_NAME: &str = "rd-iocost-bench.service";
53pub const HASHD_A_SVC_NAME: &str = "rd-hashd-A.service";
54pub const HASHD_B_SVC_NAME: &str = "rd-hashd-B.service";
55pub const OOMD_SVC_NAME: &str = "rd-oomd.service";
56pub const SIDELOADER_SVC_NAME: &str = "rd-sideloader.service";
57pub const SIDELOAD_SVC_PREFIX: &str = "rd-sideload-";
58pub const SYSLOAD_SVC_PREFIX: &str = "rd-sysload-";
59
60pub fn sysload_svc_name(name: &str) -> String {
61 format!("{}{}.service", SYSLOAD_SVC_PREFIX, name)
62}
63
64pub fn sideload_svc_name(name: &str) -> String {
65 format!("{}{}.service", SIDELOAD_SVC_PREFIX, name)
66}
67
68#[derive(Default)]
69pub struct AgentFiles {
70 pub args_path: String,
71 pub index_path: String,
72 pub args: JsonConfigFile<Args>,
73 pub index: JsonConfigFile<Index>,
74 pub cmd: JsonConfigFile<Cmd>,
75 pub cmd_ack: JsonConfigFile<CmdAck>,
76 pub sysreqs: JsonConfigFile<SysReqsReport>,
77 pub report: JsonConfigFile<Report>,
78 pub bench: JsonConfigFile<BenchKnobs>,
79 pub slices: JsonConfigFile<SliceKnobs>,
80 pub oomd: JsonConfigFile<OomdKnobs>,
81}
82
83impl AgentFiles {
84 pub fn new(dir: &str) -> Self {
85 Self {
86 args_path: dir.to_string() + "/args.json",
87 index_path: dir.to_string() + "/index.json",
88 ..Default::default()
89 }
90 }
91
92 fn refresh_one<T>(file: &mut JsonConfigFile<T>, path: &str) -> bool
93 where
94 T: JsonLoad + JsonSave,
95 {
96 match &file.path {
97 None => match JsonConfigFile::<T>::load(path) {
98 Ok(v) => {
99 *file = v;
100 true
101 }
102 Err(e) => {
103 match e.downcast_ref::<io::Error>() {
104 Some(e) if e.raw_os_error() == Some(libc::ENOENT) => (),
105 _ => error!("Failed to read {:?} ({:?})", path, &e),
106 }
107 false
108 }
109 },
110 Some(_) => match file.maybe_reload() {
111 Ok(v) => v,
112 Err(e) => {
113 match e.downcast_ref::<io::Error>() {
114 Some(e) if e.raw_os_error() == Some(libc::ENOENT) => (),
115 _ => error!("Failed to reload {:?} ({:?})", path, &e),
116 }
117 false
118 }
119 },
120 }
121 }
122
123 pub fn refresh(&mut self) {
124 Self::refresh_one(&mut self.args, &self.args_path);
125
126 if Self::refresh_one(&mut self.index, &self.index_path) {
127 self.cmd = Default::default();
128 self.cmd_ack = Default::default();
129 self.sysreqs = Default::default();
130 self.report = Default::default();
131 self.bench = Default::default();
132 self.slices = Default::default();
133 self.oomd = Default::default();
134 }
135 if let None = self.index.path {
136 return;
137 }
138
139 let index = &self.index.data;
140
141 Self::refresh_one(&mut self.cmd, &index.cmd);
142 Self::refresh_one(&mut self.cmd_ack, &index.cmd_ack);
143 Self::refresh_one(&mut self.sysreqs, &index.sysreqs);
144 Self::refresh_one(&mut self.report, &index.report);
145 Self::refresh_one(&mut self.bench, &index.bench);
146 Self::refresh_one(&mut self.slices, &index.slices);
147 Self::refresh_one(&mut self.oomd, &index.oomd);
148 }
149}