@@ -34,7 +34,7 @@ use crate::utils::stdio::make_stdout_stderr;
3434use crate :: utils:: tty:: * ;
3535
3636pub 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+ . with_context ( || format ! ( "Failed to write to {path:?}" ) ) ?
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+
193233async 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) ;
0 commit comments