Line data Source code
1 : use anyhow::{anyhow, Context};
2 : use tracing::warn;
3 :
4 : pub const RESIZE_SWAP_BIN: &str = "/neonvm/bin/resize-swap";
5 :
6 0 : pub fn resize_swap(size_bytes: u64) -> anyhow::Result<()> {
7 0 : // run `/neonvm/bin/resize-swap --once {size_bytes}`
8 0 : //
9 0 : // Passing '--once' causes resize-swap to delete itself after successful completion, which
10 0 : // means that if compute_ctl restarts later, we won't end up calling 'swapoff' while
11 0 : // postgres is running.
12 0 : //
13 0 : // NOTE: resize-swap is not very clever. If present, --once MUST be the first arg.
14 0 : let child_result = std::process::Command::new("/usr/bin/sudo")
15 0 : .arg(RESIZE_SWAP_BIN)
16 0 : .arg("--once")
17 0 : .arg(size_bytes.to_string())
18 0 : .spawn();
19 :
20 0 : if matches!(&child_result, Err(e) if e.kind() == std::io::ErrorKind::NotFound) {
21 0 : warn!("ignoring \"not found\" error from resize-swap to avoid swapoff while compute is running");
22 0 : return Ok(());
23 0 : }
24 0 :
25 0 : child_result
26 0 : .context("spawn() failed")
27 0 : .and_then(|mut child| child.wait().context("wait() failed"))
28 0 : .and_then(|status| match status.success() {
29 0 : true => Ok(()),
30 0 : false => Err(anyhow!("process exited with {status}")),
31 0 : })
32 0 : // wrap any prior error with the overall context that we couldn't run the command
33 0 : .with_context(|| {
34 0 : format!("could not run `/usr/bin/sudo {RESIZE_SWAP_BIN} --once {size_bytes}`")
35 0 : })
36 0 : }
|