New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for setting storage size on ZFS containers #21946

Merged
merged 3 commits into from Jun 8, 2016
Jump to file or symbol
Failed to load files and symbols.
+40 −11
Diff settings

Always

Just for now

Next

Add support for setting storage size on zfs containers

Now supports setting a containers storage size when using zfs as the
storage engine.  By passing in `--storage-opt size=<size>`, the created
container's storage size will be limited to the given size.  Note that
the way zfs works, the given specified storage size will be given in
addition to the base container size.

Example:

The node image reports a size of `671M` from `df -h` when started.
Setting `--storage-opt size=2G` will result in a drive the size of
`671M` + `2G`, `2.7G` in total.  Available space will be `2.0G`.

The storage size is achieved by setting the zfs option `quota` to the
given size on the zfs volume.

Signed-off-by: Ken Herner <kherner@progress.com>
  • Loading branch information...
kenXengineering authored and Ken Herner committed Apr 11, 2016
commit e91834043100a6ae3f80c21fd15daccc2f451528
@@ -250,11 +250,7 @@ func (d *Driver) CreateReadWrite(id, parent, mountLabel string, storageOpt map[s
// Create prepares the dataset and filesystem for the ZFS driver for the given id under the parent.
func (d *Driver) Create(id string, parent string, mountLabel string, storageOpt map[string]string) error {
if len(storageOpt) != 0 {
return fmt.Errorf("--storage-opt is not supported for zfs")
}
err := d.create(id, parent)
err := d.create(id, parent, storageOpt)
if err == nil {
return nil
}
@@ -273,22 +269,55 @@ func (d *Driver) Create(id string, parent string, mountLabel string, storageOpt
}
// retry
return d.create(id, parent)
return d.create(id, parent, storageOpt)
}
func (d *Driver) create(id, parent string) error {
func (d *Driver) create(id, parent string, storageOpt map[string]string) error {
name := d.zfsPath(id)
quota, err := parseStorageOpt(storageOpt)

This comment has been minimized.

@thaJeztah

thaJeztah Apr 30, 2016

Member

Should err be checked here?

This comment has been minimized.

@thaJeztah

thaJeztah Apr 30, 2016

Member

Perhaps return early on error (also below), because there's now a lot of nested if's (but that's just a suggestion)

if parent == "" {
mountoptions := map[string]string{"mountpoint": "legacy"}
fs, err := zfs.CreateFilesystem(name, mountoptions)
if err == nil {
d.Lock()
d.filesystemsCache[fs.Name] = true
d.Unlock()
err = setQuota(name, quota)
if err == nil {
d.Lock()
d.filesystemsCache[fs.Name] = true
d.Unlock()
}
}
return err
}
err = d.cloneFilesystem(name, d.zfsPath(parent))
if err == nil {
err = setQuota(name, quota)
}
return err
}
func parseStorageOpt(storageOpt map[string]string) (string, error) {
// Read size to change the disk quota per container
for k, v := range storageOpt {
key := strings.ToLower(k)
switch key {
case "size":
return v, nil
default:
return "0", fmt.Errorf("Unknown option %s", key)
}
}
return "0", nil
}
func setQuota(name string, quota string) error {
if quota == "0" {
return nil
}
fs, err := zfs.GetDataset(name)
if err != nil {
return err
}
return d.cloneFilesystem(name, d.zfsPath(parent))
return fs.SetProperty("quota", quota)
}
// Remove deletes the dataset, filesystem and the cache for the given id.
ProTip! Use n and p to navigate between commits in a pull request.