2017-08-08 14 views
0

代碼如下,我想如果我用syscall.CLONE_NEWNS啓動一個進程,當進程退出時,命名空間內的每個安裝選項都將被清除。golang mount命名空間:掛載的卷在進程退出後不會被清除?

但它不是?

package main 
import (
     "fmt" 
     "os" 
     "os/exec" 
     "syscall" 
) 

var command string = "/usr/bin/bash" 

func container_command() { 

     fmt.Printf("starting container command %s\n", command) 
     cmd := exec.Command(command) 
     cmd.SysProcAttr = &syscall.SysProcAttr{Cloneflags: syscall.CLONE_NEWPID | 
       syscall.CLONE_NEWNS, 
     } 
     cmd.Stdin = os.Stdin 
     cmd.Stdout = os.Stdout 
     cmd.Stderr = os.Stderr 

     if err := cmd.Run(); err != nil { 
       fmt.Println("error", err) 
       os.Exit(1) 
     } 
} 

func main() { 
     fmt.Printf("starting current process %d\n", os.Getpid()) 
     container_command() 
     fmt.Printf("command ended\n") 

} 

運行這個並掛載一個目錄,該目錄在程序退出後仍然退出。

[[email protected] go]# go run namespace-1.go 
starting current process 7558 
starting container command /usr/bin/bash 
[[email protected] go]# mount --bind /home /mnt 
[[email protected] go]# ls /mnt 
vagrant 
[[email protected] go]# exit 
exit 
command ended 
[[email protected] go]# ls /mnt 
vagrant 
[[email protected] go]# 

如果這是所需的行爲,proc如何在容器實現中被掛載?因爲如果我在命名空間內安裝proc,我將得到

[[email protected] go]# mount -t proc /proc 
[[email protected] go]# exit 
exit 
command ended 
[[email protected] go]# mount 
mount: failed to read mtab: No such file or directory 
[[email protected] go]# 

proc必須重新安裝才能恢復。

更新: 做同樣的C也給出了相同的結果,我認爲這應該是一個預期的行爲。

#define _GNU_SOURCE 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <stdio.h> 
#include <sched.h> 
#include <signal.h> 
#include <unistd.h> 

#define STACK_SIZE (1024 * 1024) 
static char container_stack[STACK_SIZE]; 

char* const container_args[] = { 
    "/bin/bash", 
    NULL 
}; 

int container_main(void* arg) 
{ 
     printf("Container [%5d] - inside the container!\n", getpid()); 
      sethostname("container",10); 
      system("mount -t proc proc /proc"); 
      execv(container_args[0], container_args); 
      printf("Something's wrong!\n"); 
      return 1; 
} 

int main() 
{ 
    printf("start a container!\n"); 
    int container_pid = clone(container_main, container_stack+STACK_SIZE, 
      CLONE_NEWUTS | CLONE_NEWPID | CLONE_NEWNS | SIGCHLD, NULL); 
    waitpid(container_pid, NULL, 0); 
    printf("container ended!\n"); 
    return 0; 
} 

命令輸出:

[[email protected] ~]# gcc a.c 
[[email protected] ~]# ./a.out 
start a container! 
Container [ 1] - inside the container! 
[[email protected] ~]# ps -ef 
UID  PID PPID C STIME TTY   TIME CMD 
root   1  0 0 08:57 pts/0 00:00:00 /bin/bash 
root  17  1 0 08:57 pts/0 00:00:00 ps -ef 
[[email protected] ~]# exit 
exit 
container stopped! 
[[email protected] ~]# ps -ef 
Error, do this: mount -t proc proc /proc 
[[email protected] ~]# cat a.c 

回答

1

發生這種情況,由於裝入事件命名空間之間傳播。您的安裝點的傳播類型是MS_SHARED

MS_SHARED:該掛載點與其他「同級組」的成員掛載點共享掛載和卸載事件。當在此掛載點下添加或刪除掛載點時,此更改將傳播到對等組,以便掛載或卸載也將在每個對等掛載點下發生。傳播也會在相反方向發生,因此對等安裝上的掛載和卸載事件也會傳播到此掛載點。

源 - https://lwn.net/Articles/689856/

/proc/self/mountinfoshared:N標籤指示所述安裝與對等體組共享傳播事件:

$ sudo go run namespace-1.go 
[[email protected]]# mount --bind /home/andrii/test /mnt 
# The propagation type is MS_SHARED 
[[email protected]]# grep '/mnt' /proc/self/mountinfo 
264 175 254:0 /home/andrii/test /mnt rw,noatime shared:1 - ext4 
/dev/mapper/cryptroot rw,data=ordered 
[[email protected]]# exit 
$ ls /mnt 
test_file 

在大部分Linux上的缺省傳播類型是MS_SHARED這是由systemd設置。見NOTESman 7 mount_namespaces

儘管事實上新 默認傳播類型,安裝點在許多情況下MS_PRIVATE,MS_SHARED通常更 有用。因此,systemd(1)會在系統啓動時自動將所有安裝點 點重新安裝爲MS_SHARED。因此,在大多數現代系統中, 默認傳播類型實際上是MS_SHARED。

如果你想要一個完全隔離的命名空間,可以使所有掛載點私人這樣:

$ sudo go run namespace-1.go 
[[email protected]]# mount --make-rprivate/
[[email protected]]# mount --bind /home/andrii/test /mnt 
# The propagation type is MS_PRIVATE now 
[[email protected]]# grep '/mnt' /proc/self/mountinfo 
264 175 254:0 /home/andrii/test /mnt rw,noatime - ext4 
/dev/mapper/cryptroot rw,data=ordered 
[[email protected]]# exit 
$ ls /mnt 
+1

謝謝。爲了記錄,要在golang中實現'mount --make-private /',mount標誌是'syscall.MS_PRIVATE | syscall.MS_REC' –

相關問題