mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
lxc: Work around lxc-start need for private mounts
lxc-start requires / to be mounted private, otherwise the changes it does inside the container (both mounts and unmounts) will propagate out to the host. We work around this by starting up lxc-start in its own namespace where we set / to rprivate. Unfortunately go can't really execute any code between clone and exec, so we can't do this in a nice way. Instead we have a horrible hack that use the unshare command, the shell and the mount command...
This commit is contained in:
parent
d80be57c15
commit
e40f5c7cb9
2 changed files with 31 additions and 1 deletions
17
container.go
17
container.go
|
@ -747,6 +747,7 @@ func (container *Container) Start(hostConfig *HostConfig) error {
|
|||
}
|
||||
|
||||
params := []string{
|
||||
"lxc-start",
|
||||
"-n", container.ID,
|
||||
"-f", container.lxcConfigPath(),
|
||||
"--",
|
||||
|
@ -795,7 +796,21 @@ func (container *Container) Start(hostConfig *HostConfig) error {
|
|||
params = append(params, "--", container.Path)
|
||||
params = append(params, container.Args...)
|
||||
|
||||
container.cmd = exec.Command("lxc-start", params...)
|
||||
if RootIsShared() {
|
||||
// lxc-start really needs / to be private, or all kinds of stuff break
|
||||
// What we really want is to clone into a new namespace and then
|
||||
// mount / MS_REC|MS_PRIVATE, but since we can't really clone or fork
|
||||
// without exec in go we have to do this horrible shell hack...
|
||||
shellString :=
|
||||
"mount --make-rprivate /; exec " +
|
||||
utils.ShellQuoteArguments(params)
|
||||
|
||||
params = []string{
|
||||
"unshare", "-m", "--", "/bin/sh", "-c", shellString,
|
||||
}
|
||||
}
|
||||
|
||||
container.cmd = exec.Command(params[0], params[1:]...)
|
||||
|
||||
// Setup logging of stdout and stderr to disk
|
||||
if err := container.runtime.LogToDisk(container.stdout, container.logPath("json"), "stdout"); err != nil {
|
||||
|
|
15
utils.go
15
utils.go
|
@ -2,6 +2,7 @@ package docker
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
@ -167,3 +168,17 @@ func parseLxcOpt(opt string) (string, string, error) {
|
|||
}
|
||||
return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]), nil
|
||||
}
|
||||
|
||||
func RootIsShared() bool {
|
||||
if data, err := ioutil.ReadFile("/proc/self/mountinfo"); err == nil {
|
||||
for _, line := range strings.Split(string(data), "\n") {
|
||||
cols := strings.Split(line, " ")
|
||||
if cols[3] == "/" && cols[4] == "/" {
|
||||
return strings.HasPrefix(cols[6], "shared")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No idea, probably safe to assume so
|
||||
return true
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue