Skip to content

Commit f6fa353

Browse files
committed
Merge pull request moby#1267 from sridatta/new-clean-init
* Runtime: Fix to "Inject dockerinit at /.dockerinit"
2 parents d4fa619 + 945033f commit f6fa353

File tree

6 files changed

+50
-5
lines changed

6 files changed

+50
-5
lines changed

container.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,7 @@ func (container *Container) Start(hostConfig *HostConfig) error {
631631
"-n", container.ID,
632632
"-f", container.lxcConfigPath(),
633633
"--",
634-
"/sbin/init",
634+
"/.dockerinit",
635635
}
636636

637637
// Networking

docker/docker.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ var (
1919
)
2020

2121
func main() {
22-
if utils.SelfPath() == "/sbin/init" {
22+
if selfPath := utils.SelfPath(); selfPath == "/sbin/init" || selfPath == "/.dockerinit" {
2323
// Running in init mode
2424
docker.SysInit()
2525
return

graph.go

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,39 @@ func (graph *Graph) Mktemp(id string) (string, error) {
177177
return tmp.imageRoot(id), nil
178178
}
179179

180+
// getDockerInitLayer returns the path of a layer containing a mountpoint suitable
181+
// for bind-mounting dockerinit into the container. The mountpoint is simply an
182+
// empty file at /.dockerinit
183+
//
184+
// This extra layer is used by all containers as the top-most ro layer. It protects
185+
// the container from unwanted side-effects on the rw layer.
186+
func (graph *Graph) getDockerInitLayer() (string, error) {
187+
tmp, err := graph.tmp()
188+
if err != nil {
189+
return "", err
190+
}
191+
initLayer := tmp.imageRoot("_dockerinit")
192+
if err := os.Mkdir(initLayer, 0755); err != nil && !os.IsExist(err) {
193+
// If directory already existed, keep going.
194+
// For all other errors, abort.
195+
return "", err
196+
}
197+
// FIXME: how the hell do I break down this line in a way
198+
// that is idiomatic and not ugly as hell?
199+
if f, err := os.OpenFile(path.Join(initLayer, ".dockerinit"), os.O_CREATE|os.O_TRUNC, 0700); err != nil && !os.IsExist(err) {
200+
// If file already existed, keep going.
201+
// For all other errors, abort.
202+
return "", err
203+
} else {
204+
f.Close()
205+
}
206+
// Layer is ready to use, if it wasn't before.
207+
return initLayer, nil
208+
}
209+
180210
func (graph *Graph) tmp() (*Graph, error) {
181-
return NewGraph(path.Join(graph.Root, ":tmp:"))
211+
// Changed to _tmp from :tmp:, because it messed with ":" separators in aufs branch syntax...
212+
return NewGraph(path.Join(graph.Root, "_tmp"))
182213
}
183214

184215
// Check if given error is "not empty".

image.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,13 @@ func (img *Image) layers() ([]string, error) {
263263
if len(list) == 0 {
264264
return nil, fmt.Errorf("No layer found for image %s\n", img.ID)
265265
}
266+
267+
// Inject the dockerinit layer (empty place-holder for mount-binding dockerinit)
268+
if dockerinitLayer, err := img.getDockerInitLayer(); err != nil {
269+
return nil, err
270+
} else {
271+
list = append([]string{dockerinitLayer}, list...)
272+
}
266273
return list, nil
267274
}
268275

@@ -292,6 +299,13 @@ func (img *Image) GetParent() (*Image, error) {
292299
return img.graph.Get(img.Parent)
293300
}
294301

302+
func (img *Image) getDockerInitLayer() (string, error) {
303+
if img.graph == nil {
304+
return "", fmt.Errorf("Can't lookup dockerinit layer of unregistered image")
305+
}
306+
return img.graph.getDockerInitLayer()
307+
}
308+
295309
func (img *Image) root() (string, error) {
296310
if img.graph == nil {
297311
return "", fmt.Errorf("Can't lookup root of unregistered image")

lxc_template.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ lxc.mount.entry = devpts {{$ROOTFS}}/dev/pts devpts newinstance,ptmxmode=0666,no
8484
#lxc.mount.entry = shm {{$ROOTFS}}/dev/shm tmpfs size=65536k,nosuid,nodev,noexec 0 0
8585
8686
# Inject docker-init
87-
lxc.mount.entry = {{.SysInitPath}} {{$ROOTFS}}/sbin/init none bind,ro 0 0
87+
lxc.mount.entry = {{.SysInitPath}} {{$ROOTFS}}/.dockerinit none bind,ro 0 0
8888
8989
# In order to get a working DNS environment, mount bind (ro) the host's /etc/resolv.conf into the container
9090
lxc.mount.entry = {{.ResolvConfPath}} {{$ROOTFS}}/etc/resolv.conf none bind,ro 0 0

runtime_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func layerArchive(tarfile string) (io.Reader, error) {
7373

7474
func init() {
7575
// Hack to run sys init during unit testing
76-
if utils.SelfPath() == "/sbin/init" {
76+
if selfPath := utils.SelfPath(); selfPath == "/sbin/init" || selfPath == "/.dockerinit" {
7777
SysInit()
7878
return
7979
}

0 commit comments

Comments
 (0)