Skip to content

Commit c7406f7

Browse files
committed
Support copyup mount extension for tmpfs mounts
If copyup is specified for a tmpfs mount, then the contents of the underlying directory are copied into the tmpfs mounted over it. Signed-off-by: Mrunal Patel <[email protected]>
1 parent 4356468 commit c7406f7

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

libcontainer/rootfs_linux.go

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616

1717
"github.com/docker/docker/pkg/mount"
1818
"github.com/docker/docker/pkg/symlink"
19+
"github.com/mrunalp/fileutils"
1920
"github.com/opencontainers/runc/libcontainer/cgroups"
2021
"github.com/opencontainers/runc/libcontainer/configs"
2122
"github.com/opencontainers/runc/libcontainer/label"
@@ -152,15 +153,41 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
152153
}
153154
return nil
154155
case "tmpfs":
156+
copyUp := m.Extensions&configs.EXT_COPYUP == configs.EXT_COPYUP
157+
tmpDir := ""
155158
stat, err := os.Stat(dest)
156159
if err != nil {
157160
if err := os.MkdirAll(dest, 0755); err != nil {
158161
return err
159162
}
160163
}
164+
if copyUp {
165+
tmpDir, err = ioutil.TempDir("/tmp", "runctmpdir")
166+
if err != nil {
167+
return newSystemErrorWithCause(err, "tmpcopyup: failed to create tmpdir")
168+
}
169+
defer os.RemoveAll(tmpDir)
170+
m.Destination = tmpDir
171+
}
161172
if err := mountPropagate(m, rootfs, mountLabel); err != nil {
162173
return err
163174
}
175+
if copyUp {
176+
if err := fileutils.CopyDirectory(dest, tmpDir); err != nil {
177+
errMsg := fmt.Errorf("tmpcopyup: failed to copy %s to %s: %v", dest, tmpDir, err)
178+
if err1 := syscall.Unmount(tmpDir, syscall.MNT_DETACH); err1 != nil {
179+
return newSystemErrorWithCausef(err1, "tmpcopyup: %v: failed to unmount", errMsg)
180+
}
181+
return errMsg
182+
}
183+
if err := syscall.Mount(tmpDir, dest, "", syscall.MS_MOVE, ""); err != nil {
184+
errMsg := fmt.Errorf("tmpcopyup: failed to move mount %s to %s: %v", tmpDir, dest, err)
185+
if err1 := syscall.Unmount(tmpDir, syscall.MNT_DETACH); err1 != nil {
186+
return newSystemErrorWithCausef(err1, "tmpcopyup: %v: failed to unmount", errMsg)
187+
}
188+
return errMsg
189+
}
190+
}
164191
if stat != nil {
165192
if err = os.Chmod(dest, stat.Mode()); err != nil {
166193
return err
@@ -711,7 +738,9 @@ func mountPropagate(m *configs.Mount, rootfs string, mountLabel string) error {
711738
if libcontainerUtils.CleanPath(dest) == "/dev" {
712739
flags &= ^syscall.MS_RDONLY
713740
}
714-
if !strings.HasPrefix(dest, rootfs) {
741+
742+
copyUp := m.Extensions&configs.EXT_COPYUP == configs.EXT_COPYUP
743+
if !(copyUp || strings.HasPrefix(dest, rootfs)) {
715744
dest = filepath.Join(rootfs, dest)
716745
}
717746

0 commit comments

Comments
 (0)