Merge pull request #1267 from sridatta/new-clean-init

* Runtime: Fix to "Inject dockerinit at /.dockerinit"
This commit is contained in:
Guillaume J. Charmes 2013-08-05 13:23:22 -07:00
Родитель d4fa619ed1 945033f1cc
Коммит f6fa353dd8
6 изменённых файлов: 50 добавлений и 5 удалений

Просмотреть файл

@ -631,7 +631,7 @@ func (container *Container) Start(hostConfig *HostConfig) error {
"-n", container.ID,
"-f", container.lxcConfigPath(),
"--",
"/sbin/init",
"/.dockerinit",
}
// Networking

Просмотреть файл

@ -19,7 +19,7 @@ var (
)
func main() {
if utils.SelfPath() == "/sbin/init" {
if selfPath := utils.SelfPath(); selfPath == "/sbin/init" || selfPath == "/.dockerinit" {
// Running in init mode
docker.SysInit()
return

Просмотреть файл

@ -177,8 +177,39 @@ func (graph *Graph) Mktemp(id string) (string, error) {
return tmp.imageRoot(id), nil
}
// getDockerInitLayer returns the path of a layer containing a mountpoint suitable
// for bind-mounting dockerinit into the container. The mountpoint is simply an
// empty file at /.dockerinit
//
// This extra layer is used by all containers as the top-most ro layer. It protects
// the container from unwanted side-effects on the rw layer.
func (graph *Graph) getDockerInitLayer() (string, error) {
tmp, err := graph.tmp()
if err != nil {
return "", err
}
initLayer := tmp.imageRoot("_dockerinit")
if err := os.Mkdir(initLayer, 0755); err != nil && !os.IsExist(err) {
// If directory already existed, keep going.
// For all other errors, abort.
return "", err
}
// FIXME: how the hell do I break down this line in a way
// that is idiomatic and not ugly as hell?
if f, err := os.OpenFile(path.Join(initLayer, ".dockerinit"), os.O_CREATE|os.O_TRUNC, 0700); err != nil && !os.IsExist(err) {
// If file already existed, keep going.
// For all other errors, abort.
return "", err
} else {
f.Close()
}
// Layer is ready to use, if it wasn't before.
return initLayer, nil
}
func (graph *Graph) tmp() (*Graph, error) {
return NewGraph(path.Join(graph.Root, ":tmp:"))
// Changed to _tmp from :tmp:, because it messed with ":" separators in aufs branch syntax...
return NewGraph(path.Join(graph.Root, "_tmp"))
}
// Check if given error is "not empty".

Просмотреть файл

@ -263,6 +263,13 @@ func (img *Image) layers() ([]string, error) {
if len(list) == 0 {
return nil, fmt.Errorf("No layer found for image %s\n", img.ID)
}
// Inject the dockerinit layer (empty place-holder for mount-binding dockerinit)
if dockerinitLayer, err := img.getDockerInitLayer(); err != nil {
return nil, err
} else {
list = append([]string{dockerinitLayer}, list...)
}
return list, nil
}
@ -292,6 +299,13 @@ func (img *Image) GetParent() (*Image, error) {
return img.graph.Get(img.Parent)
}
func (img *Image) getDockerInitLayer() (string, error) {
if img.graph == nil {
return "", fmt.Errorf("Can't lookup dockerinit layer of unregistered image")
}
return img.graph.getDockerInitLayer()
}
func (img *Image) root() (string, error) {
if img.graph == nil {
return "", fmt.Errorf("Can't lookup root of unregistered image")

Просмотреть файл

@ -84,7 +84,7 @@ lxc.mount.entry = devpts {{$ROOTFS}}/dev/pts devpts newinstance,ptmxmode=0666,no
#lxc.mount.entry = shm {{$ROOTFS}}/dev/shm tmpfs size=65536k,nosuid,nodev,noexec 0 0
# Inject docker-init
lxc.mount.entry = {{.SysInitPath}} {{$ROOTFS}}/sbin/init none bind,ro 0 0
lxc.mount.entry = {{.SysInitPath}} {{$ROOTFS}}/.dockerinit none bind,ro 0 0
# In order to get a working DNS environment, mount bind (ro) the host's /etc/resolv.conf into the container
lxc.mount.entry = {{.ResolvConfPath}} {{$ROOTFS}}/etc/resolv.conf none bind,ro 0 0

Просмотреть файл

@ -73,7 +73,7 @@ func layerArchive(tarfile string) (io.Reader, error) {
func init() {
// Hack to run sys init during unit testing
if utils.SelfPath() == "/sbin/init" {
if selfPath := utils.SelfPath(); selfPath == "/sbin/init" || selfPath == "/.dockerinit" {
SysInit()
return
}