Skip to content

Commit

Permalink
Merge pull request #191 from giuseppe/overlay-fuse-program
Browse files Browse the repository at this point in the history
containers-storage: add new option .fuse_program
  • Loading branch information
rhatdan authored Jun 29, 2018
2 parents 51f1f85 + fc4b862 commit 58f557c
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 8 deletions.
4 changes: 4 additions & 0 deletions docs/containers-storage.conf.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ Tells driver to wipe device (directlvm_device) even if device already has a file

Specifies the filesystem type to use for the base device. (default: xfs)

**fuse_program**=""

Specifies the path to a custom FUSE program to use instead for mounting the file system.

**log_level**=""

Sets the log level of devicemapper.
Expand Down
38 changes: 30 additions & 8 deletions drivers/overlay/overlay.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ type overlayOptions struct {
overrideKernelCheck bool
imageStores []string
quota quota.Quota
fuseProgram string
}

// Driver contains information about the home directory and the list of active mounts that are created using this driver.
Expand Down Expand Up @@ -147,11 +148,16 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
return nil, err
}

supportsDType, err := supportsOverlay(home, fsMagic, rootUID, rootGID)
if err != nil {
os.Remove(filepath.Join(home, linkDir))
os.Remove(home)
return nil, errors.Wrap(err, "kernel does not support overlay fs")
var supportsDType bool
if opts.fuseProgram != "" {
supportsDType = true
} else {
supportsDType, err = supportsOverlay(home, fsMagic, rootUID, rootGID)
if err != nil {
os.Remove(filepath.Join(home, linkDir))
os.Remove(home)
return nil, errors.Wrap(err, "kernel does not support overlay fs")
}
}

if err := mount.MakePrivate(home); err != nil {
Expand Down Expand Up @@ -227,6 +233,13 @@ func parseOptions(options []string) (*overlayOptions, error) {
}
o.imageStores = append(o.imageStores, store)
}
case ".fuse_program", "overlay.fuse_program", "overlay2.fuse_program":
logrus.Debugf("overlay: fuse_program=%s", val)
_, err := os.Stat(val)
if err != nil {
return nil, fmt.Errorf("overlay: can't stat FUSE program %s: %v", val, err)
}
o.fuseProgram = val
default:
return nil, fmt.Errorf("overlay: Unknown option %s", key)
}
Expand All @@ -236,6 +249,7 @@ func parseOptions(options []string) (*overlayOptions, error) {

func supportsOverlay(home string, homeMagic graphdriver.FsMagic, rootUID, rootGID int) (supportsDType bool, err error) {
// We can try to modprobe overlay first

exec.Command("modprobe", "overlay").Run()

layerDir, err := ioutil.TempDir(home, "compat")
Expand Down Expand Up @@ -663,16 +677,24 @@ func (d *Driver) Get(id, mountLabel string) (_ string, retErr error) {
// the page size. The mount syscall fails if the mount data cannot
// fit within a page and relative links make the mount data much
// smaller at the expense of requiring a fork exec to chroot.
if len(mountData) > pageSize {
if len(mountData) > pageSize || d.options.fuseProgram != "" {
//FIXME: We need to figure out to get this to work with additional stores
opts = fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", strings.Join(relLowers, ":"), path.Join(id, "diff"), path.Join(id, "work"))
mountData = label.FormatMountLabel(opts, mountLabel)
if len(mountData) > pageSize {
return "", fmt.Errorf("cannot mount layer, mount label too large %d", len(mountData))
}

mount = func(source string, target string, mType string, flags uintptr, label string) error {
return mountFrom(d.home, source, target, mType, flags, label)
if d.options.fuseProgram != "" {
mount = func(source string, target string, mType string, flags uintptr, label string) error {
cmdRootless := exec.Command(d.options.fuseProgram, "-o", label, target)
cmdRootless.Dir = d.home
return cmdRootless.Run()
}
} else {
mount = func(source string, target string, mType string, flags uintptr, label string) error {
return mountFrom(d.home, source, target, mType, flags, label)
}
}
mountTarget = path.Join(id, "merged")
}
Expand Down

0 comments on commit 58f557c

Please sign in to comment.