Try to resize data and metadata loopback file when initiating devicemapper

Signed-off-by: Chun Chen <ramichen@tencent.com>
This commit is contained in:
Chun Chen 2015-09-24 09:21:28 +08:00
Родитель 4a6e8c8f3c
Коммит 2458452a3b
8 изменённых файлов: 69 добавлений и 17 удалений

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

@ -52,7 +52,7 @@ func Init(home string, options []string) (graphdriver.Driver, error) {
home: home,
}
return graphdriver.NaiveDiffDriver(driver), nil
return graphdriver.NewNaiveDiffDriver(driver), nil
}
// Driver contains information about the filesystem mounted.

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

@ -232,7 +232,7 @@ func (devices *DeviceSet) hasImage(name string) bool {
// ensureImage creates a sparse file of <size> bytes at the path
// <root>/devicemapper/<name>.
// If the file already exists, it does nothing.
// If the file already exists and new size is larger than its current size, it grows to the new size.
// Either way it returns the full path.
func (devices *DeviceSet) ensureImage(name string, size int64) (string, error) {
dirname := devices.loopbackDir()
@ -242,7 +242,7 @@ func (devices *DeviceSet) ensureImage(name string, size int64) (string, error) {
return "", err
}
if _, err := os.Stat(filename); err != nil {
if fi, err := os.Stat(filename); err != nil {
if !os.IsNotExist(err) {
return "", err
}
@ -256,6 +256,19 @@ func (devices *DeviceSet) ensureImage(name string, size int64) (string, error) {
if err := file.Truncate(size); err != nil {
return "", err
}
} else {
if fi.Size() < size {
file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, 0600)
if err != nil {
return "", err
}
defer file.Close()
if err := file.Truncate(size); err != nil {
return "", fmt.Errorf("Unable to grow loopback file %s: %v", filename, err)
}
} else if fi.Size() > size {
logrus.Warnf("Can't shrink loopback file %s", filename)
}
}
return filename, nil
}

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

@ -3,8 +3,10 @@
package devmapper
import (
"fmt"
"testing"
"github.com/docker/docker/daemon/graphdriver"
"github.com/docker/docker/daemon/graphdriver/graphtest"
)
@ -40,3 +42,40 @@ func TestDevmapperCreateSnap(t *testing.T) {
func TestDevmapperTeardown(t *testing.T) {
graphtest.PutDriver(t)
}
func TestDevmapperReduceLoopBackSize(t *testing.T) {
tenMB := int64(10 * 1024 * 1024)
testChangeLoopBackSize(t, -tenMB, defaultDataLoopbackSize, defaultMetaDataLoopbackSize)
}
func TestDevmapperIncreaseLoopBackSize(t *testing.T) {
tenMB := int64(10 * 1024 * 1024)
testChangeLoopBackSize(t, tenMB, defaultDataLoopbackSize+tenMB, defaultMetaDataLoopbackSize+tenMB)
}
func testChangeLoopBackSize(t *testing.T, delta, expectDataSize, expectMetaDataSize int64) {
driver := graphtest.GetDriver(t, "devicemapper").(*graphtest.Driver).Driver.(*graphdriver.NaiveDiffDriver).ProtoDriver.(*Driver)
defer graphtest.PutDriver(t)
// make sure data or metadata loopback size are the default size
if s := driver.DeviceSet.Status(); s.Data.Total != uint64(defaultDataLoopbackSize) || s.Metadata.Total != uint64(defaultMetaDataLoopbackSize) {
t.Fatalf("data or metadata loop back size is incorrect")
}
if err := driver.Cleanup(); err != nil {
t.Fatal(err)
}
//Reload
d, err := Init(driver.home, []string{
fmt.Sprintf("dm.loopdatasize=%d", defaultDataLoopbackSize+delta),
fmt.Sprintf("dm.loopmetadatasize=%d", defaultMetaDataLoopbackSize+delta),
})
if err != nil {
t.Fatalf("error creating devicemapper driver: %v", err)
}
driver = d.(*graphdriver.NaiveDiffDriver).ProtoDriver.(*Driver)
if s := driver.DeviceSet.Status(); s.Data.Total != uint64(expectDataSize) || s.Metadata.Total != uint64(expectMetaDataSize) {
t.Fatalf("data or metadata loop back size is incorrect")
}
if err := driver.Cleanup(); err != nil {
t.Fatal(err)
}
}

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

@ -57,7 +57,7 @@ func Init(home string, options []string) (graphdriver.Driver, error) {
home: home,
}
return graphdriver.NaiveDiffDriver(d), nil
return graphdriver.NewNaiveDiffDriver(d), nil
}
func (d *Driver) String() string {

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

@ -11,29 +11,29 @@ import (
"github.com/docker/docker/pkg/ioutils"
)
// naiveDiffDriver takes a ProtoDriver and adds the
// NaiveDiffDriver takes a ProtoDriver and adds the
// capability of the Diffing methods which it may or may not
// support on its own. See the comment on the exported
// NaiveDiffDriver function below.
// NewNaiveDiffDriver function below.
// Notably, the AUFS driver doesn't need to be wrapped like this.
type naiveDiffDriver struct {
type NaiveDiffDriver struct {
ProtoDriver
}
// NaiveDiffDriver returns a fully functional driver that wraps the
// NewNaiveDiffDriver returns a fully functional driver that wraps the
// given ProtoDriver and adds the capability of the following methods which
// it may or may not support on its own:
// Diff(id, parent string) (archive.Archive, error)
// Changes(id, parent string) ([]archive.Change, error)
// ApplyDiff(id, parent string, diff archive.Reader) (size int64, err error)
// DiffSize(id, parent string) (size int64, err error)
func NaiveDiffDriver(driver ProtoDriver) Driver {
return &naiveDiffDriver{ProtoDriver: driver}
func NewNaiveDiffDriver(driver ProtoDriver) Driver {
return &NaiveDiffDriver{ProtoDriver: driver}
}
// Diff produces an archive of the changes between the specified
// layer and its parent layer which may be "".
func (gdw *naiveDiffDriver) Diff(id, parent string) (arch archive.Archive, err error) {
func (gdw *NaiveDiffDriver) Diff(id, parent string) (arch archive.Archive, err error) {
driver := gdw.ProtoDriver
layerFs, err := driver.Get(id, "")
@ -84,7 +84,7 @@ func (gdw *naiveDiffDriver) Diff(id, parent string) (arch archive.Archive, err e
// Changes produces a list of changes between the specified layer
// and its parent layer. If parent is "", then all changes will be ADD changes.
func (gdw *naiveDiffDriver) Changes(id, parent string) ([]archive.Change, error) {
func (gdw *NaiveDiffDriver) Changes(id, parent string) ([]archive.Change, error) {
driver := gdw.ProtoDriver
layerFs, err := driver.Get(id, "")
@ -109,7 +109,7 @@ func (gdw *naiveDiffDriver) Changes(id, parent string) ([]archive.Change, error)
// ApplyDiff extracts the changeset from the given diff into the
// layer with the specified id and parent, returning the size of the
// new layer in bytes.
func (gdw *naiveDiffDriver) ApplyDiff(id, parent string, diff archive.Reader) (size int64, err error) {
func (gdw *NaiveDiffDriver) ApplyDiff(id, parent string, diff archive.Reader) (size int64, err error) {
driver := gdw.ProtoDriver
// Mount the root filesystem so we can apply the diff/layer.
@ -132,7 +132,7 @@ func (gdw *naiveDiffDriver) ApplyDiff(id, parent string, diff archive.Reader) (s
// DiffSize calculates the changes between the specified layer
// and its parent and returns the size in bytes of the changes
// relative to its base filesystem directory.
func (gdw *naiveDiffDriver) DiffSize(id, parent string) (size int64, err error) {
func (gdw *NaiveDiffDriver) DiffSize(id, parent string) (size int64, err error) {
driver := gdw.ProtoDriver
changes, err := gdw.Changes(id, parent)

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

@ -43,7 +43,7 @@ type naiveDiffDriverWithApply struct {
// NaiveDiffDriverWithApply returns a NaiveDiff driver with custom ApplyDiff.
func NaiveDiffDriverWithApply(driver ApplyDiffProtoDriver) graphdriver.Driver {
return &naiveDiffDriverWithApply{
Driver: graphdriver.NaiveDiffDriver(driver),
Driver: graphdriver.NewNaiveDiffDriver(driver),
applyDiff: driver,
}
}

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

@ -23,7 +23,7 @@ func Init(home string, options []string) (graphdriver.Driver, error) {
d := &Driver{
home: home,
}
return graphdriver.NaiveDiffDriver(d), nil
return graphdriver.NewNaiveDiffDriver(d), nil
}
// Driver holds information about the driver, home directory of the driver.

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

@ -103,7 +103,7 @@ func Init(base string, opt []string) (graphdriver.Driver, error) {
options: options,
filesystemsCache: filesystemsCache,
}
return graphdriver.NaiveDiffDriver(d), nil
return graphdriver.NewNaiveDiffDriver(d), nil
}
func parseOptions(opt []string) (zfsOptions, error) {