Skip to content

Commit

Permalink
Improve wtmp record mangling. (#4501)
Browse files Browse the repository at this point in the history
This fixes two problems with the current wtmp/utmp record mangling.
First it is not idempotent, the system's notion of boot time is set to
the current time of day whenever sled agent confirms that time is
synchronised. Secondly, this is only approximate even for the first sled
agent start, but it's plain wrong if sled agent restarts later.

In conjunction with changes to stlouis, the `tmpx` utility is now able
to process all zones itself, and uses the true system boot time for each
zone when updating records.

Fixes: #3514
  • Loading branch information
citrus-it authored Dec 4, 2023
1 parent 8cf3e2a commit 6f2d1c5
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 35 deletions.
45 changes: 10 additions & 35 deletions sled-agent/src/services.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,11 @@ use sled_storage::manager::StorageHandle;
use slog::Logger;
use std::collections::BTreeMap;
use std::collections::HashSet;
use std::iter;
use std::iter::FromIterator;
use std::net::{IpAddr, Ipv6Addr, SocketAddr};
use std::str::FromStr;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::time::{SystemTime, UNIX_EPOCH};
use tokio::io::AsyncWriteExt;
use tokio::sync::Mutex;
use tokio::sync::{oneshot, MutexGuard};
Expand Down Expand Up @@ -2931,10 +2929,7 @@ impl ServiceManager {
Ok(())
}

pub fn boottime_rewrite<'a>(
&self,
zones: impl Iterator<Item = &'a RunningZone>,
) {
pub fn boottime_rewrite(&self) {
if self
.inner
.time_synced
Expand All @@ -2945,33 +2940,13 @@ impl ServiceManager {
return;
}

let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("SystemTime before UNIX EPOCH");

info!(self.inner.log, "Setting boot time to {:?}", now);

let files: Vec<Utf8PathBuf> = zones
.map(|z| z.root())
.chain(iter::once(Utf8PathBuf::from("/")))
.flat_map(|r| [r.join("var/adm/utmpx"), r.join("var/adm/wtmpx")])
.collect();

for file in files {
let mut command = std::process::Command::new(PFEXEC);
let cmd = command.args(&[
"/usr/platform/oxide/bin/tmpx",
&format!("{}", now.as_secs()),
&file.as_str(),
]);
match execute(cmd) {
Err(e) => {
warn!(self.inner.log, "Updating {} failed: {}", &file, e);
}
Ok(_) => {
info!(self.inner.log, "Updated {}", &file);
}
}
// Call out to the 'tmpx' utility program which will rewrite the wtmpx
// and utmpx databases in every zone, including the global zone, to
// reflect the adjusted system boot time.
let mut command = std::process::Command::new(PFEXEC);
let cmd = command.args(&["/usr/platform/oxide/bin/tmpx", "-Z"]);
if let Err(e) = execute(cmd) {
warn!(self.inner.log, "Updating [wu]tmpx databases failed: {}", e);
}
}

Expand All @@ -2980,7 +2955,7 @@ impl ServiceManager {

if let Some(true) = self.inner.skip_timesync {
info!(self.inner.log, "Configured to skip timesync checks");
self.boottime_rewrite(existing_zones.values());
self.boottime_rewrite();
return Ok(TimeSync {
sync: true,
ref_id: 0,
Expand Down Expand Up @@ -3034,7 +3009,7 @@ impl ServiceManager {
&& correction.abs() <= 0.05;

if sync {
self.boottime_rewrite(existing_zones.values());
self.boottime_rewrite();
}

Ok(TimeSync {
Expand Down
2 changes: 2 additions & 0 deletions tools/install_builder_prerequisites.sh
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ function install_packages {
"library/libxmlsec1"
# "bindgen leverages libclang to preprocess, parse, and type check C and C++ header files."
"pkg:/ooce/developer/clang-$CLANGVER"
"system/library/gcc-runtime"
"system/library/g++-runtime"
)

# Install/update the set of packages.
Expand Down

0 comments on commit 6f2d1c5

Please sign in to comment.