From becb4effcd84f5de8e1c679a79b60ef3ba6abb78 Mon Sep 17 00:00:00 2001 From: Ryan Newton Date: Wed, 7 Dec 2022 07:47:13 -0800 Subject: [PATCH] refactor: give Config its own Display instance Summary: The RunOpts Display instance was essentially doing all the work of the Config Display instance also. This factors that instance out to stand on its own. Eventually, this should be a step towards making some of the fields in Config private as well. Reviewed By: VladimirMakaev Differential Revision: D41721643 fbshipit-source-id: 0ae32c95e18886bf67de2840ccbc11d61610fde9 --- detcore-model/Cargo.toml | 1 + detcore-model/src/config.rs | 160 ++++++++++++++++++++++++++++++ hermit-cli/src/bin/hermit/run.rs | 161 +------------------------------ 3 files changed, 163 insertions(+), 159 deletions(-) diff --git a/detcore-model/Cargo.toml b/detcore-model/Cargo.toml index 8c54fea..4490b6f 100644 --- a/detcore-model/Cargo.toml +++ b/detcore-model/Cargo.toml @@ -15,6 +15,7 @@ libc = "0.2.137" nix = "0.25" reverie-syscalls = { version = "0.1.0", git = "https://github.com/facebookexperimental/reverie.git", branch = "main" } serde = { version = "1.0.136", features = ["derive", "rc"] } +shell-words = "1.1.0" tracing = "0.1.35" [dev-dependencies] diff --git a/detcore-model/src/config.rs b/detcore-model/src/config.rs index 51a2d60..a2735fa 100644 --- a/detcore-model/src/config.rs +++ b/detcore-model/src/config.rs @@ -414,6 +414,166 @@ impl Config { } } +impl fmt::Display for Config { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if !self.virtualize_time { + write!(f, " --no-virtualize-time")?; + } + if !self.virtualize_cpuid { + write!(f, " --no-virtualize-cpuid")?; + } + if !self.virtualize_metadata { + write!(f, " --no-virtualize-metadata")?; + } + let default_epoch: DateTime = DEFAULT_EPOCH_STR.parse::>().unwrap(); + if self.epoch != default_epoch { + write!(f, " --epoch={}", self.epoch.to_rfc3339())?; + } + if self.seed != 0 { + write!(f, " --seed={}", self.seed)?; + } + + if let Some(rng_seed) = self.rng_seed { + write!(f, " --rng-seed={}", rng_seed)?; + } + if let Some(fuzz_seed) = self.fuzz_seed { + write!(f, " --fuzz-seed={}", fuzz_seed)?; + } + + if self.fuzz_futexes { + write!(f, " --fuzz-futexes")?; + } + if let Some(m) = self.clock_multiplier { + write!(f, " --clock-multiplier={}", m)?; + } + if self.imprecise_timers { + write!(f, " --imprecise-timers")?; + } + if self.chaos { + write!(f, " --chaos")?; + } + if self.record_preemptions { + write!(f, " --record-preemptions")?; + } + + if let Some(p) = &self.record_preemptions_to { + let s = p.to_str().expect("valid unicode path"); + write!(f, " --record-preemptions-to={}", shell_words::quote(s))?; + } + if let Some(p) = &self.replay_preemptions_from { + let s = p.to_str().expect("valid unicode path"); + write!(f, " --replay-preemptions-from={}", shell_words::quote(s))?; + } + if let Some(p) = &self.replay_schedule_from { + let s = p.to_str().expect("valid unicode path"); + write!(f, " --replay-schedule-from={}", shell_words::quote(s))?; + } + if self.replay_exhausted_panic { + write!(f, " --replay-exhausted-panic")?; + } + if self.die_on_desync { + write!(f, " --die-on-desync")?; + } + for (index, path) in &self.stacktrace_event { + write!(f, " --stacktrace-event={}", index)?; + if let Some(p) = path { + let s = p.to_str().expect("valid unicode path"); + write!(f, ",{}", shell_words::quote(s))?; + } + } + if self.preemption_stacktrace { + write!(f, " --preemption-stacktrace")?; + } + if self.panic_on_unsupported_syscalls { + write!(f, " --panic-on-unsupported-syscalls")?; + } + if self.kill_daemons { + write!(f, " --kill-daemons")?; + } + if self.gdbserver { + write!(f, " --gdbserver")?; + } + if self.gdbserver_port != /* default */ 1234u16 { + write!(f, " --gdbserver-port={}", self.gdbserver_port)?; + } + match &self.preemption_timeout { + Some(x) => { + if *x != NonZeroU64::new(200_000_000).unwrap() { + write!(f, " --preemption-timeout={}", x)?; + } + } + None => { + write!(f, " --preemption-timeout=disabled")?; + } + } + if self.sigint_instakill { + write!(f, " --sigint-instakill")?; + } + if self.warn_non_zero_binds { + write!(f, " --warn-non-zero-binds")?; + } + match &self.sched_heuristic { + SchedHeuristic::None => {} + SchedHeuristic::ConnectBind => { + write!(f, " --sched-heuristic=connectbind")?; + } + SchedHeuristic::Random => { + write!(f, " --sched-heuristic=random")?; + } + SchedHeuristic::StickyRandom => { + write!(f, " --sched-heuristic=stickyrandom")?; + } + } + if let Some(s) = self.sched_seed { + write!(f, " --sched-seed={}", s)?; + } + if self.sched_sticky_random_param != 0.0 { + write!( + f, + " --sched-sticky-random-param={}", + self.sched_sticky_random_param + )?; + } + if let Some(t) = self.stop_after_turn { + write!(f, " --stop-after-turn={}", t)?; + } + if let Some(i) = self.stop_after_iter { + write!(f, " --stop-after-iter={}", i)?; + } + if self.debug_externalize_sockets { + write!(f, " --debug-externalize-sockets")?; + } + match &self.debug_futex_mode { + BlockingMode::External => { + write!(f, " --debug-futex-mode=external")?; + } + BlockingMode::Polling => { + write!(f, " --debug-futex-mode=polling")?; + } + BlockingMode::Precise => { /* default */ } + } + if self.no_rcb_time { + write!(f, " --no-rcb-time")?; + } + if self.detlog_heap { + write!(f, " --detlog-heap")?; + } + if self.detlog_stack { + write!(f, " --detlog-stack")?; + } + if self.sysinfo_uptime_offset != /* default */ 120 { + write!(f, " --sysinfo-uptime-offset={}", self.sysinfo_uptime_offset)?; + } + if self.memory != 1_000_000_000 { + write!(f, " --memory={}", self.memory)?; + } + for (tid, rcb) in &self.interrupt_at { + write!(f, " --interrupt-at={}:{}", tid, rcb)?; + } + Ok(()) + } +} + /// How should we handle syscalls which may block, but are internal to the hermit container? /// These syscalls are determinizable, but there are multiple methods of doing so. /// These choices *do not* apply to blocking syscalls that wait for external conditions outside the diff --git a/hermit-cli/src/bin/hermit/run.rs b/hermit-cli/src/bin/hermit/run.rs index f440b27..6ad1174 100644 --- a/hermit-cli/src/bin/hermit/run.rs +++ b/hermit-cli/src/bin/hermit/run.rs @@ -13,19 +13,13 @@ use std::fs::File; use std::hash::Hash; use std::hash::Hasher; use std::io::Write; -use std::num::NonZeroU64; use std::path::Path; use std::path::PathBuf; use std::str::FromStr; use ::tracing::metadata::LevelFilter; -use chrono::DateTime; -use chrono::Utc; use clap::Parser; use colored::Colorize; -use detcore::BlockingMode; -use detcore::SchedHeuristic; -use detcore_model::config::DEFAULT_EPOCH_STR; use hermit::Context; use hermit::DetConfig; use hermit::Error; @@ -445,159 +439,8 @@ impl fmt::Display for RunOpts { } } - if !dop.virtualize_time { - write!(f, " --no-virtualize-time")?; - } - if !dop.virtualize_cpuid { - write!(f, " --no-virtualize-cpuid")?; - } - if !dop.virtualize_metadata { - write!(f, " --no-virtualize-metadata")?; - } - let default_epoch: DateTime = DEFAULT_EPOCH_STR.parse::>().unwrap(); - if dop.epoch != default_epoch { - write!(f, " --epoch={}", dop.epoch.to_rfc3339())?; - } - if dop.seed != 0 { - write!(f, " --seed={}", dop.seed)?; - } - - if let Some(rng_seed) = dop.rng_seed { - write!(f, " --rng-seed={}", rng_seed)?; - } - if let Some(fuzz_seed) = dop.fuzz_seed { - write!(f, " --fuzz-seed={}", fuzz_seed)?; - } - - if dop.fuzz_futexes { - write!(f, " --fuzz-futexes")?; - } - if let Some(m) = dop.clock_multiplier { - write!(f, " --clock-multiplier={}", m)?; - } - if dop.imprecise_timers { - write!(f, " --imprecise-timers")?; - } - if dop.chaos { - write!(f, " --chaos")?; - } - if dop.record_preemptions { - write!(f, " --record-preemptions")?; - } - if let Some(p) = &dop.record_preemptions_to { - let s = p.to_str().expect("valid unicode path"); - write!(f, " --record-preemptions-to={}", shell_words::quote(s))?; - } - if let Some(p) = &dop.replay_preemptions_from { - let s = p.to_str().expect("valid unicode path"); - write!(f, " --replay-preemptions-from={}", shell_words::quote(s))?; - } - if let Some(p) = &dop.replay_schedule_from { - let s = p.to_str().expect("valid unicode path"); - write!(f, " --replay-schedule-from={}", shell_words::quote(s))?; - } - if dop.replay_exhausted_panic { - write!(f, " --replay-exhausted-panic")?; - } - if dop.die_on_desync { - write!(f, " --die-on-desync")?; - } - for (index, path) in &dop.stacktrace_event { - write!(f, " --stacktrace-event={}", index)?; - if let Some(p) = path { - let s = p.to_str().expect("valid unicode path"); - write!(f, ",{}", shell_words::quote(s))?; - } - } - if dop.preemption_stacktrace { - write!(f, " --preemption-stacktrace")?; - } - if dop.panic_on_unsupported_syscalls { - write!(f, " --panic-on-unsupported-syscalls")?; - } - if dop.kill_daemons { - write!(f, " --kill-daemons")?; - } - if dop.gdbserver { - write!(f, " --gdbserver")?; - } - if dop.gdbserver_port != /* default */ 1234u16 { - write!(f, " --gdbserver-port={}", dop.gdbserver_port)?; - } - match &dop.preemption_timeout { - Some(x) => { - if *x != NonZeroU64::new(200_000_000).unwrap() { - write!(f, " --preemption-timeout={}", x)?; - } - } - None => { - write!(f, " --preemption-timeout=disabled")?; - } - } - if dop.sigint_instakill { - write!(f, " --sigint-instakill")?; - } - if dop.warn_non_zero_binds { - write!(f, " --warn-non-zero-binds")?; - } - match &dop.sched_heuristic { - SchedHeuristic::None => {} - SchedHeuristic::ConnectBind => { - write!(f, " --sched-heuristic=connectbind")?; - } - SchedHeuristic::Random => { - write!(f, " --sched-heuristic=random")?; - } - SchedHeuristic::StickyRandom => { - write!(f, " --sched-heuristic=stickyrandom")?; - } - } - if let Some(s) = dop.sched_seed { - write!(f, " --sched-seed={}", s)?; - } - if dop.sched_sticky_random_param != 0.0 { - write!( - f, - " --sched-sticky-random-param={}", - dop.sched_sticky_random_param - )?; - } - if let Some(t) = dop.stop_after_turn { - write!(f, " --stop-after-turn={}", t)?; - } - if let Some(i) = dop.stop_after_iter { - write!(f, " --stop-after-iter={}", i)?; - } - if dop.debug_externalize_sockets { - write!(f, " --debug-externalize-sockets")?; - } - match &dop.debug_futex_mode { - BlockingMode::External => { - write!(f, " --debug-futex-mode=external")?; - } - BlockingMode::Polling => { - write!(f, " --debug-futex-mode=polling")?; - } - BlockingMode::Precise => { /* default */ } - } - if dop.no_rcb_time { - write!(f, " --no-rcb-time")?; - } - if dop.detlog_heap { - write!(f, " --detlog-heap")?; - } - if dop.detlog_stack { - write!(f, " --detlog-stack")?; - } - if dop.sysinfo_uptime_offset != /* default */ 120 { - write!(f, " --sysinfo-uptime-offset={}", dop.sysinfo_uptime_offset)?; - } - if dop.memory != 1_000_000_000 { - write!(f, " --memory={}", dop.memory)?; - } - for (tid, rcb) in &dop.interrupt_at { - write!(f, " --interrupt-at={}:{}", tid, rcb)?; - } + // Write the rest of the flags from the Config itself: + write!(f, "{}", dop)?; write!( f,