@@ -14,51 +14,71 @@ See the License for the specific language governing permissions and
1414limitations under the License.
1515*/
1616
17- use std:: ffi:: CString ;
18- use std:: os:: fd:: RawFd ;
19- use std:: process:: exit;
17+ use std:: {
18+ ffi:: CString ,
19+ os:: fd:: { AsRawFd , FromRawFd , OwnedFd , RawFd } ,
20+ path:: Path ,
21+ process:: exit,
22+ str:: FromStr ,
23+ } ;
2024
2125use anyhow:: anyhow;
26+ use clap:: Parser ;
2227use containerd_shim:: asynchronous:: monitor:: monitor_notify_by_pid;
2328use futures:: StreamExt ;
24- use log:: { debug, error, warn} ;
25- use nix:: fcntl:: { fcntl, FcntlArg , FdFlag , OFlag } ;
26- use nix:: sched:: { setns, unshare, CloneFlags } ;
27- use nix:: sys:: signal:: { sigaction, SaFlags , SigAction , SigHandler , SigSet , SIGCHLD } ;
28- use nix:: sys:: stat:: Mode ;
29- use nix:: unistd:: { close, fork, pause, pipe, read, write, ForkResult } ;
29+ use log:: { debug, error, warn, LevelFilter } ;
3030use nix:: {
3131 errno:: Errno ,
32+ fcntl:: { fcntl, FcntlArg , FdFlag , OFlag } ,
3233 libc,
34+ sched:: { setns, unshare, CloneFlags } ,
3335 sys:: {
36+ signal:: { sigaction, SaFlags , SigAction , SigHandler , SigSet , SIGCHLD } ,
37+ stat:: Mode ,
3438 wait,
3539 wait:: { WaitPidFlag , WaitStatus } ,
3640 } ,
37- unistd:: Pid ,
41+ unistd:: { fork , pause , pipe , read , write , ForkResult , Pid } ,
3842} ;
3943use prctl:: PrctlMM ;
4044use signal_hook_tokio:: Signals ;
4145use uuid:: Uuid ;
4246
43- use crate :: sandbox:: { RuncSandboxer , SandboxParent } ;
44- use crate :: task:: fork_task_server;
47+ use crate :: {
48+ sandbox:: { RuncSandboxer , SandboxParent } ,
49+ task:: fork_task_server,
50+ } ;
4551
52+ mod args;
4653mod common;
4754mod runc;
4855mod sandbox;
4956mod task;
57+ mod version;
5058
5159fn main ( ) {
52- env_logger:: builder ( ) . format_timestamp_micros ( ) . init ( ) ;
60+ let args = args:: Args :: parse ( ) ;
61+ if args. version {
62+ version:: print_version_info ( ) ;
63+ return ;
64+ }
65+
66+ // Update args log level if it not presents args but in config.
67+ let log_level =
68+ LevelFilter :: from_str ( & args. log_level . unwrap_or_default ( ) ) . unwrap_or ( LevelFilter :: Info ) ;
69+ env_logger:: Builder :: from_default_env ( )
70+ . format_timestamp_micros ( )
71+ . filter_module ( "containerd_sandbox" , log_level)
72+ . filter_module ( "runc_sandboxer" , log_level)
73+ . init ( ) ;
74+
5375 let sandbox_parent = fork_sandbox_parent ( ) . unwrap ( ) ;
54- let os_args: Vec < _ > = std:: env:: args_os ( ) . collect ( ) ;
55- // TODO avoid parse args multiple times
56- let flags = containerd_sandbox:: args:: parse ( & os_args[ 1 ..] ) . unwrap ( ) ;
57- let task_socket = format ! ( "{}/task-{}.sock" , flags. dir, Uuid :: new_v4( ) ) ;
58- fork_task_server ( & task_socket, & flags. dir ) . unwrap ( ) ;
76+
77+ let task_socket = format ! ( "{}/task-{}.sock" , & args. dir, Uuid :: new_v4( ) ) ;
78+ fork_task_server ( & task_socket, & args. dir ) . unwrap ( ) ;
5979 let runtime = tokio:: runtime:: Runtime :: new ( ) . unwrap ( ) ;
6080 runtime. block_on ( async move {
61- start_sandboxer ( sandbox_parent, task_socket, flags . dir )
81+ start_sandboxer ( sandbox_parent, task_socket, & args . listen , & args . dir )
6282 . await
6383 . unwrap ( ) ;
6484 } ) ;
@@ -75,12 +95,12 @@ fn fork_sandbox_parent() -> Result<SandboxParent, anyhow::Error> {
7595 match unsafe { fork ( ) . map_err ( |e| anyhow ! ( "failed to fork sandbox parent {}" , e) ) ? } {
7696 ForkResult :: Parent { child } => {
7797 debug ! ( "forked process {} for the sandbox parent" , child) ;
78- close ( reqr) . unwrap_or_default ( ) ;
79- close ( respw) . unwrap_or_default ( ) ;
98+ drop ( reqr) ;
99+ drop ( respw) ;
80100 }
81101 ForkResult :: Child => {
82- close ( reqw) . unwrap_or_default ( ) ;
83- close ( respr) . unwrap_or_default ( ) ;
102+ drop ( reqw) ;
103+ drop ( respr) ;
84104 prctl:: set_child_subreaper ( true ) . unwrap ( ) ;
85105 let comm = "[sandbox-parent]" ;
86106 let comm_cstr = CString :: new ( comm) . unwrap ( ) ;
@@ -95,7 +115,7 @@ fn fork_sandbox_parent() -> Result<SandboxParent, anyhow::Error> {
95115 sigaction ( SIGCHLD , & sig_action) . unwrap ( ) ;
96116 }
97117 loop {
98- let buffer = read_count ( reqr, 512 ) . unwrap ( ) ;
118+ let buffer = read_count ( reqr. as_raw_fd ( ) , 512 ) . unwrap ( ) ;
99119 let id = String :: from_utf8_lossy ( & buffer[ 0 ..64 ] ) . to_string ( ) ;
100120 let mut zero_index = 64 ;
101121 for ( i, & b) in buffer. iter ( ) . enumerate ( ) . take ( 512 ) . skip ( 64 ) {
@@ -106,12 +126,12 @@ fn fork_sandbox_parent() -> Result<SandboxParent, anyhow::Error> {
106126 }
107127 let netns = String :: from_utf8_lossy ( & buffer[ 64 ..zero_index] ) . to_string ( ) ;
108128 let sandbox_pid = fork_sandbox ( & id, & netns) . unwrap ( ) ;
109- write_all ( respw, sandbox_pid. to_le_bytes ( ) . as_slice ( ) ) . unwrap ( ) ;
129+ write_all ( & respw, sandbox_pid. to_le_bytes ( ) . as_slice ( ) ) . unwrap ( ) ;
110130 }
111131 }
112132 }
113- fcntl ( reqw, FcntlArg :: F_SETFD ( FdFlag :: FD_CLOEXEC ) ) . unwrap_or_default ( ) ;
114- fcntl ( respr, FcntlArg :: F_SETFD ( FdFlag :: FD_CLOEXEC ) ) . unwrap_or_default ( ) ;
133+ fcntl ( reqw. as_raw_fd ( ) , FcntlArg :: F_SETFD ( FdFlag :: FD_CLOEXEC ) ) . unwrap_or_default ( ) ;
134+ fcntl ( respr. as_raw_fd ( ) , FcntlArg :: F_SETFD ( FdFlag :: FD_CLOEXEC ) ) . unwrap_or_default ( ) ;
115135 Ok ( SandboxParent :: new ( reqw, respr) )
116136}
117137
@@ -136,7 +156,7 @@ pub fn read_count(fd: RawFd, count: usize) -> Result<Vec<u8>, anyhow::Error> {
136156 }
137157}
138158
139- pub fn write_all ( fd : RawFd , buf : & [ u8 ] ) -> Result < ( ) , anyhow:: Error > {
159+ pub fn write_all ( fd : & OwnedFd , buf : & [ u8 ] ) -> Result < ( ) , anyhow:: Error > {
140160 let mut idx = 0 ;
141161 let count = buf. len ( ) ;
142162 loop {
@@ -162,21 +182,21 @@ fn fork_sandbox(id: &str, netns: &str) -> Result<i32, anyhow::Error> {
162182 match unsafe { fork ( ) . map_err ( |e| anyhow ! ( "failed to fork sandbox {}" , e) ) ? } {
163183 ForkResult :: Parent { child } => {
164184 debug ! ( "forked process {} for the sandbox {}" , child, id) ;
165- close ( w ) . unwrap_or_default ( ) ;
185+ drop ( w ) ;
166186 let mut resp = [ 0u8 ; 4 ] ;
167- let r = read_count ( r, 4 ) ?;
187+ let r = read_count ( r. as_raw_fd ( ) , 4 ) ?;
168188 resp[ ..] . copy_from_slice ( r. as_slice ( ) ) ;
169189 let pid = i32:: from_le_bytes ( resp) ;
170190 Ok ( pid)
171191 }
172192 ForkResult :: Child => {
173- close ( r ) . unwrap_or_default ( ) ;
193+ drop ( r ) ;
174194 unshare ( CloneFlags :: CLONE_NEWIPC | CloneFlags :: CLONE_NEWUTS | CloneFlags :: CLONE_NEWPID )
175195 . unwrap ( ) ;
176196 match unsafe { fork ( ) . unwrap ( ) } {
177197 ForkResult :: Parent { child } => {
178198 debug ! ( "forked process {} for the sandbox {}" , child, id) ;
179- write_all ( w, child. as_raw ( ) . to_le_bytes ( ) . as_slice ( ) ) . unwrap ( ) ;
199+ write_all ( & w, child. as_raw ( ) . to_le_bytes ( ) . as_slice ( ) ) . unwrap ( ) ;
180200 exit ( 0 ) ;
181201 }
182202 ForkResult :: Child => {
@@ -186,7 +206,8 @@ fn fork_sandbox(id: &str, netns: &str) -> Result<i32, anyhow::Error> {
186206 set_process_comm ( addr as u64 , comm_cstr. as_bytes_with_nul ( ) . len ( ) as u64 ) ;
187207 if !netns. is_empty ( ) {
188208 let netns_fd =
189- nix:: fcntl:: open ( netns, OFlag :: O_CLOEXEC , Mode :: empty ( ) ) . unwrap ( ) ;
209+ safe_open_file ( Path :: new ( & netns) , OFlag :: O_CLOEXEC , Mode :: empty ( ) )
210+ . unwrap ( ) ;
190211 setns ( netns_fd, CloneFlags :: CLONE_NEWNET ) . unwrap ( ) ;
191212 }
192213 loop {
@@ -198,6 +219,16 @@ fn fork_sandbox(id: &str, netns: &str) -> Result<i32, anyhow::Error> {
198219 }
199220}
200221
222+ pub fn safe_open_file < P : ?Sized + nix:: NixPath > (
223+ path : & P ,
224+ oflag : OFlag ,
225+ mode : Mode ,
226+ ) -> Result < OwnedFd , nix:: Error > {
227+ let fd = nix:: fcntl:: open ( path, oflag, mode) ?;
228+ // SAFETY: contruct a OwnedFd from RawFd, close fd when OwnedFd drop
229+ Ok ( unsafe { OwnedFd :: from_raw_fd ( fd) } )
230+ }
231+
201232fn set_process_comm ( addr : u64 , len : u64 ) {
202233 if prctl:: set_mm ( PrctlMM :: PR_SET_MM_ARG_START , addr) . is_err ( ) {
203234 prctl:: set_mm ( PrctlMM :: PR_SET_MM_ARG_END , addr + len) . unwrap ( ) ;
@@ -230,12 +261,13 @@ extern "C" fn sandbox_parent_handle_signals(_: libc::c_int) {
230261async fn start_sandboxer (
231262 sandbox_parent : SandboxParent ,
232263 task_socket : String ,
233- dir : String ,
264+ listen : & str ,
265+ dir : & str ,
234266) -> anyhow:: Result < ( ) > {
235267 let task_address = format ! ( "unix://{}" , task_socket) ;
236268 let sandboxer = RuncSandboxer :: new ( sandbox_parent, & task_address) . await ?;
237- sandboxer. recover ( & dir) . await ?;
238- containerd_sandbox:: run ( "runc-sandboxer" , sandboxer) . await ?;
269+ sandboxer. recover ( dir) . await ?;
270+ containerd_sandbox:: run ( "kuasar- runc-sandboxer" , listen , dir , sandboxer) . await ?;
239271 Ok ( ( ) )
240272}
241273
0 commit comments