1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

devmapper: Move init layer to top rather than bottom

The init layer needs to be topmost to make sure certain files
are always there (for instance, the ubuntu:12.10 image wrongly
has /dev/shm being a symlink to /run/shm, and we need to override
that). However, previously the devmapper code implemented the
init layer by putting it in the base devmapper device, which meant
layers above it could override these files (so that ubuntu:12.10
broke).

So, instead we put the base layer in *each* images devmapper device.
This is "safe" because we still have the pristine layer data
in the layer directory. Also, it means we diff the container
against the image with the init layer applied, so it won't show
up in diffs/commits.
This commit is contained in:
Alexander Larsson 2013-09-12 20:30:55 +02:00 committed by Victor Vieux
parent e40f5c7cb9
commit c199ed228b
2 changed files with 17 additions and 62 deletions

View file

@ -542,45 +542,6 @@ func (devices *DeviceSetDM) loadMetaData() error {
return nil
}
func (devices *DeviceSetDM) createBaseLayer(dir string) error {
for pth, typ := range map[string]string{
"/dev/pts": "dir",
"/dev/shm": "dir",
"/proc": "dir",
"/sys": "dir",
"/.dockerinit": "file",
"/etc/resolv.conf": "file",
"/etc/hosts": "file",
"/etc/hostname": "file",
// "var/run": "dir",
// "var/lock": "dir",
} {
if _, err := os.Stat(path.Join(dir, pth)); err != nil {
if os.IsNotExist(err) {
switch typ {
case "dir":
if err := os.MkdirAll(path.Join(dir, pth), 0755); err != nil {
return err
}
case "file":
if err := os.MkdirAll(path.Join(dir, path.Dir(pth)), 0755); err != nil {
return err
}
if f, err := os.OpenFile(path.Join(dir, pth), os.O_CREATE, 0755); err != nil {
return err
} else {
f.Close()
}
}
} else {
return err
}
}
}
return nil
}
func (devices *DeviceSetDM) setupBaseImage() error {
oldInfo := devices.Devices[""]
if oldInfo != nil && oldInfo.Initialized {
@ -622,29 +583,6 @@ func (devices *DeviceSetDM) setupBaseImage() error {
return err
}
tmpDir := path.Join(devices.loopbackDir(), "basefs")
if err = os.MkdirAll(tmpDir, 0700); err != nil && !os.IsExist(err) {
return err
}
err = devices.MountDevice("", tmpDir)
if err != nil {
return err
}
err = devices.createBaseLayer(tmpDir)
if err != nil {
_ = syscall.Unmount(tmpDir, 0)
return err
}
err = devices.UnmountDevice("", tmpDir)
if err != nil {
return err
}
_ = os.Remove(tmpDir)
info.Initialized = true
err = devices.saveMetadata()

View file

@ -379,6 +379,23 @@ func (image *Image) ensureImageDevice(devices DeviceSet) error {
return err
}
// The docker init layer is conceptually above all other layers, so we apply
// it for every image. This is safe because the layer directory is the
// definition of the image, and the device-mapper device is just a cache
// of it instantiated. Diffs/commit compare the container device with the
// image device, which will then *not* pick up the init layer changes as
// part of the container changes
dockerinitLayer, err := image.getDockerInitLayer()
if err != nil {
_ = devices.RemoveDevice(image.ID)
return err
}
err = image.applyLayer(dockerinitLayer, mountDir)
if err != nil {
_ = devices.RemoveDevice(image.ID)
return err
}
err = devices.UnmountDevice(image.ID, mountDir)
if err != nil {
_ = devices.RemoveDevice(image.ID)