@@ -2,30 +2,53 @@ use crate::Error;
2
2
use crate :: spec:: PosixSpec ;
3
3
use crate :: spec:: FromSpec ;
4
4
use failure:: ResultExt ;
5
- use std:: path:: PathBuf ;
5
+ use nix:: sched;
6
+ use nix:: sched:: CloneFlags ;
7
+ use phf:: phf_map;
6
8
use std:: collections:: HashMap ;
9
+ use std:: fs:: File ;
10
+ use std:: os:: unix:: io:: AsRawFd ;
11
+ use std:: path:: PathBuf ;
7
12
8
- static TYPES : [ & str ; 7 ] = [
9
- "pid" ,
10
- "uts" ,
11
- "ipc" ,
12
- "user" ,
13
- "mount" ,
14
- "cgroup" ,
15
- "network" ,
16
- ] ;
13
+ static NS_TYPES : phf :: Map < & ' static str , CloneFlags > = phf_map ! {
14
+ "pid" => CloneFlags :: CLONE_NEWPID ,
15
+ "uts" => CloneFlags :: CLONE_NEWUTS ,
16
+ "ipc" => CloneFlags :: CLONE_NEWIPC ,
17
+ "user" => CloneFlags :: CLONE_NEWUSER ,
18
+ "mount" => CloneFlags :: CLONE_NEWNS ,
19
+ "cgroup" => CloneFlags :: CLONE_NEWCGROUP ,
20
+ "network" => CloneFlags :: CLONE_NEWNET ,
21
+ } ;
17
22
18
23
pub struct Namespaces {
19
24
namespaces : HashMap < String , Option < PathBuf > > ,
20
25
}
21
26
22
27
impl Namespaces {
28
+ pub fn enter ( & self ) -> Result < ( ) , Error > {
29
+ let mut flags = CloneFlags :: empty ( ) ;
30
+ for ( kind, path) in & self . namespaces {
31
+ let flag = NS_TYPES [ kind. as_str ( ) ] ;
32
+ if path. is_none ( ) {
33
+ flags. insert ( flag) ;
34
+ } else {
35
+ let file = File :: open ( path. as_ref ( ) . unwrap ( ) ) . context ( format ! ( "{:?}" , & path) ) ?;
36
+ let fd = file. as_raw_fd ( ) ;
37
+ sched:: setns ( fd, flag) . context ( format ! ( "{:?}: {:?}" , & kind, & path) ) ?;
38
+ }
39
+ }
40
+ if !flags. is_empty ( ) {
41
+ sched:: unshare ( flags) . context ( format ! ( "{:?}" , flags) ) ?;
42
+ }
43
+ Ok ( ( ) )
44
+ }
45
+
23
46
fn empty ( ) -> Namespaces {
24
47
Namespaces { namespaces : HashMap :: new ( ) }
25
48
}
26
49
27
50
fn insert ( & mut self , ns_type : String , path : Option < PathBuf > ) -> Result < ( ) , Error > {
28
- if !TYPES . contains ( & ns_type. as_str ( ) ) {
51
+ if !NS_TYPES . contains_key ( ns_type. as_str ( ) ) {
29
52
Err ( Error :: from ( "invalid namespace type" . to_string ( ) ) ) . context ( ns_type. clone ( ) ) ?;
30
53
}
31
54
if self . namespaces . contains_key ( & ns_type) {
0 commit comments