Add overlay2.size daemon storage-opt

This commit adds the overlay2.size option to the daemon daemon
storage opts.

The user can override this option by the "docker run --storage-opt"
options.

Signed-off-by: Dhawal Yogesh Bhanushali <dbhanushali@vmware.com>
This commit is contained in:
Dhawal Yogesh Bhanushali 2017-05-10 04:24:35 -07:00
Родитель bcc8b2bc47
Коммит a63d5bc035
1 изменённых файлов: 38 добавлений и 6 удалений

Просмотреть файл

@ -194,6 +194,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
ctr: graphdriver.NewRefCounter(graphdriver.NewFsChecker(graphdriver.FsMagicOverlay)), ctr: graphdriver.NewRefCounter(graphdriver.NewFsChecker(graphdriver.FsMagicOverlay)),
supportsDType: supportsDType, supportsDType: supportsDType,
locker: locker.New(), locker: locker.New(),
options: *opts,
} }
d.naiveDiff = graphdriver.NewNaiveDiffDriver(d, uidMaps, gidMaps) d.naiveDiff = graphdriver.NewNaiveDiffDriver(d, uidMaps, gidMaps)
@ -202,7 +203,12 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
// Try to enable project quota support over xfs. // Try to enable project quota support over xfs.
if d.quotaCtl, err = quota.NewControl(home); err == nil { if d.quotaCtl, err = quota.NewControl(home); err == nil {
projectQuotaSupported = true projectQuotaSupported = true
} else if opts.quota.Size > 0 {
return nil, fmt.Errorf("Storage option overlay2.size not supported. Filesystem does not support Project Quota: %v", err)
} }
} else if opts.quota.Size > 0 {
// if xfs is not the backing fs then error out if the storage-opt overlay2.size is used.
return nil, fmt.Errorf("Storage Option overlay2.size only supported for backingFS XFS. Found %v", backingFs)
} }
logrus.Debugf("backingFs=%s, projectQuotaSupported=%v", backingFs, projectQuotaSupported) logrus.Debugf("backingFs=%s, projectQuotaSupported=%v", backingFs, projectQuotaSupported)
@ -224,9 +230,14 @@ func parseOptions(options []string) (*overlayOptions, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
case "overlay2.size":
size, err := units.RAMInBytes(val)
if err != nil {
return nil, err
}
o.quota.Size = uint64(size)
default: default:
return nil, fmt.Errorf("overlay2: Unknown option %s\n", key) return nil, fmt.Errorf("overlay2: unknown option %s", key)
} }
} }
return o, nil return o, nil
@ -312,17 +323,38 @@ func (d *Driver) Cleanup() error {
// CreateReadWrite creates a layer that is writable for use as a container // CreateReadWrite creates a layer that is writable for use as a container
// file system. // file system.
func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error { func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
return d.Create(id, parent, opts) if opts != nil && len(opts.StorageOpt) != 0 && !projectQuotaSupported {
return fmt.Errorf("--storage-opt is supported only for overlay over xfs with 'pquota' mount option")
}
if opts == nil {
opts = &graphdriver.CreateOpts{
StorageOpt: map[string]string{},
}
}
if _, ok := opts.StorageOpt["size"]; !ok {
if opts.StorageOpt == nil {
opts.StorageOpt = map[string]string{}
}
opts.StorageOpt["size"] = strconv.FormatUint(d.options.quota.Size, 10)
}
return d.create(id, parent, opts)
} }
// Create is used to create the upper, lower, and merge directories required for overlay fs for a given id. // Create is used to create the upper, lower, and merge directories required for overlay fs for a given id.
// The parent filesystem is used to configure these directories for the overlay. // The parent filesystem is used to configure these directories for the overlay.
func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) (retErr error) { func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) (retErr error) {
if opts != nil && len(opts.StorageOpt) != 0 {
if opts != nil && len(opts.StorageOpt) != 0 && !projectQuotaSupported { if _, ok := opts.StorageOpt["size"]; ok {
return fmt.Errorf("--storage-opt is supported only for overlay over xfs with 'pquota' mount option") return fmt.Errorf("--storage-opt size is only supported for ReadWrite Layers")
}
} }
return d.create(id, parent, opts)
}
func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr error) {
dir := d.dir(id) dir := d.dir(id)
rootUID, rootGID, err := idtools.GetRootUIDGID(d.uidMaps, d.gidMaps) rootUID, rootGID, err := idtools.GetRootUIDGID(d.uidMaps, d.gidMaps)