|
@@ -35,7 +35,7 @@ import (
|
|
|
var (
|
|
|
defaultDataLoopbackSize int64 = 100 * 1024 * 1024 * 1024
|
|
|
defaultMetaDataLoopbackSize int64 = 2 * 1024 * 1024 * 1024
|
|
|
- defaultBaseFsSize uint64 = 100 * 1024 * 1024 * 1024
|
|
|
+ defaultBaseFsSize uint64 = 10 * 1024 * 1024 * 1024
|
|
|
defaultThinpBlockSize uint32 = 128 // 64K = 128 512b sectors
|
|
|
defaultUdevSyncOverride = false
|
|
|
maxDeviceID = 0xffffff // 24 bit, pool limit
|
|
@@ -47,6 +47,7 @@ var (
|
|
|
driverDeferredRemovalSupport = false
|
|
|
enableDeferredRemoval = false
|
|
|
enableDeferredDeletion = false
|
|
|
+ userBaseSize = false
|
|
|
)
|
|
|
|
|
|
const deviceSetMetaFile string = "deviceset-metadata"
|
|
@@ -1056,6 +1057,80 @@ func (devices *DeviceSet) setupVerifyBaseImageUUIDFS(baseInfo *devInfo) error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
+func (devices *DeviceSet) checkGrowBaseDeviceFS(info *devInfo) error {
|
|
|
+
|
|
|
+ if !userBaseSize {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ if devices.baseFsSize < devices.getBaseDeviceSize() {
|
|
|
+ return fmt.Errorf("devmapper: Base device size cannot be smaller than %s", units.HumanSize(float64(devices.getBaseDeviceSize())))
|
|
|
+ }
|
|
|
+
|
|
|
+ if devices.baseFsSize == devices.getBaseDeviceSize() {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ info.lock.Lock()
|
|
|
+ defer info.lock.Unlock()
|
|
|
+
|
|
|
+ devices.Lock()
|
|
|
+ defer devices.Unlock()
|
|
|
+
|
|
|
+ info.Size = devices.baseFsSize
|
|
|
+
|
|
|
+ if err := devices.saveMetadata(info); err != nil {
|
|
|
+ // Try to remove unused device
|
|
|
+ delete(devices.Devices, info.Hash)
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ return devices.growFS(info)
|
|
|
+}
|
|
|
+
|
|
|
+func (devices *DeviceSet) growFS(info *devInfo) error {
|
|
|
+ if err := devices.activateDeviceIfNeeded(info, false); err != nil {
|
|
|
+ return fmt.Errorf("Error activating devmapper device: %s", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ defer devices.deactivateDevice(info)
|
|
|
+
|
|
|
+ fsMountPoint := "/run/docker/mnt"
|
|
|
+ if _, err := os.Stat(fsMountPoint); os.IsNotExist(err) {
|
|
|
+ if err := os.MkdirAll(fsMountPoint, 0700); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ defer os.RemoveAll(fsMountPoint)
|
|
|
+ }
|
|
|
+
|
|
|
+ options := ""
|
|
|
+ if devices.BaseDeviceFilesystem == "xfs" {
|
|
|
+ // XFS needs nouuid or it can't mount filesystems with the same fs
|
|
|
+ options = joinMountOptions(options, "nouuid")
|
|
|
+ }
|
|
|
+ options = joinMountOptions(options, devices.mountOptions)
|
|
|
+
|
|
|
+ if err := mount.Mount(info.DevName(), fsMountPoint, devices.BaseDeviceFilesystem, options); err != nil {
|
|
|
+ return fmt.Errorf("Error mounting '%s' on '%s': %s", info.DevName(), fsMountPoint, err)
|
|
|
+ }
|
|
|
+
|
|
|
+ defer syscall.Unmount(fsMountPoint, syscall.MNT_DETACH)
|
|
|
+
|
|
|
+ switch devices.BaseDeviceFilesystem {
|
|
|
+ case "ext4":
|
|
|
+ if out, err := exec.Command("resize2fs", info.DevName()).CombinedOutput(); err != nil {
|
|
|
+ return fmt.Errorf("Failed to grow rootfs:%v:%s", err, string(out))
|
|
|
+ }
|
|
|
+ case "xfs":
|
|
|
+ if out, err := exec.Command("xfs_growfs", info.DevName()).CombinedOutput(); err != nil {
|
|
|
+ return fmt.Errorf("Failed to grow rootfs:%v:%s", err, string(out))
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ return fmt.Errorf("Unsupported filesystem type %s", devices.BaseDeviceFilesystem)
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
func (devices *DeviceSet) setupBaseImage() error {
|
|
|
oldInfo, _ := devices.lookupDeviceWithLock("")
|
|
|
|
|
@@ -1069,9 +1144,8 @@ func (devices *DeviceSet) setupBaseImage() error {
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
- if devices.baseFsSize != defaultBaseFsSize && devices.baseFsSize != devices.getBaseDeviceSize() {
|
|
|
- logrus.Warnf("devmapper: Base device is already initialized to size %s, new value of base device size %s will not take effect",
|
|
|
- units.HumanSize(float64(devices.getBaseDeviceSize())), units.HumanSize(float64(devices.baseFsSize)))
|
|
|
+ if err := devices.checkGrowBaseDeviceFS(oldInfo); err != nil {
|
|
|
+ return err
|
|
|
}
|
|
|
|
|
|
return nil
|
|
@@ -2378,6 +2452,7 @@ func NewDeviceSet(root string, doInit bool, options []string, uidMaps, gidMaps [
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
+ userBaseSize = true
|
|
|
devices.baseFsSize = uint64(size)
|
|
|
case "dm.loopdatasize":
|
|
|
size, err := units.RAMInBytes(val)
|