浏览代码

Try to resize data and metadata loopback file when initiating devicemapper

Signed-off-by: Chun Chen <ramichen@tencent.com>
Chun Chen 9 年之前
父节点
当前提交
2458452a3b

+ 1 - 1
daemon/graphdriver/btrfs/btrfs.go

@@ -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.

+ 15 - 2
daemon/graphdriver/devmapper/deviceset.go

@@ -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
 }

+ 39 - 0
daemon/graphdriver/devmapper/devmapper_test.go

@@ -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)
+	}
+}

+ 1 - 1
daemon/graphdriver/devmapper/driver.go

@@ -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 {

+ 10 - 10
daemon/graphdriver/fsdiff.go

@@ -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)

+ 1 - 1
daemon/graphdriver/overlay/overlay.go

@@ -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,
 	}
 }

+ 1 - 1
daemon/graphdriver/vfs/driver.go

@@ -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.

+ 1 - 1
daemon/graphdriver/zfs/zfs.go

@@ -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) {