diff --git a/src/error.rs b/src/error.rs index 27e88c4..4f413e9 100644 --- a/src/error.rs +++ b/src/error.rs @@ -55,6 +55,9 @@ pub enum ErrorKind { #[fail(display = "Error caused by the interactive mode")] Interactive, + + #[fail(display = "Failed umounting filesystems")] + UmountFailure, } impl Fail for Error { diff --git a/src/main.rs b/src/main.rs index f7ceacd..3d04011 100644 --- a/src/main.rs +++ b/src/main.rs @@ -210,6 +210,10 @@ fn create(command: CreateCommand) -> Result<(), Error> { } info!("Unmounting filesystems"); + mount_stack.umount()?; + + info!("Installation succeeded. It is now safe to unplug your device."); + Ok(()) } diff --git a/src/mountstack.rs b/src/mountstack.rs index 386c9a4..61137ae 100644 --- a/src/mountstack.rs +++ b/src/mountstack.rs @@ -1,3 +1,5 @@ +use super::error::{Error, ErrorKind}; +use failure::Fail; use log::{debug, warn}; use nix; use nix::mount::{mount, umount, MsFlags}; @@ -48,15 +50,24 @@ impl<'a> MountStack<'a> { self.targets.push(target); Ok(()) } -} -impl<'a> Drop for MountStack<'a> { - fn drop(&mut self) { + pub fn umount(&mut self) -> Result<(), Error> { + let mut result = Ok(()); + while let Some(target) = self.targets.pop() { debug!("Unmounting {}", target.display()); - if !umount(target).is_ok() { - warn!("Unable to umount {}", target.display()); + if let Err(e) = umount(target) { + warn!("Unable to umount {}: {}", target.display(), e); + result = Err(Error::from(e.context(ErrorKind::UmountFailure))); }; } + + result + } +} + +impl<'a> Drop for MountStack<'a> { + fn drop(&mut self) { + self.umount().ok(); } }