func aufsMount(ro []string, rw, target, mountLabel string) (err error) { defer func() { if err != nil { aufsUnmount(target) } }() // Mount options are clipped to page size(4096 bytes). If there are more // layers then these are remounted individually using append. offset := 54 if useDirperm() { offset += len("dirperm1") } b := make([]byte, syscall.Getpagesize()-len(mountLabel)-offset) // room for xino & mountLabel bp := copy(b, fmt.Sprintf("br:%s=rw", rw)) firstMount := true i := 0 for { for ; i < len(ro); i++ { layer := fmt.Sprintf(":%s=ro+wh", ro[i]) if firstMount { if bp+len(layer) > len(b) { break } bp += copy(b[bp:], layer) } else { data := utils.FormatMountLabel(fmt.Sprintf("append%s", layer), mountLabel) if err = syscall.Mount("none", target, "aufs", MsRemount, data); err != nil { return } } } if firstMount { opts := "dio,xino=/dev/shm/aufs.xino" if useDirperm() { opts += ",dirperm1" } data := utils.FormatMountLabel(fmt.Sprintf("%s,%s", string(b[:bp]), opts), mountLabel) if err = syscall.Mount("none", target, "aufs", 0, data); err != nil { return } firstMount = false } if i == len(ro) { break } } return }
func MountContainerToSharedDir(containerId, rootDir, sharedDir, mountLabel string) (string, error) { var ( mountPoint = path.Join(sharedDir, containerId, "rootfs") upperDir = path.Join(rootDir, containerId, "upper") workDir = path.Join(rootDir, containerId, "work") ) if _, err := os.Stat(mountPoint); err != nil { if err = os.MkdirAll(mountPoint, 0755); err != nil { return "", err } } lowerId, err := ioutil.ReadFile(path.Join(rootDir, containerId) + "/lower-id") if err != nil { return "", err } lowerDir := path.Join(rootDir, string(lowerId), "root") params := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lowerDir, upperDir, workDir) if err := syscall.Mount("overlay", mountPoint, "overlay", 0, utils.FormatMountLabel(params, mountLabel)); err != nil { return "", fmt.Errorf("error creating overlay mount to %s: %v", mountPoint, err) } return mountPoint, nil }