Ver código fonte

Merge pull request #6645 from snitm/dmthinp-devel

Dmthinp devel
unclejack 11 anos atrás
pai
commit
2e4f99d99c

+ 9 - 0
daemon/graphdriver/devmapper/README.md

@@ -126,6 +126,15 @@ Here is the list of supported options:
 
 
     ``docker -d --storage-opt dm.datadev=/dev/sdb1 --storage-opt dm.metadatadev=/dev/sdc1``
     ``docker -d --storage-opt dm.datadev=/dev/sdb1 --storage-opt dm.metadatadev=/dev/sdc1``
 
 
+ *  `dm.blocksize`
+
+    Specifies a custom blocksize to use for the thin pool.  The default
+    blocksize is 512K.
+
+    Example use:
+
+    ``docker -d --storage-opt dm.blocksize=64K``
+
  *  `dm.blkdiscard`
  *  `dm.blkdiscard`
 
 
     Enables or disables the use of blkdiscard when removing
     Enables or disables the use of blkdiscard when removing

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

@@ -28,6 +28,7 @@ var (
 	DefaultDataLoopbackSize     int64  = 100 * 1024 * 1024 * 1024
 	DefaultDataLoopbackSize     int64  = 100 * 1024 * 1024 * 1024
 	DefaultMetaDataLoopbackSize int64  = 2 * 1024 * 1024 * 1024
 	DefaultMetaDataLoopbackSize int64  = 2 * 1024 * 1024 * 1024
 	DefaultBaseFsSize           uint64 = 10 * 1024 * 1024 * 1024
 	DefaultBaseFsSize           uint64 = 10 * 1024 * 1024 * 1024
+	DefaultThinpBlockSize       uint32 = 1024 // 512K = 1024 512b sectors
 )
 )
 
 
 type DevInfo struct {
 type DevInfo struct {
@@ -78,6 +79,7 @@ type DeviceSet struct {
 	dataDevice           string
 	dataDevice           string
 	metadataDevice       string
 	metadataDevice       string
 	doBlkDiscard         bool
 	doBlkDiscard         bool
+	thinpBlockSize       uint32
 }
 }
 
 
 type DiskUsage struct {
 type DiskUsage struct {
@@ -510,7 +512,7 @@ func (devices *DeviceSet) ResizePool(size int64) error {
 	}
 	}
 
 
 	// Reload with the new block sizes
 	// Reload with the new block sizes
-	if err := reloadPool(devices.getPoolName(), dataloopback, metadataloopback); err != nil {
+	if err := reloadPool(devices.getPoolName(), dataloopback, metadataloopback, devices.thinpBlockSize); err != nil {
 		return fmt.Errorf("Unable to reload pool: %s", err)
 		return fmt.Errorf("Unable to reload pool: %s", err)
 	}
 	}
 
 
@@ -640,7 +642,7 @@ func (devices *DeviceSet) initDevmapper(doInit bool) error {
 		}
 		}
 		defer metadataFile.Close()
 		defer metadataFile.Close()
 
 
-		if err := createPool(devices.getPoolName(), dataFile, metadataFile); err != nil {
+		if err := createPool(devices.getPoolName(), dataFile, metadataFile, devices.thinpBlockSize); err != nil {
 			return err
 			return err
 		}
 		}
 	}
 	}
@@ -1159,6 +1161,7 @@ func NewDeviceSet(root string, doInit bool, options []string) (*DeviceSet, error
 		baseFsSize:           DefaultBaseFsSize,
 		baseFsSize:           DefaultBaseFsSize,
 		filesystem:           "ext4",
 		filesystem:           "ext4",
 		doBlkDiscard:         true,
 		doBlkDiscard:         true,
+		thinpBlockSize:       DefaultThinpBlockSize,
 	}
 	}
 
 
 	foundBlkDiscard := false
 	foundBlkDiscard := false
@@ -1170,19 +1173,19 @@ func NewDeviceSet(root string, doInit bool, options []string) (*DeviceSet, error
 		key = strings.ToLower(key)
 		key = strings.ToLower(key)
 		switch key {
 		switch key {
 		case "dm.basesize":
 		case "dm.basesize":
-			size, err := units.FromHumanSize(val)
+			size, err := units.RAMInBytes(val)
 			if err != nil {
 			if err != nil {
 				return nil, err
 				return nil, err
 			}
 			}
 			devices.baseFsSize = uint64(size)
 			devices.baseFsSize = uint64(size)
 		case "dm.loopdatasize":
 		case "dm.loopdatasize":
-			size, err := units.FromHumanSize(val)
+			size, err := units.RAMInBytes(val)
 			if err != nil {
 			if err != nil {
 				return nil, err
 				return nil, err
 			}
 			}
 			devices.dataLoopbackSize = size
 			devices.dataLoopbackSize = size
 		case "dm.loopmetadatasize":
 		case "dm.loopmetadatasize":
-			size, err := units.FromHumanSize(val)
+			size, err := units.RAMInBytes(val)
 			if err != nil {
 			if err != nil {
 				return nil, err
 				return nil, err
 			}
 			}
@@ -1206,6 +1209,13 @@ func NewDeviceSet(root string, doInit bool, options []string) (*DeviceSet, error
 			if err != nil {
 			if err != nil {
 				return nil, err
 				return nil, err
 			}
 			}
+		case "dm.blocksize":
+			size, err := units.RAMInBytes(val)
+			if err != nil {
+				return nil, err
+			}
+			// convert to 512b sectors
+			devices.thinpBlockSize = uint32(size) >> 9
 		default:
 		default:
 			return nil, fmt.Errorf("Unknown option %s\n", key)
 			return nil, fmt.Errorf("Unknown option %s\n", key)
 		}
 		}

+ 4 - 4
daemon/graphdriver/devmapper/devmapper.go

@@ -328,7 +328,7 @@ func BlockDeviceDiscard(path string) error {
 }
 }
 
 
 // This is the programmatic example of "dmsetup create"
 // This is the programmatic example of "dmsetup create"
-func createPool(poolName string, dataFile, metadataFile *os.File) error {
+func createPool(poolName string, dataFile, metadataFile *os.File, poolBlockSize uint32) error {
 	task, err := createTask(DeviceCreate, poolName)
 	task, err := createTask(DeviceCreate, poolName)
 	if task == nil {
 	if task == nil {
 		return err
 		return err
@@ -339,7 +339,7 @@ func createPool(poolName string, dataFile, metadataFile *os.File) error {
 		return fmt.Errorf("Can't get data size %s", err)
 		return fmt.Errorf("Can't get data size %s", err)
 	}
 	}
 
 
-	params := metadataFile.Name() + " " + dataFile.Name() + " 128 32768 1 skip_block_zeroing"
+	params := fmt.Sprintf("%s %s %d 32768 1 skip_block_zeroing", metadataFile.Name(), dataFile.Name(), poolBlockSize)
 	if err := task.AddTarget(0, size/512, "thin-pool", params); err != nil {
 	if err := task.AddTarget(0, size/512, "thin-pool", params); err != nil {
 		return fmt.Errorf("Can't add target %s", err)
 		return fmt.Errorf("Can't add target %s", err)
 	}
 	}
@@ -358,7 +358,7 @@ func createPool(poolName string, dataFile, metadataFile *os.File) error {
 	return nil
 	return nil
 }
 }
 
 
-func reloadPool(poolName string, dataFile, metadataFile *os.File) error {
+func reloadPool(poolName string, dataFile, metadataFile *os.File, poolBlockSize uint32) error {
 	task, err := createTask(DeviceReload, poolName)
 	task, err := createTask(DeviceReload, poolName)
 	if task == nil {
 	if task == nil {
 		return err
 		return err
@@ -369,7 +369,7 @@ func reloadPool(poolName string, dataFile, metadataFile *os.File) error {
 		return fmt.Errorf("Can't get data size %s", err)
 		return fmt.Errorf("Can't get data size %s", err)
 	}
 	}
 
 
-	params := metadataFile.Name() + " " + dataFile.Name() + " 128 32768"
+	params := fmt.Sprintf("%s %s %d 32768 1 skip_block_zeroing", metadataFile.Name(), dataFile.Name(), poolBlockSize)
 	if err := task.AddTarget(0, size/512, "thin-pool", params); err != nil {
 	if err := task.AddTarget(0, size/512, "thin-pool", params); err != nil {
 		return fmt.Errorf("Can't add target %s", err)
 		return fmt.Errorf("Can't add target %s", err)
 	}
 	}

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

@@ -54,6 +54,7 @@ func (d *Driver) Status() [][2]string {
 
 
 	status := [][2]string{
 	status := [][2]string{
 		{"Pool Name", s.PoolName},
 		{"Pool Name", s.PoolName},
+		{"Pool Blocksize", fmt.Sprintf("%d Kb", s.SectorSize/1024)},
 		{"Data file", s.DataLoopback},
 		{"Data file", s.DataLoopback},
 		{"Metadata file", s.MetadataLoopback},
 		{"Metadata file", s.MetadataLoopback},
 		{"Data Space Used", fmt.Sprintf("%.1f Mb", float64(s.Data.Used)/(1024*1024))},
 		{"Data Space Used", fmt.Sprintf("%.1f Mb", float64(s.Data.Used)/(1024*1024))},

+ 5 - 3
pkg/units/size.go

@@ -58,11 +58,11 @@ func FromHumanSize(size string) (int64, error) {
 }
 }
 
 
 // Parses a human-readable string representing an amount of RAM
 // Parses a human-readable string representing an amount of RAM
-// in bytes, kibibytes, mebibytes or gibibytes, and returns the
-// number of bytes, or -1 if the string is unparseable.
+// in bytes, kibibytes, mebibytes, gibibytes, or tebibytes and
+// returns the number of bytes, or -1 if the string is unparseable.
 // Units are case-insensitive, and the 'b' suffix is optional.
 // Units are case-insensitive, and the 'b' suffix is optional.
 func RAMInBytes(size string) (bytes int64, err error) {
 func RAMInBytes(size string) (bytes int64, err error) {
-	re, error := regexp.Compile("^(\\d+)([kKmMgG])?[bB]?$")
+	re, error := regexp.Compile("^(\\d+)([kKmMgGtT])?[bB]?$")
 	if error != nil {
 	if error != nil {
 		return -1, error
 		return -1, error
 	}
 	}
@@ -86,6 +86,8 @@ func RAMInBytes(size string) (bytes int64, err error) {
 		memLimit *= 1024 * 1024
 		memLimit *= 1024 * 1024
 	} else if unit == "g" {
 	} else if unit == "g" {
 		memLimit *= 1024 * 1024 * 1024
 		memLimit *= 1024 * 1024 * 1024
+	} else if unit == "t" {
+		memLimit *= 1024 * 1024 * 1024 * 1024
 	}
 	}
 
 
 	return memLimit, nil
 	return memLimit, nil

+ 3 - 0
pkg/units/size_test.go

@@ -64,7 +64,10 @@ func TestRAMInBytes(t *testing.T) {
 	assertRAMInBytes(t, "32kb", false, 32*1024)
 	assertRAMInBytes(t, "32kb", false, 32*1024)
 	assertRAMInBytes(t, "32Kb", false, 32*1024)
 	assertRAMInBytes(t, "32Kb", false, 32*1024)
 	assertRAMInBytes(t, "32Mb", false, 32*1024*1024)
 	assertRAMInBytes(t, "32Mb", false, 32*1024*1024)
+	assertRAMInBytes(t, "32MB", false, 32*1024*1024)
 	assertRAMInBytes(t, "32Gb", false, 32*1024*1024*1024)
 	assertRAMInBytes(t, "32Gb", false, 32*1024*1024*1024)
+	assertRAMInBytes(t, "32G", false, 32*1024*1024*1024)
+	assertRAMInBytes(t, "32Tb", false, 32*1024*1024*1024*1024)
 
 
 	assertRAMInBytes(t, "", true, -1)
 	assertRAMInBytes(t, "", true, -1)
 	assertRAMInBytes(t, "hello", true, -1)
 	assertRAMInBytes(t, "hello", true, -1)