Implement resizing of zpool
This commit is contained in:
parent
f410517ffa
commit
f0725c503f
10 changed files with 234 additions and 17 deletions
|
@ -308,21 +308,67 @@ impl Command {
|
|||
cmd.status()
|
||||
.with_context(|| format!("Could not spawn command: {}", command_to_string(self)))
|
||||
}
|
||||
|
||||
pub fn spawn_into_parts(&mut self) -> anyhow::Result<(String, String, ExitStatus)> {
|
||||
let mut cmd = self.as_command();
|
||||
let mut child = cmd
|
||||
.stderr(self.stderr.as_std_stdio())
|
||||
.stdin(self.stdin.as_std_stdio())
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.with_context(|| format!("Could not spawn command: {}", command_to_string(self)))?;
|
||||
let mut stdin = Stdin::Null;
|
||||
std::mem::swap(&mut self.stdin, &mut stdin);
|
||||
let join_handle = if let Some(data) = stdin.into_data() {
|
||||
let mut stdin_pipe = child.stdin.take().expect("Child has no stdin");
|
||||
Some(std::thread::spawn(move || {
|
||||
stdin_pipe
|
||||
.write_all(data.as_slice())
|
||||
.expect("Could not write to child");
|
||||
}))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let output: Result<(Vec<u8>, Vec<u8>, ExitStatus), anyhow::Error> =
|
||||
wait_with_output_into_parts(child, || command_to_string(self));
|
||||
if let Some(join_handle) = join_handle {
|
||||
join_handle
|
||||
.join()
|
||||
.map_err(|e| anyhow::format_err!("Thread sending stdin panicked: {e:?}"))?;
|
||||
}
|
||||
let (stdout, stderr, status) = output?;
|
||||
let stdout =
|
||||
String::from_utf8(stdout).context("Could not read stdout of command as UTF-8")?;
|
||||
let stderr =
|
||||
String::from_utf8(stderr).context("Could not read stderr of command as UTF-8")?;
|
||||
Ok((stdout, stderr, status))
|
||||
}
|
||||
}
|
||||
|
||||
fn wait_with_output(child: Child, cmd_str: impl Fn() -> String) -> anyhow::Result<Vec<u8>> {
|
||||
let output = child
|
||||
.wait_with_output()
|
||||
.with_context(|| format!("Could not wait for output of commnad: {}", cmd_str()))?;
|
||||
if !output.status.success() {
|
||||
fn wait_with_output(child: Child, cmd_str: impl Fn() -> String + Clone) -> anyhow::Result<Vec<u8>> {
|
||||
let (stdout, stderr, status) = wait_with_output_into_parts(child, cmd_str.clone())?;
|
||||
if !status.success() {
|
||||
return Err(anyhow::format_err!(
|
||||
"Command {}, exited unexpectedly: {:?}. With stderr: {}",
|
||||
cmd_str(),
|
||||
output.status,
|
||||
String::from_utf8_lossy(&output.stderr),
|
||||
status,
|
||||
String::from_utf8_lossy(&stderr),
|
||||
));
|
||||
}
|
||||
Ok(output.stdout)
|
||||
Ok(stdout)
|
||||
}
|
||||
|
||||
fn wait_with_output_into_parts(
|
||||
child: Child,
|
||||
cmd_str: impl Fn() -> String,
|
||||
) -> anyhow::Result<(Vec<u8>, Vec<u8>, ExitStatus)> {
|
||||
let output = child
|
||||
.wait_with_output()
|
||||
.with_context(|| format!("Could not wait for output of commnad: {}", cmd_str()))?;
|
||||
let status = output.status;
|
||||
let stdout = output.stdout;
|
||||
let stderr = output.stderr;
|
||||
Ok((stdout, stderr, status))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue