Skip to content

Commit b47ff77

Browse files
committed
Merge pull request moby#9006 from snitm/thin-pool-improvements
Thin pool improvements
2 parents 75b4746 + b9f1b0a commit b47ff77

File tree

4 files changed

+58
-9
lines changed

4 files changed

+58
-9
lines changed

daemon/graphdriver/devmapper/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,25 @@ Here is the list of supported options:
100100

101101
``docker -d --storage-opt dm.mountopt=nodiscard``
102102

103+
* `dm.thinpooldev`
104+
105+
Specifies a custom blockdevice to use for the thin pool.
106+
107+
If using a block device for device mapper storage, ideally lvm2
108+
would be used to create/manage the thin-pool volume that is then
109+
handed to docker to exclusively create/manage the thin and thin
110+
snapshot volumes needed for it's containers. Managing the thin-pool
111+
outside of docker makes for the most feature-rich method of having
112+
docker utilize device mapper thin provisioning as the backing
113+
storage for docker's containers. lvm2-based thin-pool management
114+
feature highlights include: automatic or interactive thin-pool
115+
resize support, dynamically change thin-pool features, automatic
116+
thinp metadata checking when lvm2 activates the thin-pool, etc.
117+
118+
Example use:
119+
120+
``docker -d --storage-opt dm.thinpooldev=/dev/mapper/thin-pool``
121+
103122
* `dm.datadev`
104123

105124
Specifies a custom blockdevice to use for data for the thin pool.

daemon/graphdriver/devmapper/deviceset.go

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ type DeviceSet struct {
8484
metadataDevice string
8585
doBlkDiscard bool
8686
thinpBlockSize uint32
87+
thinPoolDevice string
8788
}
8889

8990
type DiskUsage struct {
@@ -150,7 +151,10 @@ func (devices *DeviceSet) oldMetadataFile() string {
150151
}
151152

152153
func (devices *DeviceSet) getPoolName() string {
153-
return devices.devicePrefix + "-pool"
154+
if devices.thinPoolDevice == "" {
155+
return devices.devicePrefix + "-pool"
156+
}
157+
return devices.thinPoolDevice
154158
}
155159

156160
func (devices *DeviceSet) getPoolDevName() string {
@@ -411,7 +415,22 @@ func (devices *DeviceSet) setupBaseImage() error {
411415
}
412416
}
413417

414-
log.Debugf("Initializing base device-manager snapshot")
418+
if devices.thinPoolDevice != "" && oldInfo == nil {
419+
_, transactionId, dataUsed, _, _, _, err := devices.poolStatus()
420+
if err != nil {
421+
return err
422+
}
423+
if dataUsed != 0 {
424+
return fmt.Errorf("Unable to take ownership of thin-pool (%s) that already has used data blocks",
425+
devices.thinPoolDevice)
426+
}
427+
if transactionId != 0 {
428+
return fmt.Errorf("Unable to take ownership of thin-pool (%s) with non-zero transaction Id",
429+
devices.thinPoolDevice)
430+
}
431+
}
432+
433+
log.Debugf("Initializing base device-mapper thin volume")
415434

416435
id := devices.NextDeviceId
417436

@@ -430,7 +449,7 @@ func (devices *DeviceSet) setupBaseImage() error {
430449
return err
431450
}
432451

433-
log.Debugf("Creating filesystem on base device-manager snapshot")
452+
log.Debugf("Creating filesystem on base device-mapper thin volume")
434453

435454
if err = devices.activateDeviceIfNeeded(info); err != nil {
436455
return err
@@ -605,7 +624,7 @@ func (devices *DeviceSet) initDevmapper(doInit bool) error {
605624
devices.devicePrefix = fmt.Sprintf("docker-%d:%d-%d", major(sysSt.Dev), minor(sysSt.Dev), sysSt.Ino)
606625
log.Debugf("Generated prefix: %s", devices.devicePrefix)
607626

608-
// Check for the existence of the device <prefix>-pool
627+
// Check for the existence of the thin-pool device
609628
log.Debugf("Checking for existence of the pool '%s'", devices.getPoolName())
610629
info, err := devicemapper.GetInfo(devices.getPoolName())
611630
if info == nil {
@@ -624,7 +643,7 @@ func (devices *DeviceSet) initDevmapper(doInit bool) error {
624643
createdLoopback := false
625644

626645
// If the pool doesn't exist, create it
627-
if info.Exists == 0 {
646+
if info.Exists == 0 && devices.thinPoolDevice == "" {
628647
log.Debugf("Pool doesn't exist. Creating it.")
629648

630649
var (
@@ -988,8 +1007,10 @@ func (devices *DeviceSet) Shutdown() error {
9881007
}
9891008

9901009
devices.Lock()
991-
if err := devices.deactivatePool(); err != nil {
992-
log.Debugf("Shutdown deactivate pool , error: %s", err)
1010+
if devices.thinPoolDevice == "" {
1011+
if err := devices.deactivatePool(); err != nil {
1012+
log.Debugf("Shutdown deactivate pool , error: %s", err)
1013+
}
9931014
}
9941015

9951016
devices.saveDeviceSetMetaData()
@@ -1275,6 +1296,8 @@ func NewDeviceSet(root string, doInit bool, options []string) (*DeviceSet, error
12751296
devices.metadataDevice = val
12761297
case "dm.datadev":
12771298
devices.dataDevice = val
1299+
case "dm.thinpooldev":
1300+
devices.thinPoolDevice = strings.TrimPrefix(val, "/dev/mapper/")
12781301
case "dm.blkdiscard":
12791302
foundBlkDiscard = true
12801303
devices.doBlkDiscard, err = strconv.ParseBool(val)
@@ -1294,7 +1317,7 @@ func NewDeviceSet(root string, doInit bool, options []string) (*DeviceSet, error
12941317
}
12951318

12961319
// By default, don't do blk discard hack on raw devices, its rarely useful and is expensive
1297-
if !foundBlkDiscard && devices.dataDevice != "" {
1320+
if !foundBlkDiscard && (devices.dataDevice != "" || devices.thinPoolDevice != "") {
12981321
devices.doBlkDiscard = false
12991322
}
13001323

pkg/devicemapper/devmapper.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,8 @@ func CreatePool(poolName string, dataFile, metadataFile *os.File, poolBlockSize
384384
}
385385

386386
var cookie uint = 0
387-
if err := task.SetCookie(&cookie, 0); err != nil {
387+
var flags uint16 = DmUdevDisableSubsystemRulesFlag | DmUdevDisableDiskRulesFlag | DmUdevDisableOtherRulesFlag
388+
if err := task.SetCookie(&cookie, flags); err != nil {
388389
return fmt.Errorf("Can't set cookie %s", err)
389390
}
390391
defer UdevWait(cookie)

pkg/devicemapper/devmapper_wrapper.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ const (
8282
LoNameSize = C.LO_NAME_SIZE
8383
)
8484

85+
const (
86+
DmUdevDisableSubsystemRulesFlag = C.DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG
87+
DmUdevDisableDiskRulesFlag = C.DM_UDEV_DISABLE_DISK_RULES_FLAG
88+
DmUdevDisableOtherRulesFlag = C.DM_UDEV_DISABLE_OTHER_RULES_FLAG
89+
)
90+
8591
var (
8692
DmGetLibraryVersion = dmGetLibraryVersionFct
8793
DmGetNextTarget = dmGetNextTargetFct

0 commit comments

Comments
 (0)