Skip to content

Commit

Permalink
CLI flag for docker create(run) to change block device size.
Browse files Browse the repository at this point in the history
Signed-off-by: Shishir Mahajan <shishir.mahajan@redhat.com>
  • Loading branch information
Shishir Mahajan committed Mar 28, 2016
1 parent 35986d4 commit b16decf
Show file tree
Hide file tree
Showing 30 changed files with 228 additions and 72 deletions.
2 changes: 1 addition & 1 deletion contrib/docker-device-tool/device_tool.go
Expand Up @@ -137,7 +137,7 @@ func main() {
usage()
}

err := devices.AddDevice(args[1], args[2])
err := devices.AddDevice(args[1], args[2], nil)
if err != nil {
fmt.Println("Can't create snap device: ", err)
os.Exit(1)
Expand Down
4 changes: 3 additions & 1 deletion daemon/create.go
Expand Up @@ -84,6 +84,8 @@ func (daemon *Daemon) create(params types.ContainerCreateConfig) (retC *containe
return nil, err
}

container.HostConfig.StorageOpt = params.HostConfig.StorageOpt

// Set RWLayer for container after mount labels have been set
if err := daemon.setRWLayer(container); err != nil {
return nil, err
Expand Down Expand Up @@ -156,7 +158,7 @@ func (daemon *Daemon) setRWLayer(container *container.Container) error {
}
layerID = img.RootFS.ChainID()
}
rwLayer, err := daemon.layerStore.CreateRWLayer(container.ID, layerID, container.MountLabel, daemon.setupInitLayer)
rwLayer, err := daemon.layerStore.CreateRWLayer(container.ID, layerID, container.MountLabel, daemon.setupInitLayer, container.HostConfig.StorageOpt)
if err != nil {
return err
}
Expand Down
7 changes: 6 additions & 1 deletion daemon/graphdriver/aufs/aufs.go
Expand Up @@ -195,7 +195,12 @@ func (a *Driver) Exists(id string) bool {

// Create three folders for each id
// mnt, layers, and diff
func (a *Driver) Create(id, parent, mountLabel string) error {
func (a *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) error {

if len(storageOpt) != 0 {
return fmt.Errorf("--storage-opt is not supported for aufs")
}

if err := a.createDirsFor(id); err != nil {
return err
}
Expand Down
58 changes: 29 additions & 29 deletions daemon/graphdriver/aufs/aufs_test.go
Expand Up @@ -101,7 +101,7 @@ func TestCreateNewDir(t *testing.T) {
d := newDriver(t)
defer os.RemoveAll(tmp)

if err := d.Create("1", "", ""); err != nil {
if err := d.Create("1", "", "", nil); err != nil {
t.Fatal(err)
}
}
Expand All @@ -110,7 +110,7 @@ func TestCreateNewDirStructure(t *testing.T) {
d := newDriver(t)
defer os.RemoveAll(tmp)

if err := d.Create("1", "", ""); err != nil {
if err := d.Create("1", "", "", nil); err != nil {
t.Fatal(err)
}

Expand All @@ -131,7 +131,7 @@ func TestRemoveImage(t *testing.T) {
d := newDriver(t)
defer os.RemoveAll(tmp)

if err := d.Create("1", "", ""); err != nil {
if err := d.Create("1", "", "", nil); err != nil {
t.Fatal(err)
}

Expand All @@ -156,7 +156,7 @@ func TestGetWithoutParent(t *testing.T) {
d := newDriver(t)
defer os.RemoveAll(tmp)

if err := d.Create("1", "", ""); err != nil {
if err := d.Create("1", "", "", nil); err != nil {
t.Fatal(err)
}

Expand All @@ -183,7 +183,7 @@ func TestCleanupWithDir(t *testing.T) {
d := newDriver(t)
defer os.RemoveAll(tmp)

if err := d.Create("1", "", ""); err != nil {
if err := d.Create("1", "", "", nil); err != nil {
t.Fatal(err)
}

Expand All @@ -196,7 +196,7 @@ func TestMountedFalseResponse(t *testing.T) {
d := newDriver(t)
defer os.RemoveAll(tmp)

if err := d.Create("1", "", ""); err != nil {
if err := d.Create("1", "", "", nil); err != nil {
t.Fatal(err)
}

Expand All @@ -215,10 +215,10 @@ func TestMountedTrueReponse(t *testing.T) {
defer os.RemoveAll(tmp)
defer d.Cleanup()

if err := d.Create("1", "", ""); err != nil {
if err := d.Create("1", "", "", nil); err != nil {
t.Fatal(err)
}
if err := d.Create("2", "1", ""); err != nil {
if err := d.Create("2", "1", "", nil); err != nil {
t.Fatal(err)
}

Expand All @@ -241,10 +241,10 @@ func TestMountWithParent(t *testing.T) {
d := newDriver(t)
defer os.RemoveAll(tmp)

if err := d.Create("1", "", ""); err != nil {
if err := d.Create("1", "", "", nil); err != nil {
t.Fatal(err)
}
if err := d.Create("2", "1", ""); err != nil {
if err := d.Create("2", "1", "", nil); err != nil {
t.Fatal(err)
}

Expand Down Expand Up @@ -272,10 +272,10 @@ func TestRemoveMountedDir(t *testing.T) {
d := newDriver(t)
defer os.RemoveAll(tmp)

if err := d.Create("1", "", ""); err != nil {
if err := d.Create("1", "", "", nil); err != nil {
t.Fatal(err)
}
if err := d.Create("2", "1", ""); err != nil {
if err := d.Create("2", "1", "", nil); err != nil {
t.Fatal(err)
}

Expand Down Expand Up @@ -311,7 +311,7 @@ func TestCreateWithInvalidParent(t *testing.T) {
d := newDriver(t)
defer os.RemoveAll(tmp)

if err := d.Create("1", "docker", ""); err == nil {
if err := d.Create("1", "docker", "", nil); err == nil {
t.Fatalf("Error should not be nil with parent does not exist")
}
}
Expand All @@ -320,7 +320,7 @@ func TestGetDiff(t *testing.T) {
d := newDriver(t)
defer os.RemoveAll(tmp)

if err := d.Create("1", "", ""); err != nil {
if err := d.Create("1", "", "", nil); err != nil {
t.Fatal(err)
}

Expand Down Expand Up @@ -354,10 +354,10 @@ func TestChanges(t *testing.T) {
d := newDriver(t)
defer os.RemoveAll(tmp)

if err := d.Create("1", "", ""); err != nil {
if err := d.Create("1", "", "", nil); err != nil {
t.Fatal(err)
}
if err := d.Create("2", "1", ""); err != nil {
if err := d.Create("2", "1", "", nil); err != nil {
t.Fatal(err)
}

Expand Down Expand Up @@ -403,7 +403,7 @@ func TestChanges(t *testing.T) {
t.Fatalf("Change kind should be ChangeAdd got %s", change.Kind)
}

if err := d.Create("3", "2", ""); err != nil {
if err := d.Create("3", "2", "", nil); err != nil {
t.Fatal(err)
}
mntPoint, err = d.Get("3", "")
Expand Down Expand Up @@ -448,7 +448,7 @@ func TestDiffSize(t *testing.T) {
d := newDriver(t)
defer os.RemoveAll(tmp)

if err := d.Create("1", "", ""); err != nil {
if err := d.Create("1", "", "", nil); err != nil {
t.Fatal(err)
}

Expand Down Expand Up @@ -490,7 +490,7 @@ func TestChildDiffSize(t *testing.T) {
defer os.RemoveAll(tmp)
defer d.Cleanup()

if err := d.Create("1", "", ""); err != nil {
if err := d.Create("1", "", "", nil); err != nil {
t.Fatal(err)
}

Expand Down Expand Up @@ -526,7 +526,7 @@ func TestChildDiffSize(t *testing.T) {
t.Fatalf("Expected size to be %d got %d", size, diffSize)
}

if err := d.Create("2", "1", ""); err != nil {
if err := d.Create("2", "1", "", nil); err != nil {
t.Fatal(err)
}

Expand All @@ -545,7 +545,7 @@ func TestExists(t *testing.T) {
defer os.RemoveAll(tmp)
defer d.Cleanup()

if err := d.Create("1", "", ""); err != nil {
if err := d.Create("1", "", "", nil); err != nil {
t.Fatal(err)
}

Expand All @@ -563,7 +563,7 @@ func TestStatus(t *testing.T) {
defer os.RemoveAll(tmp)
defer d.Cleanup()

if err := d.Create("1", "", ""); err != nil {
if err := d.Create("1", "", "", nil); err != nil {
t.Fatal(err)
}

Expand Down Expand Up @@ -592,7 +592,7 @@ func TestApplyDiff(t *testing.T) {
defer os.RemoveAll(tmp)
defer d.Cleanup()

if err := d.Create("1", "", ""); err != nil {
if err := d.Create("1", "", "", nil); err != nil {
t.Fatal(err)
}

Expand All @@ -618,10 +618,10 @@ func TestApplyDiff(t *testing.T) {
t.Fatal(err)
}

if err := d.Create("2", "", ""); err != nil {
if err := d.Create("2", "", "", nil); err != nil {
t.Fatal(err)
}
if err := d.Create("3", "2", ""); err != nil {
if err := d.Create("3", "2", "", nil); err != nil {
t.Fatal(err)
}

Expand Down Expand Up @@ -671,7 +671,7 @@ func testMountMoreThan42Layers(t *testing.T, mountPath string) {
}
current = hash(current)

if err := d.Create(current, parent, ""); err != nil {
if err := d.Create(current, parent, "", nil); err != nil {
t.Logf("Current layer %d", i)
t.Error(err)
}
Expand Down Expand Up @@ -750,11 +750,11 @@ func BenchmarkConcurrentAccess(b *testing.B) {
ids = append(ids, stringid.GenerateNonCryptoID())
}

if err := d.Create(ids[0], "", ""); err != nil {
if err := d.Create(ids[0], "", "", nil); err != nil {
b.Fatal(err)
}

if err := d.Create(ids[1], ids[0], ""); err != nil {
if err := d.Create(ids[1], ids[0], "", nil); err != nil {
b.Fatal(err)
}

Expand All @@ -770,7 +770,7 @@ func BenchmarkConcurrentAccess(b *testing.B) {
for _, id := range ids {
go func(id string) {
defer outerGroup.Done()
if err := d.Create(id, parent, ""); err != nil {
if err := d.Create(id, parent, "", nil); err != nil {
b.Logf("Create %s failed", id)
chErr <- err
return
Expand Down
7 changes: 6 additions & 1 deletion daemon/graphdriver/btrfs/btrfs.go
Expand Up @@ -242,7 +242,12 @@ func (d *Driver) subvolumesDirID(id string) string {
}

// Create the filesystem with given id.
func (d *Driver) Create(id, parent, mountLabel string) error {
func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) error {

if len(storageOpt) != 0 {
return fmt.Errorf("--storage-opt is not supported for btrfs")
}

subvolumes := path.Join(d.home, "subvolumes")
rootUID, rootGID, err := idtools.GetRootUIDGID(d.uidMaps, d.gidMaps)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion daemon/graphdriver/btrfs/btrfs_test.go
Expand Up @@ -30,7 +30,7 @@ func TestBtrfsCreateSnap(t *testing.T) {

func TestBtrfsSubvolDelete(t *testing.T) {
d := graphtest.GetDriver(t, "btrfs")
if err := d.Create("test", "", ""); err != nil {
if err := d.Create("test", "", "", nil); err != nil {
t.Fatal(err)
}
defer graphtest.PutDriver(t)
Expand Down
54 changes: 50 additions & 4 deletions daemon/graphdriver/devmapper/deviceset.go
Expand Up @@ -839,7 +839,7 @@ func (devices *DeviceSet) createRegisterDevice(hash string) (*devInfo, error) {
return info, nil
}

func (devices *DeviceSet) createRegisterSnapDevice(hash string, baseInfo *devInfo) error {
func (devices *DeviceSet) createRegisterSnapDevice(hash string, baseInfo *devInfo, size uint64) error {
if err := devices.poolHasFreeSpace(); err != nil {
return err
}
Expand Down Expand Up @@ -878,7 +878,7 @@ func (devices *DeviceSet) createRegisterSnapDevice(hash string, baseInfo *devInf
break
}

if _, err := devices.registerDevice(deviceID, hash, baseInfo.Size, devices.OpenTransactionID); err != nil {
if _, err := devices.registerDevice(deviceID, hash, size, devices.OpenTransactionID); err != nil {
devicemapper.DeleteDevice(devices.getPoolDevName(), deviceID)
devices.markDeviceIDFree(deviceID)
logrus.Debugf("devmapper: Error registering device: %s", err)
Expand Down Expand Up @@ -1830,7 +1830,7 @@ func (devices *DeviceSet) initDevmapper(doInit bool) error {
}

// AddDevice adds a device and registers in the hash.
func (devices *DeviceSet) AddDevice(hash, baseHash string) error {
func (devices *DeviceSet) AddDevice(hash, baseHash string, storageOpt map[string]string) error {
logrus.Debugf("devmapper: AddDevice(hash=%s basehash=%s)", hash, baseHash)
defer logrus.Debugf("devmapper: AddDevice(hash=%s basehash=%s) END", hash, baseHash)

Expand All @@ -1856,10 +1856,56 @@ func (devices *DeviceSet) AddDevice(hash, baseHash string) error {
return fmt.Errorf("devmapper: device %s already exists. Deleted=%v", hash, info.Deleted)
}

if err := devices.createRegisterSnapDevice(hash, baseInfo); err != nil {
devinfo := &devInfo{}

if err := devices.parseStorageOpt(storageOpt, devinfo); err != nil {
return err
}

if devinfo.Size == 0 {
devinfo.Size = baseInfo.Size
}

if devinfo.Size < baseInfo.Size {
return fmt.Errorf("devmapper: Container size cannot be smaller than %s", units.HumanSize(float64(baseInfo.Size)))
}

if err := devices.createRegisterSnapDevice(hash, baseInfo, devinfo.Size); err != nil {
return err
}

// Grow the container rootfs.
if devinfo.Size > 0 {
info, err := devices.lookupDevice(hash)
if err != nil {
return err
}

if err := devices.growFS(info); err != nil {
return err
}
}

return nil
}

func (devices *DeviceSet) parseStorageOpt(storageOpt map[string]string, devinfo *devInfo) error {

// Read size to change the block device size 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
}
devinfo.Size = uint64(size)
default:
return fmt.Errorf("Unknown option %s", key)
}
}

return nil
}

Expand Down
4 changes: 2 additions & 2 deletions daemon/graphdriver/devmapper/driver.go
Expand Up @@ -118,8 +118,8 @@ func (d *Driver) Cleanup() error {
}

// Create adds a device with a given id and the parent.
func (d *Driver) Create(id, parent, mountLabel string) error {
if err := d.DeviceSet.AddDevice(id, parent); err != nil {
func (d *Driver) Create(id, parent, mountLabel string, storageOpt map[string]string) error {
if err := d.DeviceSet.AddDevice(id, parent, storageOpt); err != nil {
return err
}

Expand Down

0 comments on commit b16decf

Please sign in to comment.