Как правильно реализовать mount namespaces в go

У меня есть следующий код mnt.go

package main

import (
    "fmt"
    "log"
    "os"
    "os/exec"
    "syscall"
)

func main() {
    fmt.Println("Entering go program")

    cmd := exec.Command("/bin/bash")
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    cmd.Stdin = os.Stdin

    cmd.SysProcAttr = &syscall.SysProcAttr{ 
        Cloneflags: syscall.CLONE_NEWNS,
    }

    if err := cmd.Run(); err != nil {
        log.Fatal(err)
    }

    fmt.Println("Exiting go program")
}

Я хочу запустить приведенный выше код, чтобы создать оболочку bash, и выполнить следующие команды:

./mnt
mkdir /tmp/testmount
mount -n -o size=1m -t tmpfs tmpfs /tmp/testmount
cd /tmp/testmount
touch 1.txt 2.txt 3.txt

Теперь, когда я запускаю другую оболочку и запускаю команду

ls /tmp/testmount

Я не должен видеть файлы 1.txt, 2.txt и 3.txt. Поскольку временная файловая система была смонтирована внутри пространства имен монтирования, она не должна быть видна снаружи.

Но это не так, как это работает для меня. Почему syscall.CLONE_NEWNS не работает должным образом? Что мне делать по-другому?

В одном из комментариев упоминается, что этот код отлично работает для них. FWIW, я использую коробку Vagrant bento/centos-7 с установленным golang и без других настроек.


person ashwnacharya    schedule 19.11.2019    source источник
comment
На самом деле я запускаю ваш пример, он работает, как и ожидалось. mnt для запуска требуется sudo, и после выполнения ваших команд три файла txt не видны из других процессов (доступна только папка /tmp/testmount).   -  person ivzhh    schedule 19.11.2019
comment
@etc-100g Очень интересно. Я запускаю это в бродячей коробке bento/centos-7. Я понятия не имею, почему это работает для вас. На какой ОС вы это пробуете?   -  person ashwnacharya    schedule 19.11.2019
comment
WSL2/Убунту 18.04. Вы правы, после тестирования на других CentOS-7/Virtualbox результат такой же, как у вас.   -  person ivzhh    schedule 19.11.2019
comment
Возможно, из-за этого: stackoverflow.com/a/45524409/225692   -  person ivzhh    schedule 19.11.2019


Ответы (1)


Я был правым относительно решение. Но я не знал почему. В целях документации я сделаю этот пост полным. Если вы умеете читать по-китайски, прочитайте непосредственно этот пост Zhihu Zhuanlan. . Этот автор очень профессионально разбирается в контейнерах и докерах Linux.

Ключевые слова знания: Общие поддеревья и типы распространения: MS_SHARED, MS_PRIVATE и MS_SLAVE. По умолчанию система предполагает, что вы хотите повторно использовать смонтированные файловые системы. Но если вы этого не хотите, вам придется проделать дополнительную работу:

Процесс хочет клонировать свое собственное пространство имен, но по-прежнему хочет получить доступ к недавно смонтированному компакт-диску. Семантика разделяемых поддеревьев обеспечивает необходимый механизм для выполнения вышеуказанного.

В командной строке вы можете mount --make-rprivate /; в коде вам нужно использовать syscall.MS_PRIVATE | syscall.MS_REC для создания изолированное крепление.

person ivzhh    schedule 04.08.2020