summary refs log tree commit diff
diff options
context:
space:
mode:
authoredef <edef@unfathomable.blue>2022-07-31 17:49:47 +0000
committeredef <edef@unfathomable.blue>2022-07-31 17:50:41 +0000
commitdbd1db43fc8db263134e85cbf9e8312cdd0e4c2b (patch)
tree5a6a4024943c6212f2199e49d06989bd155e5328
parent02c55f1480dd8efcf8f33abc583476d5adde3d1b (diff)
ripple/minitrace/maps_file: represent inodes more precisely
Change-Id: I5c537b5e41bb085094eb758617c40abe16531ab9
-rw-r--r--ripple/minitrace/src/main.rs5
-rw-r--r--ripple/minitrace/src/maps_file.rs36
2 files changed, 31 insertions, 10 deletions
diff --git a/ripple/minitrace/src/main.rs b/ripple/minitrace/src/main.rs
index 7053d22..1b67011 100644
--- a/ripple/minitrace/src/main.rs
+++ b/ripple/minitrace/src/main.rs
@@ -147,13 +147,12 @@ impl Process {
 		for &mut maps_file::Mapping {
 			start,
 			end,
-			dev,
 			inode,
 			ref mut pathname,
 			..
 		} in &mut mappings
 		{
-			if (dev, inode) == ((0, 0), 0) {
+			if inode.is_none() {
 				let is_special = pathname.starts_with('[') && pathname.ends_with(']');
 				assert!(is_special || pathname.is_empty());
 				// these won't exist in map_files
@@ -184,7 +183,7 @@ impl Process {
 			let mut segment = vec![];
 			segment.push(last);
 			while let Some(&next) = mappings.peek() {
-				if last.dev != next.dev || last.inode != next.inode {
+				if last.inode != next.inode {
 					// not the same file
 					break;
 				}
diff --git a/ripple/minitrace/src/maps_file.rs b/ripple/minitrace/src/maps_file.rs
index 77601e6..7a48147 100644
--- a/ripple/minitrace/src/maps_file.rs
+++ b/ripple/minitrace/src/maps_file.rs
@@ -2,6 +2,7 @@
 // SPDX-License-Identifier: OSL-3.0
 
 use {
+	crate::syscall_abi::Device,
 	anyhow::bail,
 	nom::{
 		branch::alt,
@@ -10,7 +11,10 @@ use {
 		sequence::tuple,
 		IResult,
 	},
-	std::fmt::{self, Debug},
+	std::{
+		fmt::{self, Debug},
+		num::NonZeroU64,
+	},
 };
 
 fn whitespace(s: &str) -> IResult<&str, &str> {
@@ -94,6 +98,15 @@ fn mapping(input: &str) -> IResult<&str, Mapping> {
 		whitespace,
 		pathname,
 	))(input)?;
+
+	let dev = Device::checked_new(dev_maj, dev_min);
+	let inode = NonZeroU64::new(inode);
+	let inode = match (dev, inode) {
+		(None, None) => None,
+		(Some(dev), Some(node)) => Some(Inode { dev, node }),
+		_ => unreachable!(),
+	};
+
 	Ok((
 		input,
 		Mapping {
@@ -104,7 +117,6 @@ fn mapping(input: &str) -> IResult<&str, Mapping> {
 			perm_exec,
 			shared,
 			offset,
-			dev: (dev_maj, dev_min),
 			inode,
 			pathname: pathname.to_owned(),
 		},
@@ -128,11 +140,16 @@ pub(crate) struct Mapping {
 	pub(crate) perm_exec: bool,
 	pub(crate) shared: bool,
 	pub(crate) offset: u64,
-	pub(crate) dev: (u32, u32),
-	pub(crate) inode: u64,
+	pub(crate) inode: Option<Inode>,
 	pub(crate) pathname: String,
 }
 
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+pub(crate) struct Inode {
+	pub(crate) dev: Device,
+	pub(crate) node: NonZeroU64,
+}
+
 impl Debug for Mapping {
 	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 		use std::fmt::Write;
@@ -145,11 +162,14 @@ impl Debug for Mapping {
 			perm_exec,
 			shared,
 			offset,
-			dev: (dev_maj, dev_min),
 			inode,
 			ref pathname,
 		} = *self;
 
+		let (dev_maj, dev_min, inode): (u32, u32, u64) = inode
+			.map(|inode| (inode.dev.major(), inode.dev.minor(), inode.node.into()))
+			.unwrap_or_default();
+
 		write!(f, "{start:016x}-{end:016x} ")?;
 
 		for (c, p) in [('r', perm_read), ('w', perm_write), ('x', perm_exec)] {
@@ -178,8 +198,10 @@ fn golden_mapping() {
 		perm_exec: false,
 		shared: false,
 		offset: 0,
-		dev: (0x00, 0x1e),
-		inode: 7507895,
+		inode: Some(Inode {
+			dev: Device::new(0x00, 0x1e),
+			node: NonZeroU64::new(7507895).unwrap(),
+		}),
 		pathname: "/nix/store/hgl0ydlkgs6y6hx9h7k209shw3v7z77j-coreutils-9.0/bin/coreutils"
 			.to_owned(),
 	};