From 8b0d9ef16a4d2378c852220d214dc01d06529152 Mon Sep 17 00:00:00 2001 From: Roey Darwish Dror Date: Sun, 4 Nov 2018 16:05:11 +0200 Subject: [PATCH] Perform mount using API (fix #10 fix #6) --- Cargo.lock | 20 ++++++++++++++++ Cargo.toml | 1 + src/main.rs | 37 +++++++++++++++-------------- src/mountstack.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 100 insertions(+), 18 deletions(-) create mode 100644 src/mountstack.rs diff --git a/Cargo.lock b/Cargo.lock index 01ecf05..c6ac3ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,6 +4,7 @@ version = "0.1.0" dependencies = [ "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "simplelog 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -148,6 +149,18 @@ dependencies = [ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "nix" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "num-integer" version = "0.1.39" @@ -348,6 +361,11 @@ name = "vec_map" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "which" version = "2.0.0" @@ -394,6 +412,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" +"checksum nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17" "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" "checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee" @@ -419,6 +438,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum which 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49c4f580e93079b70ac522e7bdebbe1568c8afa7d8d05ee534ee737ca37d2f51" "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" diff --git a/Cargo.toml b/Cargo.toml index ab1e671..afd1bb3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,4 @@ log = "0.4.6" structopt = "0.2.12" simplelog = "0.5.3" tempfile = "3.0.4" +nix = "0.11.0" diff --git a/src/main.rs b/src/main.rs index 977c725..0810999 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,19 @@ #[macro_use] extern crate log; extern crate failure; +extern crate nix; extern crate simplelog; extern crate structopt; extern crate tempfile; extern crate which; mod error; +mod mountstack; mod tool; use error::*; use failure::{Fail, ResultExt}; +use mountstack::{Filesystem, MountStack}; use simplelog::*; use std::fs; use std::path::PathBuf; @@ -90,10 +93,9 @@ fn create(disk: PathBuf) -> Result<(), Error> { let pacstrap = Tool::find("pacstrap")?; let arch_chroot = Tool::find("arch-chroot")?; let genfstab = Tool::find("genfstab")?; - let mount = Tool::find("mount")?; - let umount = Tool::find("umount")?; let mkfat = Tool::find("mkfs.fat")?; let mkbtrfs = Tool::find("mkfs.btrfs")?; + let mut mount_stack = MountStack::new(); if !(disk.starts_with("/dev/disk/by-id") && (disk @@ -137,20 +139,24 @@ fn create(disk: PathBuf) -> Result<(), Error> { .run(ErrorKind::Creation)?; info!("Mounting filesystems to {}", mount_point.path().display()); - mount - .execute() - .arg(format!("{}-part3", disk.display())) - .arg(mount_point.path()) - .run(ErrorKind::Creation)?; + mount_stack + .mount( + &PathBuf::from(format!("{}-part3", disk.display())), + &mount_point.path(), + Filesystem::Btrfs, + Some("compress=zstd"), + ).context(ErrorKind::Creation)?; let boot_point = mount_point.path().join("boot"); fs::create_dir(&boot_point).context(ErrorKind::Creation)?; - mount - .execute() - .arg(format!("{}-part2", disk.display())) - .arg(&boot_point) - .run(ErrorKind::Creation)?; + mount_stack + .mount( + &PathBuf::from(format!("{}-part2", disk.display())), + &boot_point, + Filesystem::Vfat, + None, + ).context(ErrorKind::Creation)?; info!("Bootstrapping system"); pacstrap @@ -199,12 +205,7 @@ fn create(disk: PathBuf) -> Result<(), Error> { .run(ErrorKind::Creation)?; info!("Unmounting filesystems"); - umount - .execute() - .arg(boot_point) - .arg(mount_point.path()) - .run(ErrorKind::Creation)?; - + drop(mount_stack); sync.execute().run(ErrorKind::Creation)?; Ok(()) diff --git a/src/mountstack.rs b/src/mountstack.rs new file mode 100644 index 0000000..edc1e94 --- /dev/null +++ b/src/mountstack.rs @@ -0,0 +1,60 @@ +use nix; +use nix::mount::{mount, umount, MsFlags}; +use std::path::{Path, PathBuf}; + +#[derive(Debug)] +pub enum Filesystem { + Btrfs, + Vfat, +} + +impl Filesystem { + fn to_type(self) -> &'static str { + match self { + Filesystem::Btrfs => "btrfs", + Filesystem::Vfat => "vfat", + } + } +} + +pub struct MountStack { + targets: Vec, +} + +impl MountStack { + pub fn new() -> Self { + MountStack { + targets: Vec::new(), + } + } + + #[must_use] + pub fn mount( + &mut self, + source: &Path, + target: &Path, + filesystem: Filesystem, + options: Option<&str>, + ) -> nix::Result<()> { + debug!("Mounting {:?} ({:?}) to {:?}", source, filesystem, target); + mount( + Some(source), + target, + Some(filesystem.to_type()), + MsFlags::empty(), + options, + )?; + self.targets.push(target.to_owned()); + Ok(()) + } +} + +impl Drop for MountStack { + fn drop(&mut self) { + while let Some(target) = self.targets.pop() { + if !umount(&target).is_ok() { + warn!("Unable to mount {}", target.display()); + }; + } + } +}