Unmount apfs volumes before deleting them (#662)
This commit is contained in:
parent
d01e1b820c
commit
25ed45fc1b
|
@ -1,3 +1,4 @@
|
|||
use std::io::Cursor;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use tokio::process::Command;
|
||||
|
@ -7,7 +8,7 @@ use crate::action::{ActionError, ActionTag, StatefulAction};
|
|||
use crate::execute_command;
|
||||
|
||||
use crate::action::{Action, ActionDescription};
|
||||
use crate::os::darwin::DiskUtilApfsListOutput;
|
||||
use crate::os::darwin::{DiskUtilApfsListOutput, DiskUtilInfoOutput};
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct CreateApfsVolume {
|
||||
|
@ -122,6 +123,38 @@ impl Action for CreateApfsVolume {
|
|||
|
||||
#[tracing::instrument(level = "debug", skip_all)]
|
||||
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||
let currently_mounted = {
|
||||
let buf = execute_command(
|
||||
Command::new("/usr/sbin/diskutil")
|
||||
.process_group(0)
|
||||
.args(["info", "-plist"])
|
||||
.arg(&self.name)
|
||||
.stdin(std::process::Stdio::null()),
|
||||
)
|
||||
.await
|
||||
.map_err(Self::error)?
|
||||
.stdout;
|
||||
let the_plist: DiskUtilInfoOutput =
|
||||
plist::from_reader(Cursor::new(buf)).map_err(Self::error)?;
|
||||
|
||||
the_plist.mount_point.is_some()
|
||||
};
|
||||
|
||||
// Unmounts the volume before attempting to remove it, avoiding 'in use' errors
|
||||
// https://github.com/DeterminateSystems/nix-installer/issues/647
|
||||
if !currently_mounted {
|
||||
execute_command(
|
||||
Command::new("/usr/sbin/diskutil")
|
||||
.process_group(0)
|
||||
.args(["unmount", "force", &self.name])
|
||||
.stdin(std::process::Stdio::null()),
|
||||
)
|
||||
.await
|
||||
.map_err(Self::error)?;
|
||||
} else {
|
||||
tracing::debug!("Volume was already unmounted, can skip unmounting")
|
||||
}
|
||||
|
||||
execute_command(
|
||||
Command::new("/usr/sbin/diskutil")
|
||||
.process_group(0)
|
||||
|
|
Loading…
Reference in a new issue