diff --git a/Cargo.lock b/Cargo.lock index 01d223e832dd7a159e47ee373602994930bc1e42..3ae3a17190e7e72cdebce8dbd7b8855a8e44d937 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "aes" version = "0.7.5" @@ -44,6 +59,21 @@ dependencies = [ "winapi", ] +[[package]] +name = "backtrace" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base64ct" version = "1.6.0" @@ -80,6 +110,12 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + [[package]] name = "cfg-if" version = "1.0.0" @@ -138,6 +174,28 @@ dependencies = [ "termcolor", ] +[[package]] +name = "failure" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -181,6 +239,12 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "gimli" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -217,12 +281,30 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + [[package]] name = "numtoa" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" +[[package]] +name = "object" +version = "0.30.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" +dependencies = [ + "memchr", +] + [[package]] name = "opaque-debug" version = "0.3.0" @@ -342,6 +424,7 @@ dependencies = [ "argon2", "base64ct", "env_logger", + "failure", "fuser", "getrandom", "libc", @@ -371,6 +454,12 @@ version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +[[package]] +name = "rustc-demangle" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a36c42d1873f9a77c53bde094f9664d9891bc604a45b4798fd2c389ed12e5b" + [[package]] name = "seahash" version = "4.1.0" @@ -400,6 +489,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + [[package]] name = "termcolor" version = "1.2.0" @@ -444,6 +545,12 @@ version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + [[package]] name = "users" version = "0.11.0" diff --git a/Cargo.toml b/Cargo.toml index 4cbe883b4f7ad5889f59737dc81082f60552a716..cf56761a56116163179ec2a0b58fa8b691c02b0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,7 @@ aes = { version = "=0.7.5", default-features = false } argon2 = { version = "0.3.4", default-features = false, features = ["alloc"] } base64ct = { version = "1", default-features = false } env_logger = { version = "0.9.0", optional = true } +failure = "0.1.8" getrandom = { version = "0.2.5", optional = true } libc = "0.2" log = { version = "0.4.14", default-features = false, optional = true} diff --git a/Makefile b/Makefile index 0e233fd9744a52a0e5600703b9b8355c39f8adfe..222226946ab9b7ab9763bc118a0b2b1ea48c6df0 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,20 @@ +UNAME := $(shell uname) + +ifeq ($(UNAME),Darwin) + FUMOUNT=umount +else ifeq ($(UNAME),FreeBSD) + FUMOUNT=sudo umount +else + # Detect which version of the fusermount binary is available. + ifneq (, $(shell which fusermount3)) + FUMOUNT=fusermount3 -u + else + FUMOUNT=fusermount -u + endif +endif + image.bin: - dd if=/dev/zero of=image.bin bs=1M count=1024 + dd if=/dev/zero of=image.bin bs=1048576 count=1024 cargo build --release --bin redoxfs-mkfs target/release/redoxfs-mkfs image.bin @@ -10,12 +25,12 @@ mount: image.bin FORCE unmount: FORCE sync - -fusermount -u image + -${FUMOUNT} image rm -rf image clean: FORCE sync - -fusermount -u image + -${FUMOUNT} image rm -rf image image.bin cargo clean diff --git a/src/lib.rs b/src/lib.rs index 03deee8a9f9f303b6ed41391ada827f4ca74d787..3e8b0f385a7341146eded7af08d35fdad4ecfc15 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,6 +27,7 @@ pub use self::mount::mount; pub use self::node::{Node, NodeLevel}; pub use self::transaction::Transaction; pub use self::tree::{Tree, TreeData, TreeList, TreePtr}; +pub use self::unmount::unmount_path; mod allocator; #[cfg(feature = "std")] @@ -42,6 +43,8 @@ mod mount; mod node; mod transaction; mod tree; +#[cfg(feature = "std")] +mod unmount; #[cfg(all(feature = "std", test))] mod tests; diff --git a/src/tests.rs b/src/tests.rs index eff15368a1ee3598c9e92a68f828a5ecefca98d5..2fd0ca619e32bc99944312ba870a77fa2f468d5b 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -3,7 +3,7 @@ use std::path::Path; use std::process::Command; use std::{fs, sync, thread, time}; -use crate::{DiskSparse, FileSystem}; +use crate::{unmount_path, DiskSparse, FileSystem}; fn with_redoxfs<T, F>(callback: F) -> T where @@ -43,17 +43,7 @@ where panic!("sync failed"); } - let status_res = if cfg!(target_os = "linux") { - Command::new("fusermount") - .arg("-u") - .arg(mount_path) - .status() - } else { - Command::new("umount").arg(mount_path).status() - }; - - let status = dbg!(status_res).unwrap(); - if !status.success() { + if !unmount_path(mount_path).is_ok() { panic!("umount failed"); } } diff --git a/src/unmount.rs b/src/unmount.rs new file mode 100644 index 0000000000000000000000000000000000000000..2461a627bcb06ffe5e407105b14bc506af741cbb --- /dev/null +++ b/src/unmount.rs @@ -0,0 +1,53 @@ +use failure::Error; + +use std::{ + fs, + io::{self}, + process::{Command, ExitStatus}, +}; + +fn unmount_linux_path(mount_path: &str) -> io::Result<ExitStatus> { + // Different distributions can have various fusermount binaries. Try + // them all. + let commands = ["fusermount", "fusermount3"]; + + for command in commands { + let status = Command::new(command).arg("-u").arg(mount_path).status(); + if status.is_ok() { + return status; + } + if let Err(ref e) = status { + if e.kind() == io::ErrorKind::NotFound { + continue; + } + } + } + + // Unmounting failed since no suitable command was found + Err(std::io::Error::new( + io::ErrorKind::NotFound, + format!( + "Unable to locate any fusermount binaries. Tried {:?}. Is fuse installed?", + commands + ), + )) +} + +pub fn unmount_path(mount_path: &str) -> Result<(), Error> { + if cfg!(target_os = "redox") { + fs::remove_file(format!(":{}", mount_path))? + } else { + let status_res = if cfg!(target_os = "linux") { + unmount_linux_path(mount_path) + } else { + Command::new("umount").arg(mount_path).status() + }; + + let status = status_res?; + if !status.success() { + return Err(io::Error::new(io::ErrorKind::Other, "redoxfs umount failed").into()); + } + } + + Ok(()) +} diff --git a/test.sh b/test.sh index e6ddec998d91229f88230dcc697c2d4316fd3e14..d75b3254d57b29e6d90d9e44483b6c7e60f882da 100755 --- a/test.sh +++ b/test.sh @@ -8,6 +8,7 @@ export RUST_LOG=info function cleanup { sync fusermount -u image || true + fusermount3 -u image || true } trap 'cleanup' ERR