Unmount apfs volumes before deleting them (#662)

This commit is contained in:
Ana Hobden 2023-10-03 10:07:17 -07:00 committed by GitHub
parent d01e1b820c
commit 25ed45fc1b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,3 +1,4 @@
use std::io::Cursor;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use tokio::process::Command; use tokio::process::Command;
@ -7,7 +8,7 @@ use crate::action::{ActionError, ActionTag, StatefulAction};
use crate::execute_command; use crate::execute_command;
use crate::action::{Action, ActionDescription}; use crate::action::{Action, ActionDescription};
use crate::os::darwin::DiskUtilApfsListOutput; use crate::os::darwin::{DiskUtilApfsListOutput, DiskUtilInfoOutput};
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)] #[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
pub struct CreateApfsVolume { pub struct CreateApfsVolume {
@ -122,6 +123,38 @@ impl Action for CreateApfsVolume {
#[tracing::instrument(level = "debug", skip_all)] #[tracing::instrument(level = "debug", skip_all)]
async fn revert(&mut self) -> Result<(), ActionError> { 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( execute_command(
Command::new("/usr/sbin/diskutil") Command::new("/usr/sbin/diskutil")
.process_group(0) .process_group(0)