overlay2: add support for --storage-opt size

Allow passing --storage-opt size=X to docker create/run commands
for the `overlay2` graphriver.

The size option is only available if the backing fs is xfs that is
mounted with the `pquota` mount option.
The user can pass any size less then the backing fs size.

Signed-off-by: Amir Goldstein <amir73il@aquasec.com>
This commit is contained in:
Amir Goldstein 2016-09-18 22:35:55 +03:00
parent 52897d1c09
commit 05bac4591a
5 changed files with 88 additions and 21 deletions

View File

@ -24,6 +24,7 @@ import (
"github.com/docker/docker/pkg/mount"
"github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/pkg/parsers/kernel"
"github.com/docker/go-units"
"github.com/opencontainers/runc/libcontainer/label"
)
@ -76,15 +77,25 @@ const (
idLength = 26
)
// Driver contains information about the home directory and the list of active mounts that are created using this driver.
type Driver struct {
home string
uidMaps []idtools.IDMap
gidMaps []idtools.IDMap
ctr *graphdriver.RefCounter
type overlayOptions struct {
overrideKernelCheck bool
quota graphdriver.Quota
}
var backingFs = "<unknown>"
// Driver contains information about the home directory and the list of active mounts that are created using this driver.
type Driver struct {
home string
uidMaps []idtools.IDMap
gidMaps []idtools.IDMap
ctr *graphdriver.RefCounter
quotaCtl *graphdriver.QuotaCtl
options overlayOptions
}
var (
backingFs = "<unknown>"
projectQuotaSupported = false
)
func init() {
graphdriver.Register(driverName, Init)
@ -150,11 +161,16 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
ctr: graphdriver.NewRefCounter(graphdriver.NewFsChecker(graphdriver.FsMagicOverlay)),
}
return d, nil
}
if backingFs == "xfs" {
// Try to enable project quota support over xfs.
if d.quotaCtl, err = graphdriver.NewQuotaCtl(home); err == nil {
projectQuotaSupported = true
}
}
type overlayOptions struct {
overrideKernelCheck bool
logrus.Debugf("backingFs=%s, projectQuotaSupported=%v", backingFs, projectQuotaSupported)
return d, nil
}
func parseOptions(options []string) (*overlayOptions, error) {
@ -171,6 +187,7 @@ func parseOptions(options []string) (*overlayOptions, error) {
if err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("overlay2: Unknown option %s\n", key)
}
@ -253,8 +270,8 @@ func (d *Driver) CreateReadWrite(id, parent, mountLabel string, storageOpt map[s
// The parent filesystem is used to configure these directories for the overlay.
func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) (retErr error) {
if len(storageOpt) != 0 {
return fmt.Errorf("--storage-opt is not supported for overlay")
if len(storageOpt) != 0 && !projectQuotaSupported {
return fmt.Errorf("--storage-opt is supported only for overlay over xfs with 'pquota' mount option")
}
dir := d.dir(id)
@ -277,6 +294,20 @@ func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]str
}
}()
if len(storageOpt) > 0 {
driver := &Driver{}
if err := d.parseStorageOpt(storageOpt, driver); err != nil {
return err
}
if driver.options.quota.Size > 0 {
// Set container disk quota limit
if err := d.quotaCtl.SetQuota(dir, driver.options.quota); err != nil {
return err
}
}
}
if err := idtools.MkdirAs(path.Join(dir, "diff"), 0755, rootUID, rootGID); err != nil {
return err
}
@ -316,6 +347,26 @@ func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]str
return nil
}
// Parse overlay storage options
func (d *Driver) parseStorageOpt(storageOpt map[string]string, driver *Driver) error {
// Read size to set the disk project quota per container
for key, val := range storageOpt {
key := strings.ToLower(key)
switch key {
case "size":
size, err := units.RAMInBytes(val)
if err != nil {
return err
}
driver.options.quota.Size = uint64(size)
default:
return fmt.Errorf("Unknown option %s", key)
}
}
return nil
}
func (d *Driver) getLower(parent string) (string, error) {
parentDir := d.dir(parent)

View File

@ -171,8 +171,13 @@ Set storage driver options per container.
$ docker create -it --storage-opt size=120G fedora /bin/bash
This (size) will allow to set the container rootfs size to 120G at creation time.
User cannot pass a size less than the Default BaseFS Size. This option is only
available for the `devicemapper`, `btrfs`, `windowsfilter`, and `zfs` graph drivers.
This option is only available for the `devicemapper`, `btrfs`, `overlay2`,
`windowsfilter` and `zfs` graph drivers.
For the `devicemapper`, `btrfs`, `windowsfilter` and `zfs` graph drivers,
user cannot pass a size less than the Default BaseFS Size.
For the `overlay2` storage driver, the size option is only available if the
backing fs is `xfs` and mounted with the `pquota` mount option.
Under these conditions, user can pass any size less then the backing fs size.
### Specify isolation technology for container (--isolation)

View File

@ -198,8 +198,13 @@ The `-w` lets the command being executed inside directory given, here
$ docker run -it --storage-opt size=120G fedora /bin/bash
This (size) will allow to set the container rootfs size to 120G at creation time.
User cannot pass a size less than the Default BaseFS Size. This option is only
available for the `devicemapper`, `btrfs`, `windowsfilter`, and `zfs` graph drivers.
This option is only available for the `devicemapper`, `btrfs`, `overlay2`,
`windowsfilter` and `zfs` graph drivers.
For the `devicemapper`, `btrfs`, `windowsfilter` and `zfs` graph drivers,
user cannot pass a size less than the Default BaseFS Size.
For the `overlay2` storage driver, the size option is only available if the
backing fs is `xfs` and mounted with the `pquota` mount option.
Under these conditions, user can pass any size less then the backing fs size.
### Mount tmpfs (--tmpfs)

View File

@ -343,8 +343,11 @@ unit, `b` is used. Set LIMIT to `-1` to enable unlimited swap.
$ docker create -it --storage-opt size=120G fedora /bin/bash
This (size) will allow to set the container rootfs size to 120G at creation time. User cannot pass a size less than the Default BaseFS Size.
This option is only available for the `devicemapper`, `btrfs`, and `zfs` graph drivers.
This (size) will allow to set the container rootfs size to 120G at creation time.
This option is only available for the `devicemapper`, `btrfs`, `overlay2` and `zfs` graph drivers.
For the `devicemapper`, `btrfs` and `zfs` storage drivers, user cannot pass a size less than the Default BaseFS Size.
For the `overlay2` storage driver, the size option is only available if the backing fs is `xfs` and mounted with the `pquota` mount option.
Under these conditions, user can pass any size less then the backing fs size.
**--stop-signal**=*SIGTERM*
Signal to stop a container. Default is SIGTERM.

View File

@ -493,8 +493,11 @@ incompatible with any restart policy other than `none`.
$ docker run -it --storage-opt size=120G fedora /bin/bash
This (size) will allow to set the container rootfs size to 120G at creation time. User cannot pass a size less than the Default BaseFS Size.
This option is only available for the `devicemapper`, `btrfs`, and `zfs` graph drivers.
This (size) will allow to set the container rootfs size to 120G at creation time.
This option is only available for the `devicemapper`, `btrfs`, `overlay2` and `zfs` graph drivers.
For the `devicemapper`, `btrfs` and `zfs` storage drivers, user cannot pass a size less than the Default BaseFS Size.
For the `overlay2` storage driver, the size option is only available if the backing fs is `xfs` and mounted with the `pquota` mount option.
Under these conditions, user can pass any size less then the backing fs size.
**--stop-signal**=*SIGTERM*
Signal to stop a container. Default is SIGTERM.