Skip to content

Commit

Permalink
fix errors, able to tail -F
Browse files Browse the repository at this point in the history
Signed-off-by: Brian L. Troutwine <[email protected]>
  • Loading branch information
blt committed Oct 22, 2024
1 parent 4733928 commit 7c41181
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 34 deletions.
71 changes: 47 additions & 24 deletions lading/src/bin/logrotate_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,16 @@ impl LogrotateFS {

#[tracing::instrument(skip(self))]
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,
Expand All @@ -110,7 +116,7 @@ impl LogrotateFS {
} else {
0o644
},
nlink: 1,
nlink,
uid: unsafe { libc::getuid() },
gid: unsafe { libc::getgid() },
rdev: 0,
Expand All @@ -137,9 +143,14 @@ impl Filesystem for LogrotateFS {
let name_str = name.to_str().unwrap_or("");
if let Some(ino) = self.state.lookup(tick, parent as usize, name_str) {
if let Some(attr) = self.getattr_helper(tick, ino) {
info!("lookup: returning attr for inode {}: {:?}", ino, attr);
reply.entry(&TTL, &attr, 0);
return;
} else {
error!("lookup: getattr_helper returned None for inode {}", ino);
}
} else {
error!("lookup: state.lookup returned None for name {}", name_str);
}
reply.error(ENOENT);
}
Expand Down Expand Up @@ -191,44 +202,56 @@ impl Filesystem for LogrotateFS {
let tick = self.get_current_tick();
self.state.advance_time(tick);

if offset != 0 {
reply.ok();
return;
}

let root_inode = self.state.root_inode();

if let Some(entries) = self.state.readdir(ino as usize) {
let mut index = 1;
// TODO fix
let _ = reply.add(ino, index, fuser::FileType::Directory, ".");
index += 1;
if ino != root_inode as u64 {
let parent_ino = self
.state
.get_parent_inode(ino as usize)
.expect("inode must have parent");
// TODO fix
let _ = reply.add(parent_ino as u64, index, fuser::FileType::Directory, "..");
index += 1;
}
// TODO building up a vec of entries here to handle offset really does
// suggest that the model needs to be exposed in such a way that this
// needn't be done.
let mut entries = Vec::new();

for child_ino in entries {
// '.' and '..'
entries.push((ino, fuser::FileType::Directory, ".".to_string()));
if ino != root_inode as u64 {
let parent_ino = self
.state
.get_parent_inode(ino as usize)
.expect("inode must have parent");
entries.push((
parent_ino as u64,
fuser::FileType::Directory,
"..".to_string(),
));
}

// reaming children
if let Some(child_inodes) = self.state.readdir(ino as usize) {
for child_ino in child_inodes {
if let Some(name) = self.state.get_name(*child_ino) {
let file_type = self
.state
.get_file_type(*child_ino)
.expect("inode must have file type");
let _ = reply.add(*child_ino as u64, index, file_type, name);
index += 1;
entries.push((*child_ino as u64, file_type, name.to_string()));
} else {
error!("child inode has no name");
}
}
reply.ok();
} else {
reply.error(ENOENT);
return;
}

let mut idx = offset as usize;
while idx < entries.len() {
let (inode, file_type, name) = &entries[idx];
let next_offset = (idx + 1) as i64;
if reply.add(*inode, next_offset, *file_type, name) {
// Buffer is full, exit the loop
break;
}
idx += 1;
}
reply.ok();
}

#[tracing::instrument(skip(self, _req, reply))]
Expand Down
40 changes: 30 additions & 10 deletions lading/src/generator/file_gen/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ impl File {
self.advance_time(now);

assert!(self.bytes_written >= self.bytes_read);
self.bytes_read.saturating_sub(self.bytes_read)
self.bytes_written.saturating_sub(self.bytes_read)
}

/// Register a read.
Expand Down Expand Up @@ -181,18 +181,19 @@ pub enum NodeType {

impl State {
/// Create a new instance of `State`.
#[tracing::instrument]
#[tracing::instrument(skip(block_cache))]
pub fn new(bytes_per_tick: u64, block_cache: block::Cache) -> State {
let root_inode: Inode = 0; // `/`
let logs_inode: Inode = 1; // `/logs`
let foo_log_inode: Inode = 2; // `/logs/foo.log`
let root_inode: Inode = 1; // `/`
let logs_inode: Inode = 2; // `/logs`
let foo_log_inode: Inode = 3; // `/logs/foo.log`

let mut nodes = HashMap::new();

let root_dir = Directory {
let mut root_dir = Directory {
children: HashSet::new(),
parent: None,
};
root_dir.children.insert(logs_inode);
nodes.insert(
root_inode,
Node::Directory {
Expand All @@ -201,14 +202,15 @@ impl State {
},
);

let logs_dir = Directory {
let mut logs_dir = Directory {
children: HashSet::new(),
parent: Some(root_inode),
};
logs_dir.children.insert(foo_log_inode);
nodes.insert(
logs_inode,
Node::Directory {
name: "/logs".to_string(),
name: "logs".to_string(),
dir: logs_dir,
},
);
Expand All @@ -228,7 +230,7 @@ impl State {
nodes.insert(
foo_log_inode,
Node::File {
name: "/logs/foo.log".to_string(),
name: "foo.log".to_string(),
file: foo_log,
},
);
Expand Down Expand Up @@ -267,7 +269,7 @@ impl State {
pub fn lookup(&mut self, now: Tick, parent_inode: Inode, name: &str) -> Option<Inode> {
self.advance_time(now);

if let Some(Node::Directory { name, dir }) = self.nodes.get(&parent_inode) {
if let Some(Node::Directory { dir, .. }) = self.nodes.get(&parent_inode) {
for child_inode in &dir.children {
let child_node = &self
.nodes
Expand Down Expand Up @@ -391,4 +393,22 @@ impl State {
pub fn root_inode(&self) -> Inode {
self.root_inode
}

/// Return the number of links for the inode.
#[must_use]
pub fn nlink(&self, inode: Inode) -> usize {
if let Some(Node::Directory { dir, .. }) = self.nodes.get(&inode) {
let subdirectory_count = dir
.children
.iter()
.filter(|child_inode| {
matches!(self.nodes.get(child_inode), Some(Node::Directory { .. }))
})
.count();
// nlink is 2 (for "." and "..") plus the number of subdirectories
2 + subdirectory_count
} else {
1
}
}
}

0 comments on commit 7c41181

Please sign in to comment.