Skip to content

Commit

Permalink
Update file timestamps to reflect real systemtime (#1041)
Browse files Browse the repository at this point in the history
### What does this PR do?

This commit retains the use of a stateless tick in the model but
allows for the filesystem to report times in systemtime. This
resolves a problem where all times were previously reported by the
filesystem as being UNIX_EPOCH even though the model kept track of
time.
  • Loading branch information
blt authored Oct 28, 2024
1 parent 35a65a9 commit 382b730
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 33 deletions.
76 changes: 43 additions & 33 deletions lading/src/bin/logrotate_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,7 @@ use tracing_subscriber::{fmt::format::FmtSpan, util::SubscriberInitExt};
// use lading_payload::block;
use nix::libc::{self, ENOENT};
use serde::Deserialize;
use std::{
ffi::OsStr,
num::NonZeroU32,
path::PathBuf,
time::{Duration, UNIX_EPOCH},
};
use std::{ffi::OsStr, num::NonZeroU32, path::PathBuf, time::Duration};

// fn default_config_path() -> String {
// "/etc/lading/logrotate_fs.yaml".to_string()
Expand Down Expand Up @@ -83,6 +78,7 @@ const TTL: Duration = Duration::from_secs(1); // Attribute cache timeout
struct LogrotateFS {
state: model::State,
start_time: std::time::Instant,
start_time_system: std::time::SystemTime,
}

impl LogrotateFS {
Expand All @@ -95,33 +91,46 @@ impl LogrotateFS {
fn getattr_helper(&mut self, tick: model::Tick, inode: usize) -> Option<FileAttr> {
let nlink = self.state.nlink(inode) as u32;

self.state.getattr(tick, inode).map(|attr| FileAttr {
ino: attr.inode as u64,
size: attr.size,
blocks: (attr.size + 511) / 512,
// TODO these times should reflect those in the model, will need to
// be translated from the tick to systemtime. Implies we'll need to
// adjust up from start_time, knowing that a tick is one second
// wide.
atime: UNIX_EPOCH,
mtime: UNIX_EPOCH,
ctime: UNIX_EPOCH,
crtime: UNIX_EPOCH,
kind: match attr.kind {
model::NodeType::File => fuser::FileType::RegularFile,
model::NodeType::Directory => fuser::FileType::Directory,
},
perm: if matches!(attr.kind, model::NodeType::Directory) {
0o755
} else {
0o644
},
nlink,
uid: unsafe { libc::getuid() },
gid: unsafe { libc::getgid() },
rdev: 0,
blksize: 512,
flags: 0,
self.state.getattr(tick, inode).map(|attr| {
// Convert ticks to durations
let access_duration = Duration::from_secs(attr.access_tick);
let modified_duration = Duration::from_secs(attr.modified_tick);
let status_duration = Duration::from_secs(attr.status_tick);

// Calculate SystemTime instances
let atime = self.start_time_system + access_duration;
let mtime = self.start_time_system + modified_duration;
let ctime = self.start_time_system + status_duration;
let crtime = self.start_time_system; // Assume creation time is when the filesystem started

FileAttr {
ino: attr.inode as u64,
size: attr.size,
blocks: (attr.size + 511) / 512,
// TODO these times should reflect those in the model, will need to
// be translated from the tick to systemtime. Implies we'll need to
// adjust up from start_time, knowing that a tick is one second
// wide.
atime,
mtime,
ctime,
crtime,
kind: match attr.kind {
model::NodeType::File => fuser::FileType::RegularFile,
model::NodeType::Directory => fuser::FileType::Directory,
},
perm: if matches!(attr.kind, model::NodeType::Directory) {
0o755
} else {
0o644
},
nlink,
uid: unsafe { libc::getuid() },
gid: unsafe { libc::getgid() },
rdev: 0,
blksize: 512,
flags: 0,
}
})
}
}
Expand Down Expand Up @@ -297,6 +306,7 @@ fn main() -> Result<(), Error> {
let fs = LogrotateFS {
state,
start_time: std::time::Instant::now(),
start_time_system: std::time::SystemTime::now(),
};

// Mount the filesystem
Expand Down
12 changes: 12 additions & 0 deletions lading/src/generator/file_gen/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,12 @@ pub struct NodeAttributes {
pub kind: NodeType,
/// The size in bytes.
pub size: u64,
/// The last access time in ticks.
pub access_tick: Tick,
/// The last modified time in ticks.
pub modified_tick: Tick,
/// The last status change time in ticks.
pub status_tick: Tick,
}

/// Describe whether the Node is a File or Directory.
Expand Down Expand Up @@ -298,11 +304,17 @@ impl State {
inode,
kind: NodeType::File,
size: file.bytes_written,
access_tick: file.access_tick,
modified_tick: file.modified_tick,
status_tick: file.status_tick,
},
Node::Directory { .. } => NodeAttributes {
inode,
kind: NodeType::Directory,
size: 0,
access_tick: self.now,
modified_tick: self.now,
status_tick: self.now,
},
})
}
Expand Down

0 comments on commit 382b730

Please sign in to comment.