Skip to content

Commit ce466b7

Browse files
committed
muvm-guest: add virtual command for memory watermark sysctl
To remove the need for a sysctl binary. Signed-off-by: Val Packett <[email protected]>
1 parent edca74b commit ce466b7

File tree

2 files changed

+54
-35
lines changed

2 files changed

+54
-35
lines changed

crates/muvm/src/guest/server_worker.rs

Lines changed: 52 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use crate::utils::stdio::make_stdout_stderr;
3434
use crate::utils::tty::*;
3535

3636
pub enum ConnRequest {
37-
DropCaches,
37+
HandledByBuiltin,
3838
ExecuteCommand {
3939
command: PathBuf,
4040
child: Child,
@@ -83,7 +83,7 @@ impl Worker {
8383

8484
match handle_connection(stream).await {
8585
Ok(request) => match request {
86-
ConnRequest::DropCaches => {},
86+
ConnRequest::HandledByBuiltin => {},
8787
ConnRequest::ExecuteCommand {command, mut child, stop_pipe } => {
8888
self.child_set.spawn(async move { (command, child.wait().await, stop_pipe) });
8989
self.set_child_processes(self.child_set.len());
@@ -190,6 +190,46 @@ async fn read_request(stream: &mut BufStream<UnixStream>) -> Result<Launch> {
190190
}
191191
}
192192

193+
async fn write_to(
194+
mut stream: BufStream<UnixStream>,
195+
path: &'static std::ffi::CStr,
196+
data: &[u8],
197+
) -> Result<ConnRequest> {
198+
// SAFETY: `open` and `write` are async signal safe
199+
let code = unsafe {
200+
user::run_as_root(|| {
201+
let fd = nix::libc::open(path.as_ptr(), nix::libc::O_WRONLY);
202+
if fd < 0 {
203+
return 1;
204+
}
205+
let written = nix::libc::write(fd, data.as_ptr() as *const _, data.len()) as usize;
206+
if written == data.len() {
207+
0
208+
} else {
209+
2
210+
}
211+
})
212+
.context(format!("Failed to write to {}", path.to_str().unwrap()))?
213+
};
214+
match code {
215+
0 => {
216+
stream.write_all(b"OK").await.ok();
217+
stream.flush().await.ok();
218+
Ok(ConnRequest::HandledByBuiltin)
219+
},
220+
1 => Err(anyhow!(
221+
"Failed to open {} for writing",
222+
path.to_str().unwrap()
223+
)),
224+
2 => Err(anyhow!("Failed to write to {}", path.to_str().unwrap())),
225+
e => Err(anyhow!(
226+
"Unexpected return status when attempting to write to {}: {}",
227+
path.to_str().unwrap(),
228+
e
229+
)),
230+
}
231+
}
232+
193233
async fn handle_connection(mut stream: BufStream<UnixStream>) -> Result<ConnRequest> {
194234
let mut envs: HashMap<String, String> = env::vars().collect();
195235

@@ -204,38 +244,17 @@ async fn handle_connection(mut stream: BufStream<UnixStream>) -> Result<ConnRequ
204244
debug!(command:?, command_args:?, env:?; "received launch request");
205245

206246
if command == Path::new("/muvmdropcaches") {
207-
// SAFETY: everything below should be async signal safe
208-
let code = unsafe {
209-
user::run_as_root(|| {
210-
let fd = nix::libc::open(c"/proc/sys/vm/drop_caches".as_ptr(), nix::libc::O_WRONLY);
211-
if fd < 0 {
212-
return 1;
213-
}
214-
let data = b"1";
215-
let written = nix::libc::write(fd, data.as_ptr() as *const _, data.len()) as usize;
216-
if written == data.len() {
217-
0
218-
} else {
219-
2
220-
}
221-
})
222-
.context("Failed to drop caches")?
223-
};
224-
return match code {
225-
0 => {
226-
stream.write_all(b"OK").await.ok();
227-
stream.flush().await.ok();
228-
Ok(ConnRequest::DropCaches)
229-
},
230-
1 => Err(anyhow!(
231-
"Failed to open /proc/sys/vm/drop_caches for writing"
232-
)),
233-
2 => Err(anyhow!("Failed to write to /proc/sys/vm/drop_caches")),
234-
e => Err(anyhow!(
235-
"Unexpected return status when attempting to drop caches: {}",
236-
e
237-
)),
247+
return write_to(stream, c"/proc/sys/vm/drop_caches", b"1").await;
248+
} else if command == Path::new("/muvmwatermarkscalefactor") {
249+
let Some(data) = command_args.first() else {
250+
return Err(anyhow!("muvmwatermarkscalefactor: missing arg"));
238251
};
252+
return write_to(
253+
stream,
254+
c"/proc/sys/vm/watermark_scale_factor",
255+
data.as_bytes(),
256+
)
257+
.await;
239258
}
240259

241260
envs.extend(env);

crates/muvm/src/monitor.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ fn set_guest_pressure(pressure: GuestPressure) -> Result<()> {
4949
let wsf: u32 = pressure.into();
5050
debug!("setting watermark_scale_factor to {wsf}");
5151

52-
let command = PathBuf::from(std::option_env!("MUVM_SYSCTL_PATH").unwrap_or("/sbin/sysctl"));
53-
let command_args = vec![format!("vm.watermark_scale_factor={}", wsf)];
52+
let command = PathBuf::from("/muvmwatermarkscalefactor");
53+
let command_args = vec![format!("{}", wsf)];
5454
let env = HashMap::new();
5555
request_launch(command, command_args, env, 0, false, true)
5656
}

0 commit comments

Comments
 (0)