Skip to content

Commit 3b13c25

Browse files
committed
unmount disks on macos before write
1 parent ebe7f44 commit 3b13c25

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

src/writer_process/ipc.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ pub enum ErrorType {
4949
VerificationFailed,
5050
UnexpectedTermination,
5151
UnknownChildProcError(String),
52+
FailedToUnmount { message: String, exit_code: i32 },
5253
}
5354

5455
impl From<std::io::Error> for ErrorType {
@@ -75,6 +76,10 @@ impl Display for ErrorType {
7576
ErrorType::UnknownChildProcError(err) => {
7677
write!(f, "Unknown error occurred in child process: {err}")
7778
}
79+
ErrorType::FailedToUnmount { message, exit_code } => write!(
80+
f,
81+
"Failed to unmount disk (exit code {exit_code})\n{message}"
82+
),
7883
}
7984
}
8085
}

src/writer_process/mod.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33
//! IT IS NOT TO BE USED DIRECTLY BY THE USER! ITS API HAS NO STABILITY GUARANTEES!
44
55
use std::fs::OpenOptions;
6+
use std::os::unix::process::ExitStatusExt;
7+
use std::process::{Command, Stdio};
68
use std::{
79
fs::File,
810
io::{self, Read, Seek, Write},
911
};
1012

1113
use aligned_vec::avec_rt;
1214
use interprocess::local_socket::{prelude::*, GenericFilePath};
13-
use tracing::info;
15+
use tracing::{debug, info};
1416
use tracing_unwrap::ResultExt;
1517

1618
use crate::childproc_common::child_init;
@@ -60,6 +62,36 @@ pub fn main() {
6062
}
6163

6264
fn run(mut tx: impl FnMut(StatusMessage), args: &WriterProcessConfig) -> Result<(), ErrorType> {
65+
if cfg!(target_os = "macos") {
66+
let mut command = Command::new("diskutil");
67+
command
68+
.arg("unmountdisk")
69+
.arg(&args.dest)
70+
.stdin(Stdio::null())
71+
.stdout(Stdio::piped())
72+
.stderr(Stdio::piped());
73+
74+
info!(?command, "spawning process to unmount disk");
75+
let mut child = command.spawn()?;
76+
debug!("successfully ran diskutil, waiting on child process");
77+
78+
let exit = child.wait()?;
79+
let mut stderr = String::new();
80+
child.stderr.take().unwrap().read_to_string(&mut stderr)?;
81+
let mut stdout = String::new();
82+
child.stdout.take().unwrap().read_to_string(&mut stdout)?;
83+
84+
debug!(?exit, ?stderr, "child exited");
85+
86+
let exit_code = exit.into_raw();
87+
if !exit.success() {
88+
return Err(ErrorType::FailedToUnmount {
89+
message: format!("stderr: {stderr}\nstdout: {stdout}"),
90+
exit_code,
91+
});
92+
}
93+
}
94+
6395
info!("Opening file {}", args.src.to_string_lossy());
6496
let mut file = File::open(&args.src).unwrap_or_log();
6597
let size = file.seek(io::SeekFrom::End(0))?;

0 commit comments

Comments
 (0)