daemon/graphdriver/devmapper/ fix lint errors/warnings

Addresses #14756
Signed-off-by: Srini Brahmaroutu <srbrahma@us.ibm.com>
This commit is contained in:
Srini Brahmaroutu 2015-07-23 00:42:28 +00:00
parent f809037128
commit 972a94b449
5 changed files with 245 additions and 197 deletions

View File

@ -27,35 +27,35 @@ import (
) )
var ( 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 = 100 * 1024 * 1024 * 1024 defaultBaseFsSize uint64 = 100 * 1024 * 1024 * 1024
DefaultThinpBlockSize uint32 = 128 // 64K = 128 512b sectors defaultThinpBlockSize uint32 = 128 // 64K = 128 512b sectors
DefaultUdevSyncOverride bool = false defaultUdevSyncOverride = false
MaxDeviceId int = 0xffffff // 24 bit, pool limit maxDeviceID = 0xffffff // 24 bit, pool limit
DeviceIdMapSz int = (MaxDeviceId + 1) / 8 deviceIDMapSz = (maxDeviceID + 1) / 8
// We retry device removal so many a times that even error messages // We retry device removal so many a times that even error messages
// will fill up console during normal operation. So only log Fatal // will fill up console during normal operation. So only log Fatal
// messages by default. // messages by default.
DMLogLevel int = devicemapper.LogLevelFatal logLevel = devicemapper.LogLevelFatal
DriverDeferredRemovalSupport bool = false driverDeferredRemovalSupport = false
EnableDeferredRemoval bool = false enableDeferredRemoval = false
) )
const deviceSetMetaFile string = "deviceset-metadata" const deviceSetMetaFile string = "deviceset-metadata"
const transactionMetaFile string = "transaction-metadata" const transactionMetaFile string = "transaction-metadata"
type Transaction struct { type transaction struct {
OpenTransactionId uint64 `json:"open_transaction_id"` OpenTransactionID uint64 `json:"open_transaction_id"`
DeviceIdHash string `json:"device_hash"` DeviceIDHash string `json:"device_hash"`
DeviceId int `json:"device_id"` DeviceID int `json:"device_id"`
} }
type DevInfo struct { type devInfo struct {
Hash string `json:"-"` Hash string `json:"-"`
DeviceId int `json:"device_id"` DeviceID int `json:"device_id"`
Size uint64 `json:"size"` Size uint64 `json:"size"`
TransactionId uint64 `json:"transaction_id"` TransactionID uint64 `json:"transaction_id"`
Initialized bool `json:"initialized"` Initialized bool `json:"initialized"`
devices *DeviceSet devices *DeviceSet
@ -75,19 +75,20 @@ type DevInfo struct {
lock sync.Mutex lock sync.Mutex
} }
type MetaData struct { type metaData struct {
Devices map[string]*DevInfo `json:"Devices"` Devices map[string]*devInfo `json:"Devices"`
devicesLock sync.Mutex // Protects all read/writes to Devices map devicesLock sync.Mutex // Protects all read/writes to Devices map
} }
// DeviceSet holds information about list of devices
type DeviceSet struct { type DeviceSet struct {
MetaData `json:"-"` metaData `json:"-"`
sync.Mutex `json:"-"` // Protects Devices map and serializes calls into libdevmapper sync.Mutex `json:"-"` // Protects Devices map and serializes calls into libdevmapper
root string root string
devicePrefix string devicePrefix string
TransactionId uint64 `json:"-"` TransactionID uint64 `json:"-"`
NextDeviceId int `json:"next_device_id"` NextDeviceID int `json:"next_device_id"`
deviceIdMap []byte deviceIDMap []byte
// Options // Options
dataLoopbackSize int64 dataLoopbackSize int64
@ -103,44 +104,66 @@ type DeviceSet struct {
doBlkDiscard bool doBlkDiscard bool
thinpBlockSize uint32 thinpBlockSize uint32
thinPoolDevice string thinPoolDevice string
Transaction `json:"-"` transaction `json:"-"`
overrideUdevSyncCheck bool overrideUdevSyncCheck bool
deferredRemove bool // use deferred removal deferredRemove bool // use deferred removal
BaseDeviceUUID string //save UUID of base device BaseDeviceUUID string //save UUID of base device
} }
// DiskUsage contains information about disk usage and is used when reporting Status of a device.
type DiskUsage struct { type DiskUsage struct {
Used uint64 // Used bytes on the disk.
Total uint64 Used uint64
// Total bytes on the disk.
Total uint64
// Available bytes on the disk.
Available uint64 Available uint64
} }
// Status returns the information about the device.
type Status struct { type Status struct {
PoolName string // PoolName is the name of the data pool.
DataFile string // actual block device for data PoolName string
DataLoopback string // loopback file, if used // DataFile is the actual block device for data.
MetadataFile string // actual block device for metadata DataFile string
MetadataLoopback string // loopback file, if used // DataLoopback loopback file, if used.
Data DiskUsage DataLoopback string
Metadata DiskUsage // MetadataFile is the actual block device for metadata.
SectorSize uint64 MetadataFile string
UdevSyncSupported bool // MetadataLoopback is the loopback file, if used.
MetadataLoopback string
// Data is the disk used for data.
Data DiskUsage
// Metadata is the disk used for meta data.
Metadata DiskUsage
// SectorSize size of the vector.
SectorSize uint64
// UdevSyncSupported is true if sync is supported.
UdevSyncSupported bool
// DeferredRemoveEnabled is true then the device is not unmounted.
DeferredRemoveEnabled bool DeferredRemoveEnabled bool
} }
// Structure used to export image/container metadata in docker inspect. // Structure used to export image/container metadata in docker inspect.
type DeviceMetadata struct { type deviceMetadata struct {
deviceId int deviceID int
deviceSize uint64 // size in bytes deviceSize uint64 // size in bytes
deviceName string // Device name as used during activation deviceName string // Device name as used during activation
} }
// DevStatus returns information about device mounted containing its id, size and sector information.
type DevStatus struct { type DevStatus struct {
DeviceId int // DeviceID is the id of the device.
Size uint64 DeviceID int
TransactionId uint64 // Size is the size of the filesystem.
SizeInSectors uint64 Size uint64
MappedSectors uint64 // TransactionID is a unique integer per device set used to identify an operation on the file system, this number is incremental.
TransactionID uint64
// SizeInSectors indicates the size of the sectors allocated.
SizeInSectors uint64
// MappedSectors indicates number of mapped sectors.
MappedSectors uint64
// HighestMappedSector is the pointer to the highest mapped sector.
HighestMappedSector uint64 HighestMappedSector uint64
} }
@ -148,7 +171,7 @@ func getDevName(name string) string {
return "/dev/mapper/" + name return "/dev/mapper/" + name
} }
func (info *DevInfo) Name() string { func (info *devInfo) Name() string {
hash := info.Hash hash := info.Hash
if hash == "" { if hash == "" {
hash = "base" hash = "base"
@ -156,7 +179,7 @@ func (info *DevInfo) Name() string {
return fmt.Sprintf("%s-%s", info.devices.devicePrefix, hash) return fmt.Sprintf("%s-%s", info.devices.devicePrefix, hash)
} }
func (info *DevInfo) DevName() string { func (info *devInfo) DevName() string {
return getDevName(info.Name()) return getDevName(info.Name())
} }
@ -168,7 +191,7 @@ func (devices *DeviceSet) metadataDir() string {
return path.Join(devices.root, "metadata") return path.Join(devices.root, "metadata")
} }
func (devices *DeviceSet) metadataFile(info *DevInfo) string { func (devices *DeviceSet) metadataFile(info *devInfo) string {
file := info.Hash file := info.Hash
if file == "" { if file == "" {
file = "base" file = "base"
@ -237,20 +260,20 @@ func (devices *DeviceSet) ensureImage(name string, size int64) (string, error) {
return filename, nil return filename, nil
} }
func (devices *DeviceSet) allocateTransactionId() uint64 { func (devices *DeviceSet) allocateTransactionID() uint64 {
devices.OpenTransactionId = devices.TransactionId + 1 devices.OpenTransactionID = devices.TransactionID + 1
return devices.OpenTransactionId return devices.OpenTransactionID
} }
func (devices *DeviceSet) updatePoolTransactionId() error { func (devices *DeviceSet) updatePoolTransactionID() error {
if err := devicemapper.SetTransactionId(devices.getPoolDevName(), devices.TransactionId, devices.OpenTransactionId); err != nil { if err := devicemapper.SetTransactionId(devices.getPoolDevName(), devices.TransactionID, devices.OpenTransactionID); err != nil {
return fmt.Errorf("Error setting devmapper transaction ID: %s", err) return fmt.Errorf("Error setting devmapper transaction ID: %s", err)
} }
devices.TransactionId = devices.OpenTransactionId devices.TransactionID = devices.OpenTransactionID
return nil return nil
} }
func (devices *DeviceSet) removeMetadata(info *DevInfo) error { func (devices *DeviceSet) removeMetadata(info *devInfo) error {
if err := os.RemoveAll(devices.metadataFile(info)); err != nil { if err := os.RemoveAll(devices.metadataFile(info)); err != nil {
return fmt.Errorf("Error removing metadata file %s: %s", devices.metadataFile(info), err) return fmt.Errorf("Error removing metadata file %s: %s", devices.metadataFile(info), err)
} }
@ -284,7 +307,7 @@ func (devices *DeviceSet) writeMetaFile(jsonData []byte, filePath string) error
return nil return nil
} }
func (devices *DeviceSet) saveMetadata(info *DevInfo) error { func (devices *DeviceSet) saveMetadata(info *devInfo) error {
jsonData, err := json.Marshal(info) jsonData, err := json.Marshal(info)
if err != nil { if err != nil {
return fmt.Errorf("Error encoding metadata to json: %s", err) return fmt.Errorf("Error encoding metadata to json: %s", err)
@ -295,31 +318,31 @@ func (devices *DeviceSet) saveMetadata(info *DevInfo) error {
return nil return nil
} }
func (devices *DeviceSet) markDeviceIdUsed(deviceId int) { func (devices *DeviceSet) markDeviceIDUsed(deviceID int) {
var mask byte var mask byte
i := deviceId % 8 i := deviceID % 8
mask = 1 << uint(i) mask = 1 << uint(i)
devices.deviceIdMap[deviceId/8] = devices.deviceIdMap[deviceId/8] | mask devices.deviceIDMap[deviceID/8] = devices.deviceIDMap[deviceID/8] | mask
} }
func (devices *DeviceSet) markDeviceIdFree(deviceId int) { func (devices *DeviceSet) markDeviceIDFree(deviceID int) {
var mask byte var mask byte
i := deviceId % 8 i := deviceID % 8
mask = ^(1 << uint(i)) mask = ^(1 << uint(i))
devices.deviceIdMap[deviceId/8] = devices.deviceIdMap[deviceId/8] & mask devices.deviceIDMap[deviceID/8] = devices.deviceIDMap[deviceID/8] & mask
} }
func (devices *DeviceSet) isDeviceIdFree(deviceId int) bool { func (devices *DeviceSet) isDeviceIDFree(deviceID int) bool {
var mask byte var mask byte
i := deviceId % 8 i := deviceID % 8
mask = (1 << uint(i)) mask = (1 << uint(i))
if (devices.deviceIdMap[deviceId/8] & mask) != 0 { if (devices.deviceIDMap[deviceID/8] & mask) != 0 {
return false return false
} }
return true return true
} }
func (devices *DeviceSet) lookupDevice(hash string) (*DevInfo, error) { func (devices *DeviceSet) lookupDevice(hash string) (*devInfo, error) {
devices.devicesLock.Lock() devices.devicesLock.Lock()
defer devices.devicesLock.Unlock() defer devices.devicesLock.Unlock()
info := devices.Devices[hash] info := devices.Devices[hash]
@ -364,22 +387,22 @@ func (devices *DeviceSet) deviceFileWalkFunction(path string, finfo os.FileInfo)
return fmt.Errorf("Error loading device metadata file %s", hash) return fmt.Errorf("Error loading device metadata file %s", hash)
} }
if dinfo.DeviceId > MaxDeviceId { if dinfo.DeviceID > maxDeviceID {
logrus.Errorf("Ignoring Invalid DeviceId=%d", dinfo.DeviceId) logrus.Errorf("Ignoring Invalid DeviceID=%d", dinfo.DeviceID)
return nil return nil
} }
devices.Lock() devices.Lock()
devices.markDeviceIdUsed(dinfo.DeviceId) devices.markDeviceIDUsed(dinfo.DeviceID)
devices.Unlock() devices.Unlock()
logrus.Debugf("Added deviceId=%d to DeviceIdMap", dinfo.DeviceId) logrus.Debugf("Added deviceID=%d to DeviceIDMap", dinfo.DeviceID)
return nil return nil
} }
func (devices *DeviceSet) constructDeviceIdMap() error { func (devices *DeviceSet) constructDeviceIDMap() error {
logrus.Debugf("[deviceset] constructDeviceIdMap()") logrus.Debugf("[deviceset] constructDeviceIDMap()")
defer logrus.Debugf("[deviceset] constructDeviceIdMap() END") defer logrus.Debugf("[deviceset] constructDeviceIDMap() END")
var scan = func(path string, info os.FileInfo, err error) error { var scan = func(path string, info os.FileInfo, err error) error {
if err != nil { if err != nil {
@ -400,9 +423,9 @@ func (devices *DeviceSet) constructDeviceIdMap() error {
func (devices *DeviceSet) unregisterDevice(id int, hash string) error { func (devices *DeviceSet) unregisterDevice(id int, hash string) error {
logrus.Debugf("unregisterDevice(%v, %v)", id, hash) logrus.Debugf("unregisterDevice(%v, %v)", id, hash)
info := &DevInfo{ info := &devInfo{
Hash: hash, Hash: hash,
DeviceId: id, DeviceID: id,
} }
devices.devicesLock.Lock() devices.devicesLock.Lock()
@ -417,13 +440,13 @@ func (devices *DeviceSet) unregisterDevice(id int, hash string) error {
return nil return nil
} }
func (devices *DeviceSet) registerDevice(id int, hash string, size uint64, transactionId uint64) (*DevInfo, error) { func (devices *DeviceSet) registerDevice(id int, hash string, size uint64, transactionID uint64) (*devInfo, error) {
logrus.Debugf("registerDevice(%v, %v)", id, hash) logrus.Debugf("registerDevice(%v, %v)", id, hash)
info := &DevInfo{ info := &devInfo{
Hash: hash, Hash: hash,
DeviceId: id, DeviceID: id,
Size: size, Size: size,
TransactionId: transactionId, TransactionID: transactionID,
Initialized: false, Initialized: false,
devices: devices, devices: devices,
} }
@ -443,7 +466,7 @@ func (devices *DeviceSet) registerDevice(id int, hash string, size uint64, trans
return info, nil return info, nil
} }
func (devices *DeviceSet) activateDeviceIfNeeded(info *DevInfo) error { func (devices *DeviceSet) activateDeviceIfNeeded(info *devInfo) error {
logrus.Debugf("activateDeviceIfNeeded(%v)", info.Hash) logrus.Debugf("activateDeviceIfNeeded(%v)", info.Hash)
// Make sure deferred removal on device is canceled, if one was // Make sure deferred removal on device is canceled, if one was
@ -456,10 +479,10 @@ func (devices *DeviceSet) activateDeviceIfNeeded(info *DevInfo) error {
return nil return nil
} }
return devicemapper.ActivateDevice(devices.getPoolDevName(), info.Name(), info.DeviceId, info.Size) return devicemapper.ActivateDevice(devices.getPoolDevName(), info.Name(), info.DeviceID, info.Size)
} }
func (devices *DeviceSet) createFilesystem(info *DevInfo) error { func (devices *DeviceSet) createFilesystem(info *devInfo) error {
devname := info.DevName() devname := info.DevName()
args := []string{} args := []string{}
@ -500,7 +523,7 @@ func (devices *DeviceSet) migrateOldMetaData() error {
} }
if jsonData != nil { if jsonData != nil {
m := MetaData{Devices: make(map[string]*DevInfo)} m := metaData{Devices: make(map[string]*devInfo)}
if err := json.Unmarshal(jsonData, &m); err != nil { if err := json.Unmarshal(jsonData, &m); err != nil {
return err return err
@ -524,14 +547,14 @@ func (devices *DeviceSet) initMetaData() error {
return err return err
} }
_, transactionId, _, _, _, _, err := devices.poolStatus() _, transactionID, _, _, _, _, err := devices.poolStatus()
if err != nil { if err != nil {
return err return err
} }
devices.TransactionId = transactionId devices.TransactionID = transactionID
if err := devices.constructDeviceIdMap(); err != nil { if err := devices.constructDeviceIDMap(); err != nil {
return err return err
} }
@ -541,129 +564,129 @@ func (devices *DeviceSet) initMetaData() error {
return nil return nil
} }
func (devices *DeviceSet) incNextDeviceId() { func (devices *DeviceSet) incNextDeviceID() {
// Ids are 24bit, so wrap around // IDs are 24bit, so wrap around
devices.NextDeviceId = (devices.NextDeviceId + 1) & MaxDeviceId devices.NextDeviceID = (devices.NextDeviceID + 1) & maxDeviceID
} }
func (devices *DeviceSet) getNextFreeDeviceId() (int, error) { func (devices *DeviceSet) getNextFreeDeviceID() (int, error) {
devices.incNextDeviceId() devices.incNextDeviceID()
for i := 0; i <= MaxDeviceId; i++ { for i := 0; i <= maxDeviceID; i++ {
if devices.isDeviceIdFree(devices.NextDeviceId) { if devices.isDeviceIDFree(devices.NextDeviceID) {
devices.markDeviceIdUsed(devices.NextDeviceId) devices.markDeviceIDUsed(devices.NextDeviceID)
return devices.NextDeviceId, nil return devices.NextDeviceID, nil
} }
devices.incNextDeviceId() devices.incNextDeviceID()
} }
return 0, fmt.Errorf("Unable to find a free device Id") return 0, fmt.Errorf("Unable to find a free device ID")
} }
func (devices *DeviceSet) createRegisterDevice(hash string) (*DevInfo, error) { func (devices *DeviceSet) createRegisterDevice(hash string) (*devInfo, error) {
deviceId, err := devices.getNextFreeDeviceId() deviceID, err := devices.getNextFreeDeviceID()
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err := devices.openTransaction(hash, deviceId); err != nil { if err := devices.openTransaction(hash, deviceID); err != nil {
logrus.Debugf("Error opening transaction hash = %s deviceId = %d", hash, deviceId) logrus.Debugf("Error opening transaction hash = %s deviceID = %d", hash, deviceID)
devices.markDeviceIdFree(deviceId) devices.markDeviceIDFree(deviceID)
return nil, err return nil, err
} }
for { for {
if err := devicemapper.CreateDevice(devices.getPoolDevName(), deviceId); err != nil { if err := devicemapper.CreateDevice(devices.getPoolDevName(), deviceID); err != nil {
if devicemapper.DeviceIdExists(err) { if devicemapper.DeviceIdExists(err) {
// Device Id already exists. This should not // Device ID already exists. This should not
// happen. Now we have a mechianism to find // happen. Now we have a mechianism to find
// a free device Id. So something is not right. // a free device ID. So something is not right.
// Give a warning and continue. // Give a warning and continue.
logrus.Errorf("Device Id %d exists in pool but it is supposed to be unused", deviceId) logrus.Errorf("Device ID %d exists in pool but it is supposed to be unused", deviceID)
deviceId, err = devices.getNextFreeDeviceId() deviceID, err = devices.getNextFreeDeviceID()
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Save new device id into transaction // Save new device id into transaction
devices.refreshTransaction(deviceId) devices.refreshTransaction(deviceID)
continue continue
} }
logrus.Debugf("Error creating device: %s", err) logrus.Debugf("Error creating device: %s", err)
devices.markDeviceIdFree(deviceId) devices.markDeviceIDFree(deviceID)
return nil, err return nil, err
} }
break break
} }
logrus.Debugf("Registering device (id %v) with FS size %v", deviceId, devices.baseFsSize) logrus.Debugf("Registering device (id %v) with FS size %v", deviceID, devices.baseFsSize)
info, err := devices.registerDevice(deviceId, hash, devices.baseFsSize, devices.OpenTransactionId) info, err := devices.registerDevice(deviceID, hash, devices.baseFsSize, devices.OpenTransactionID)
if err != nil { if err != nil {
_ = devicemapper.DeleteDevice(devices.getPoolDevName(), deviceId) _ = devicemapper.DeleteDevice(devices.getPoolDevName(), deviceID)
devices.markDeviceIdFree(deviceId) devices.markDeviceIDFree(deviceID)
return nil, err return nil, err
} }
if err := devices.closeTransaction(); err != nil { if err := devices.closeTransaction(); err != nil {
devices.unregisterDevice(deviceId, hash) devices.unregisterDevice(deviceID, hash)
devicemapper.DeleteDevice(devices.getPoolDevName(), deviceId) devicemapper.DeleteDevice(devices.getPoolDevName(), deviceID)
devices.markDeviceIdFree(deviceId) devices.markDeviceIDFree(deviceID)
return nil, err return nil, err
} }
return info, nil return info, nil
} }
func (devices *DeviceSet) createRegisterSnapDevice(hash string, baseInfo *DevInfo) error { func (devices *DeviceSet) createRegisterSnapDevice(hash string, baseInfo *devInfo) error {
deviceId, err := devices.getNextFreeDeviceId() deviceID, err := devices.getNextFreeDeviceID()
if err != nil { if err != nil {
return err return err
} }
if err := devices.openTransaction(hash, deviceId); err != nil { if err := devices.openTransaction(hash, deviceID); err != nil {
logrus.Debugf("Error opening transaction hash = %s deviceId = %d", hash, deviceId) logrus.Debugf("Error opening transaction hash = %s deviceID = %d", hash, deviceID)
devices.markDeviceIdFree(deviceId) devices.markDeviceIDFree(deviceID)
return err return err
} }
for { for {
if err := devicemapper.CreateSnapDevice(devices.getPoolDevName(), deviceId, baseInfo.Name(), baseInfo.DeviceId); err != nil { if err := devicemapper.CreateSnapDevice(devices.getPoolDevName(), deviceID, baseInfo.Name(), baseInfo.DeviceID); err != nil {
if devicemapper.DeviceIdExists(err) { if devicemapper.DeviceIdExists(err) {
// Device Id already exists. This should not // Device ID already exists. This should not
// happen. Now we have a mechianism to find // happen. Now we have a mechianism to find
// a free device Id. So something is not right. // a free device ID. So something is not right.
// Give a warning and continue. // Give a warning and continue.
logrus.Errorf("Device Id %d exists in pool but it is supposed to be unused", deviceId) logrus.Errorf("Device ID %d exists in pool but it is supposed to be unused", deviceID)
deviceId, err = devices.getNextFreeDeviceId() deviceID, err = devices.getNextFreeDeviceID()
if err != nil { if err != nil {
return err return err
} }
// Save new device id into transaction // Save new device id into transaction
devices.refreshTransaction(deviceId) devices.refreshTransaction(deviceID)
continue continue
} }
logrus.Debugf("Error creating snap device: %s", err) logrus.Debugf("Error creating snap device: %s", err)
devices.markDeviceIdFree(deviceId) devices.markDeviceIDFree(deviceID)
return err return err
} }
break break
} }
if _, err := devices.registerDevice(deviceId, hash, baseInfo.Size, devices.OpenTransactionId); err != nil { if _, err := devices.registerDevice(deviceID, hash, baseInfo.Size, devices.OpenTransactionID); err != nil {
devicemapper.DeleteDevice(devices.getPoolDevName(), deviceId) devicemapper.DeleteDevice(devices.getPoolDevName(), deviceID)
devices.markDeviceIdFree(deviceId) devices.markDeviceIDFree(deviceID)
logrus.Debugf("Error registering device: %s", err) logrus.Debugf("Error registering device: %s", err)
return err return err
} }
if err := devices.closeTransaction(); err != nil { if err := devices.closeTransaction(); err != nil {
devices.unregisterDevice(deviceId, hash) devices.unregisterDevice(deviceID, hash)
devicemapper.DeleteDevice(devices.getPoolDevName(), deviceId) devicemapper.DeleteDevice(devices.getPoolDevName(), deviceID)
devices.markDeviceIdFree(deviceId) devices.markDeviceIDFree(deviceID)
return err return err
} }
return nil return nil
} }
func (devices *DeviceSet) loadMetadata(hash string) *DevInfo { func (devices *DeviceSet) loadMetadata(hash string) *devInfo {
info := &DevInfo{Hash: hash, devices: devices} info := &devInfo{Hash: hash, devices: devices}
jsonData, err := ioutil.ReadFile(devices.metadataFile(info)) jsonData, err := ioutil.ReadFile(devices.metadataFile(info))
if err != nil { if err != nil {
@ -690,7 +713,7 @@ func getDeviceUUID(device string) (string, error) {
return uuid, nil return uuid, nil
} }
func (devices *DeviceSet) verifyBaseDeviceUUID(baseInfo *DevInfo) error { func (devices *DeviceSet) verifyBaseDeviceUUID(baseInfo *devInfo) error {
devices.Lock() devices.Lock()
defer devices.Unlock() defer devices.Unlock()
@ -712,7 +735,7 @@ func (devices *DeviceSet) verifyBaseDeviceUUID(baseInfo *DevInfo) error {
return nil return nil
} }
func (devices *DeviceSet) saveBaseDeviceUUID(baseInfo *DevInfo) error { func (devices *DeviceSet) saveBaseDeviceUUID(baseInfo *devInfo) error {
devices.Lock() devices.Lock()
defer devices.Unlock() defer devices.Unlock()
@ -758,7 +781,7 @@ func (devices *DeviceSet) setupBaseImage() error {
} }
if devices.thinPoolDevice != "" && oldInfo == nil { if devices.thinPoolDevice != "" && oldInfo == nil {
_, transactionId, dataUsed, _, _, _, err := devices.poolStatus() _, transactionID, dataUsed, _, _, _, err := devices.poolStatus()
if err != nil { if err != nil {
return err return err
} }
@ -766,8 +789,8 @@ func (devices *DeviceSet) setupBaseImage() error {
return fmt.Errorf("Unable to take ownership of thin-pool (%s) that already has used data blocks", return fmt.Errorf("Unable to take ownership of thin-pool (%s) that already has used data blocks",
devices.thinPoolDevice) devices.thinPoolDevice)
} }
if transactionId != 0 { if transactionID != 0 {
return fmt.Errorf("Unable to take ownership of thin-pool (%s) with non-zero transaction Id", return fmt.Errorf("Unable to take ownership of thin-pool (%s) with non-zero transaction ID",
devices.thinPoolDevice) devices.thinPoolDevice)
} }
} }
@ -817,11 +840,12 @@ func setCloseOnExec(name string) {
} }
} }
// DMLog implements logging using DevMapperLogger interface.
func (devices *DeviceSet) DMLog(level int, file string, line int, dmError int, message string) { func (devices *DeviceSet) DMLog(level int, file string, line int, dmError int, message string) {
// By default libdm sends us all the messages including debug ones. // By default libdm sends us all the messages including debug ones.
// We need to filter out messages here and figure out which one // We need to filter out messages here and figure out which one
// should be printed. // should be printed.
if level > DMLogLevel { if level > logLevel {
return return
} }
@ -844,6 +868,7 @@ func minor(device uint64) uint64 {
return (device & 0xff) | ((device >> 12) & 0xfff00) return (device & 0xff) | ((device >> 12) & 0xfff00)
} }
// ResizePool increases the size of the pool.
func (devices *DeviceSet) ResizePool(size int64) error { func (devices *DeviceSet) ResizePool(size int64) error {
dirname := devices.loopbackDir() dirname := devices.loopbackDir()
datafilename := path.Join(dirname, "data") datafilename := path.Join(dirname, "data")
@ -922,18 +947,18 @@ func (devices *DeviceSet) loadTransactionMetaData() error {
// There is no active transaction. This will be the case // There is no active transaction. This will be the case
// during upgrade. // during upgrade.
if os.IsNotExist(err) { if os.IsNotExist(err) {
devices.OpenTransactionId = devices.TransactionId devices.OpenTransactionID = devices.TransactionID
return nil return nil
} }
return err return err
} }
json.Unmarshal(jsonData, &devices.Transaction) json.Unmarshal(jsonData, &devices.transaction)
return nil return nil
} }
func (devices *DeviceSet) saveTransactionMetaData() error { func (devices *DeviceSet) saveTransactionMetaData() error {
jsonData, err := json.Marshal(&devices.Transaction) jsonData, err := json.Marshal(&devices.transaction)
if err != nil { if err != nil {
return fmt.Errorf("Error encoding metadata to json: %s", err) return fmt.Errorf("Error encoding metadata to json: %s", err)
} }
@ -949,20 +974,20 @@ func (devices *DeviceSet) removeTransactionMetaData() error {
} }
func (devices *DeviceSet) rollbackTransaction() error { func (devices *DeviceSet) rollbackTransaction() error {
logrus.Debugf("Rolling back open transaction: TransactionId=%d hash=%s device_id=%d", devices.OpenTransactionId, devices.DeviceIdHash, devices.DeviceId) logrus.Debugf("Rolling back open transaction: TransactionID=%d hash=%s device_id=%d", devices.OpenTransactionID, devices.DeviceIDHash, devices.DeviceID)
// A device id might have already been deleted before transaction // A device id might have already been deleted before transaction
// closed. In that case this call will fail. Just leave a message // closed. In that case this call will fail. Just leave a message
// in case of failure. // in case of failure.
if err := devicemapper.DeleteDevice(devices.getPoolDevName(), devices.DeviceId); err != nil { if err := devicemapper.DeleteDevice(devices.getPoolDevName(), devices.DeviceID); err != nil {
logrus.Errorf("Unable to delete device: %s", err) logrus.Errorf("Unable to delete device: %s", err)
} }
dinfo := &DevInfo{Hash: devices.DeviceIdHash} dinfo := &devInfo{Hash: devices.DeviceIDHash}
if err := devices.removeMetadata(dinfo); err != nil { if err := devices.removeMetadata(dinfo); err != nil {
logrus.Errorf("Unable to remove metadata: %s", err) logrus.Errorf("Unable to remove metadata: %s", err)
} else { } else {
devices.markDeviceIdFree(devices.DeviceId) devices.markDeviceIDFree(devices.DeviceID)
} }
if err := devices.removeTransactionMetaData(); err != nil { if err := devices.removeTransactionMetaData(); err != nil {
@ -977,26 +1002,26 @@ func (devices *DeviceSet) processPendingTransaction() error {
return err return err
} }
// If there was open transaction but pool transaction Id is same // If there was open transaction but pool transaction ID is same
// as open transaction Id, nothing to roll back. // as open transaction ID, nothing to roll back.
if devices.TransactionId == devices.OpenTransactionId { if devices.TransactionID == devices.OpenTransactionID {
return nil return nil
} }
// If open transaction Id is less than pool transaction Id, something // If open transaction ID is less than pool transaction ID, something
// is wrong. Bail out. // is wrong. Bail out.
if devices.OpenTransactionId < devices.TransactionId { if devices.OpenTransactionID < devices.TransactionID {
logrus.Errorf("Open Transaction id %d is less than pool transaction id %d", devices.OpenTransactionId, devices.TransactionId) logrus.Errorf("Open Transaction id %d is less than pool transaction id %d", devices.OpenTransactionID, devices.TransactionID)
return nil return nil
} }
// Pool transaction Id is not same as open transaction. There is // Pool transaction ID is not same as open transaction. There is
// a transaction which was not completed. // a transaction which was not completed.
if err := devices.rollbackTransaction(); err != nil { if err := devices.rollbackTransaction(); err != nil {
return fmt.Errorf("Rolling back open transaction failed: %s", err) return fmt.Errorf("Rolling back open transaction failed: %s", err)
} }
devices.OpenTransactionId = devices.TransactionId devices.OpenTransactionID = devices.TransactionID
return nil return nil
} }
@ -1023,18 +1048,18 @@ func (devices *DeviceSet) saveDeviceSetMetaData() error {
return devices.writeMetaFile(jsonData, devices.deviceSetMetaFile()) return devices.writeMetaFile(jsonData, devices.deviceSetMetaFile())
} }
func (devices *DeviceSet) openTransaction(hash string, DeviceId int) error { func (devices *DeviceSet) openTransaction(hash string, DeviceID int) error {
devices.allocateTransactionId() devices.allocateTransactionID()
devices.DeviceIdHash = hash devices.DeviceIDHash = hash
devices.DeviceId = DeviceId devices.DeviceID = DeviceID
if err := devices.saveTransactionMetaData(); err != nil { if err := devices.saveTransactionMetaData(); err != nil {
return fmt.Errorf("Error saving transaction metadata: %s", err) return fmt.Errorf("Error saving transaction metadata: %s", err)
} }
return nil return nil
} }
func (devices *DeviceSet) refreshTransaction(DeviceId int) error { func (devices *DeviceSet) refreshTransaction(DeviceID int) error {
devices.DeviceId = DeviceId devices.DeviceID = DeviceID
if err := devices.saveTransactionMetaData(); err != nil { if err := devices.saveTransactionMetaData(); err != nil {
return fmt.Errorf("Error saving transaction metadata: %s", err) return fmt.Errorf("Error saving transaction metadata: %s", err)
} }
@ -1042,7 +1067,7 @@ func (devices *DeviceSet) refreshTransaction(DeviceId int) error {
} }
func (devices *DeviceSet) closeTransaction() error { func (devices *DeviceSet) closeTransaction() error {
if err := devices.updatePoolTransactionId(); err != nil { if err := devices.updatePoolTransactionID(); err != nil {
logrus.Debugf("Failed to close Transaction") logrus.Debugf("Failed to close Transaction")
return err return err
} }
@ -1064,7 +1089,7 @@ func determineDriverCapabilities(version string) error {
} }
if major > 4 { if major > 4 {
DriverDeferredRemovalSupport = true driverDeferredRemovalSupport = true
return nil return nil
} }
@ -1082,7 +1107,7 @@ func determineDriverCapabilities(version string) error {
* check for patch level as it can not be less than 0. * check for patch level as it can not be less than 0.
*/ */
if minor >= 27 { if minor >= 27 {
DriverDeferredRemovalSupport = true driverDeferredRemovalSupport = true
return nil return nil
} }
@ -1225,7 +1250,7 @@ func (devices *DeviceSet) initDevmapper(doInit bool) error {
// If user asked for deferred removal and both library and driver // If user asked for deferred removal and both library and driver
// supports deferred removal use it. // supports deferred removal use it.
if EnableDeferredRemoval && DriverDeferredRemovalSupport && devicemapper.LibraryDeferredRemovalSupport == true { if enableDeferredRemoval && driverDeferredRemovalSupport && devicemapper.LibraryDeferredRemovalSupport == true {
logrus.Debugf("devmapper: Deferred removal support enabled.") logrus.Debugf("devmapper: Deferred removal support enabled.")
devices.deferredRemove = true devices.deferredRemove = true
} }
@ -1372,7 +1397,7 @@ func (devices *DeviceSet) initDevmapper(doInit bool) error {
} }
} }
// Right now this loads only NextDeviceId. If there is more metadata // Right now this loads only NextDeviceID. If there is more metadata
// down the line, we might have to move it earlier. // down the line, we might have to move it earlier.
if err := devices.loadDeviceSetMetaData(); err != nil { if err := devices.loadDeviceSetMetaData(); err != nil {
return err return err
@ -1389,6 +1414,7 @@ func (devices *DeviceSet) initDevmapper(doInit bool) error {
return nil return nil
} }
// AddDevice adds a device and registers in the hash.
func (devices *DeviceSet) AddDevice(hash, baseHash string) error { func (devices *DeviceSet) AddDevice(hash, baseHash string) error {
logrus.Debugf("[deviceset] AddDevice(hash=%s basehash=%s)", hash, baseHash) logrus.Debugf("[deviceset] AddDevice(hash=%s basehash=%s)", hash, baseHash)
defer logrus.Debugf("[deviceset] AddDevice(hash=%s basehash=%s) END", hash, baseHash) defer logrus.Debugf("[deviceset] AddDevice(hash=%s basehash=%s) END", hash, baseHash)
@ -1415,7 +1441,7 @@ func (devices *DeviceSet) AddDevice(hash, baseHash string) error {
return nil return nil
} }
func (devices *DeviceSet) deleteDevice(info *DevInfo) error { func (devices *DeviceSet) deleteDevice(info *devInfo) error {
if devices.doBlkDiscard { if devices.doBlkDiscard {
// This is a workaround for the kernel not discarding block so // This is a workaround for the kernel not discarding block so
// on the thin pool when we remove a thinp device, so we do it // on the thin pool when we remove a thinp device, so we do it
@ -1435,17 +1461,17 @@ func (devices *DeviceSet) deleteDevice(info *DevInfo) error {
} }
} }
if err := devices.openTransaction(info.Hash, info.DeviceId); err != nil { if err := devices.openTransaction(info.Hash, info.DeviceID); err != nil {
logrus.Debugf("Error opening transaction hash = %s deviceId = %d", "", info.DeviceId) logrus.Debugf("Error opening transaction hash = %s deviceID = %d", "", info.DeviceID)
return err return err
} }
if err := devicemapper.DeleteDevice(devices.getPoolDevName(), info.DeviceId); err != nil { if err := devicemapper.DeleteDevice(devices.getPoolDevName(), info.DeviceID); err != nil {
logrus.Debugf("Error deleting device: %s", err) logrus.Debugf("Error deleting device: %s", err)
return err return err
} }
if err := devices.unregisterDevice(info.DeviceId, info.Hash); err != nil { if err := devices.unregisterDevice(info.DeviceID, info.Hash); err != nil {
return err return err
} }
@ -1453,11 +1479,12 @@ func (devices *DeviceSet) deleteDevice(info *DevInfo) error {
return err return err
} }
devices.markDeviceIdFree(info.DeviceId) devices.markDeviceIDFree(info.DeviceID)
return nil return nil
} }
// DeleteDevice deletes a device from the hash.
func (devices *DeviceSet) DeleteDevice(hash string) error { func (devices *DeviceSet) DeleteDevice(hash string) error {
info, err := devices.lookupDevice(hash) info, err := devices.lookupDevice(hash)
if err != nil { if err != nil {
@ -1493,7 +1520,7 @@ func (devices *DeviceSet) deactivatePool() error {
return nil return nil
} }
func (devices *DeviceSet) deactivateDevice(info *DevInfo) error { func (devices *DeviceSet) deactivateDevice(info *devInfo) error {
logrus.Debugf("[devmapper] deactivateDevice(%s)", info.Hash) logrus.Debugf("[devmapper] deactivateDevice(%s)", info.Hash)
defer logrus.Debugf("[devmapper] deactivateDevice END(%s)", info.Hash) defer logrus.Debugf("[devmapper] deactivateDevice END(%s)", info.Hash)
@ -1544,7 +1571,7 @@ func (devices *DeviceSet) removeDevice(devname string) error {
return err return err
} }
func (devices *DeviceSet) cancelDeferredRemoval(info *DevInfo) error { func (devices *DeviceSet) cancelDeferredRemoval(info *devInfo) error {
if !devices.deferredRemove { if !devices.deferredRemove {
return nil return nil
} }
@ -1583,12 +1610,13 @@ func (devices *DeviceSet) cancelDeferredRemoval(info *DevInfo) error {
return err return err
} }
// Shutdown shuts down the device by unmounting the root.
func (devices *DeviceSet) Shutdown() error { func (devices *DeviceSet) Shutdown() error {
logrus.Debugf("[deviceset %s] Shutdown()", devices.devicePrefix) logrus.Debugf("[deviceset %s] Shutdown()", devices.devicePrefix)
logrus.Debugf("[devmapper] Shutting down DeviceSet: %s", devices.root) logrus.Debugf("[devmapper] Shutting down DeviceSet: %s", devices.root)
defer logrus.Debugf("[deviceset %s] Shutdown() END", devices.devicePrefix) defer logrus.Debugf("[deviceset %s] Shutdown() END", devices.devicePrefix)
var devs []*DevInfo var devs []*devInfo
devices.devicesLock.Lock() devices.devicesLock.Lock()
for _, info := range devices.Devices { for _, info := range devices.Devices {
@ -1639,6 +1667,7 @@ func (devices *DeviceSet) Shutdown() error {
return nil return nil
} }
// MountDevice mounts the device if not already mounted.
func (devices *DeviceSet) MountDevice(hash, path, mountLabel string) error { func (devices *DeviceSet) MountDevice(hash, path, mountLabel string) error {
info, err := devices.lookupDevice(hash) info, err := devices.lookupDevice(hash)
if err != nil { if err != nil {
@ -1664,8 +1693,6 @@ func (devices *DeviceSet) MountDevice(hash, path, mountLabel string) error {
return fmt.Errorf("Error activating devmapper device for '%s': %s", hash, err) return fmt.Errorf("Error activating devmapper device for '%s': %s", hash, err)
} }
var flags uintptr = syscall.MS_MGC_VAL
fstype, err := ProbeFsType(info.DevName()) fstype, err := ProbeFsType(info.DevName())
if err != nil { if err != nil {
return err return err
@ -1681,7 +1708,7 @@ func (devices *DeviceSet) MountDevice(hash, path, mountLabel string) error {
options = joinMountOptions(options, devices.mountOptions) options = joinMountOptions(options, devices.mountOptions)
options = joinMountOptions(options, label.FormatMountLabel("", mountLabel)) options = joinMountOptions(options, label.FormatMountLabel("", mountLabel))
if err := syscall.Mount(info.DevName(), path, fstype, flags, options); err != nil { if err := syscall.Mount(info.DevName(), path, fstype, syscall.MS_MGC_VAL, options); err != nil {
return fmt.Errorf("Error mounting '%s' on '%s': %s", info.DevName(), path, err) return fmt.Errorf("Error mounting '%s' on '%s': %s", info.DevName(), path, err)
} }
@ -1691,6 +1718,7 @@ func (devices *DeviceSet) MountDevice(hash, path, mountLabel string) error {
return nil return nil
} }
// UnmountDevice unmounts the device and removes it from hash.
func (devices *DeviceSet) UnmountDevice(hash string) error { func (devices *DeviceSet) UnmountDevice(hash string) error {
logrus.Debugf("[devmapper] UnmountDevice(hash=%s)", hash) logrus.Debugf("[devmapper] UnmountDevice(hash=%s)", hash)
defer logrus.Debugf("[devmapper] UnmountDevice(hash=%s) END", hash) defer logrus.Debugf("[devmapper] UnmountDevice(hash=%s) END", hash)
@ -1730,6 +1758,7 @@ func (devices *DeviceSet) UnmountDevice(hash string) error {
return nil return nil
} }
// HasDevice returns true if the device is in the hash and mounted.
func (devices *DeviceSet) HasDevice(hash string) bool { func (devices *DeviceSet) HasDevice(hash string) bool {
devices.Lock() devices.Lock()
defer devices.Unlock() defer devices.Unlock()
@ -1738,6 +1767,7 @@ func (devices *DeviceSet) HasDevice(hash string) bool {
return info != nil return info != nil
} }
// HasActivatedDevice return true if the device exists.
func (devices *DeviceSet) HasActivatedDevice(hash string) bool { func (devices *DeviceSet) HasActivatedDevice(hash string) bool {
info, _ := devices.lookupDevice(hash) info, _ := devices.lookupDevice(hash)
if info == nil { if info == nil {
@ -1754,6 +1784,7 @@ func (devices *DeviceSet) HasActivatedDevice(hash string) bool {
return devinfo != nil && devinfo.Exists != 0 return devinfo != nil && devinfo.Exists != 0
} }
// List returns a list of device ids.
func (devices *DeviceSet) List() []string { func (devices *DeviceSet) List() []string {
devices.Lock() devices.Lock()
defer devices.Unlock() defer devices.Unlock()
@ -1782,6 +1813,7 @@ func (devices *DeviceSet) deviceStatus(devName string) (sizeInSectors, mappedSec
return return
} }
// GetDeviceStatus provides size, mapped sectors
func (devices *DeviceSet) GetDeviceStatus(hash string) (*DevStatus, error) { func (devices *DeviceSet) GetDeviceStatus(hash string) (*DevStatus, error) {
info, err := devices.lookupDevice(hash) info, err := devices.lookupDevice(hash)
if err != nil { if err != nil {
@ -1795,9 +1827,9 @@ func (devices *DeviceSet) GetDeviceStatus(hash string) (*DevStatus, error) {
defer devices.Unlock() defer devices.Unlock()
status := &DevStatus{ status := &DevStatus{
DeviceId: info.DeviceId, DeviceID: info.DeviceID,
Size: info.Size, Size: info.Size,
TransactionId: info.TransactionId, TransactionID: info.TransactionID,
} }
if err := devices.activateDeviceIfNeeded(info); err != nil { if err := devices.activateDeviceIfNeeded(info); err != nil {
@ -1817,10 +1849,10 @@ func (devices *DeviceSet) GetDeviceStatus(hash string) (*DevStatus, error) {
return status, nil return status, nil
} }
func (devices *DeviceSet) poolStatus() (totalSizeInSectors, transactionId, dataUsed, dataTotal, metadataUsed, metadataTotal uint64, err error) { func (devices *DeviceSet) poolStatus() (totalSizeInSectors, transactionID, dataUsed, dataTotal, metadataUsed, metadataTotal uint64, err error) {
var params string var params string
if _, totalSizeInSectors, _, params, err = devicemapper.GetStatus(devices.getPoolName()); err == nil { if _, totalSizeInSectors, _, params, err = devicemapper.GetStatus(devices.getPoolName()); err == nil {
_, err = fmt.Sscanf(params, "%d %d/%d %d/%d", &transactionId, &metadataUsed, &metadataTotal, &dataUsed, &dataTotal) _, err = fmt.Sscanf(params, "%d %d/%d %d/%d", &transactionID, &metadataUsed, &metadataTotal, &dataUsed, &dataTotal)
} }
return return
} }
@ -1908,7 +1940,7 @@ func (devices *DeviceSet) Status() *Status {
} }
// Status returns the current status of this deviceset // Status returns the current status of this deviceset
func (devices *DeviceSet) ExportDeviceMetadata(hash string) (*DeviceMetadata, error) { func (devices *DeviceSet) exportDeviceMetadata(hash string) (*deviceMetadata, error) {
info, err := devices.lookupDevice(hash) info, err := devices.lookupDevice(hash)
if err != nil { if err != nil {
return nil, err return nil, err
@ -1917,24 +1949,25 @@ func (devices *DeviceSet) ExportDeviceMetadata(hash string) (*DeviceMetadata, er
info.lock.Lock() info.lock.Lock()
defer info.lock.Unlock() defer info.lock.Unlock()
metadata := &DeviceMetadata{info.DeviceId, info.Size, info.Name()} metadata := &deviceMetadata{info.DeviceID, info.Size, info.Name()}
return metadata, nil return metadata, nil
} }
// NewDeviceSet creates the device set based on the options provided.
func NewDeviceSet(root string, doInit bool, options []string) (*DeviceSet, error) { func NewDeviceSet(root string, doInit bool, options []string) (*DeviceSet, error) {
devicemapper.SetDevDir("/dev") devicemapper.SetDevDir("/dev")
devices := &DeviceSet{ devices := &DeviceSet{
root: root, root: root,
MetaData: MetaData{Devices: make(map[string]*DevInfo)}, metaData: metaData{Devices: make(map[string]*devInfo)},
dataLoopbackSize: DefaultDataLoopbackSize, dataLoopbackSize: defaultDataLoopbackSize,
metaDataLoopbackSize: DefaultMetaDataLoopbackSize, metaDataLoopbackSize: defaultMetaDataLoopbackSize,
baseFsSize: DefaultBaseFsSize, baseFsSize: defaultBaseFsSize,
overrideUdevSyncCheck: DefaultUdevSyncOverride, overrideUdevSyncCheck: defaultUdevSyncOverride,
filesystem: "ext4", filesystem: "ext4",
doBlkDiscard: true, doBlkDiscard: true,
thinpBlockSize: DefaultThinpBlockSize, thinpBlockSize: defaultThinpBlockSize,
deviceIdMap: make([]byte, DeviceIdMapSz), deviceIDMap: make([]byte, deviceIDMapSz),
} }
foundBlkDiscard := false foundBlkDiscard := false
@ -1998,7 +2031,7 @@ func NewDeviceSet(root string, doInit bool, options []string) (*DeviceSet, error
} }
case "dm.use_deferred_removal": case "dm.use_deferred_removal":
EnableDeferredRemoval, err = strconv.ParseBool(val) enableDeferredRemoval, err = strconv.ParseBool(val)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -10,10 +10,10 @@ import (
func init() { func init() {
// Reduce the size the the base fs and loopback for the tests // Reduce the size the the base fs and loopback for the tests
DefaultDataLoopbackSize = 300 * 1024 * 1024 defaultDataLoopbackSize = 300 * 1024 * 1024
DefaultMetaDataLoopbackSize = 200 * 1024 * 1024 defaultMetaDataLoopbackSize = 200 * 1024 * 1024
DefaultBaseFsSize = 300 * 1024 * 1024 defaultBaseFsSize = 300 * 1024 * 1024
DefaultUdevSyncOverride = true defaultUdevSyncOverride = true
if err := graphtest.InitLoopbacks(); err != nil { if err := graphtest.InitLoopbacks(); err != nil {
panic(err) panic(err)
} }

View File

@ -25,6 +25,7 @@ func init() {
// End of placeholder interfaces. // End of placeholder interfaces.
// Driver contains the device set mounted and the home directory
type Driver struct { type Driver struct {
*DeviceSet *DeviceSet
home string home string
@ -32,6 +33,7 @@ type Driver struct {
var backingFs = "<unknown>" var backingFs = "<unknown>"
// Init creates a driver with the given home and the set of options.
func Init(home string, options []string) (graphdriver.Driver, error) { func Init(home string, options []string) (graphdriver.Driver, error) {
fsMagic, err := graphdriver.GetFSMagic(home) fsMagic, err := graphdriver.GetFSMagic(home)
if err != nil { if err != nil {
@ -62,6 +64,9 @@ func (d *Driver) String() string {
return "devicemapper" return "devicemapper"
} }
// Status returns the status about the driver in a printable format.
// Information returned contains Pool Name, Data File, Metadata file, disk usage by
// the data and metadata, etc.
func (d *Driver) Status() [][2]string { func (d *Driver) Status() [][2]string {
s := d.DeviceSet.Status() s := d.DeviceSet.Status()
@ -92,20 +97,22 @@ func (d *Driver) Status() [][2]string {
return status return status
} }
// GetMetadata returns a map of information about the device.
func (d *Driver) GetMetadata(id string) (map[string]string, error) { func (d *Driver) GetMetadata(id string) (map[string]string, error) {
m, err := d.DeviceSet.ExportDeviceMetadata(id) m, err := d.DeviceSet.exportDeviceMetadata(id)
if err != nil { if err != nil {
return nil, err return nil, err
} }
metadata := make(map[string]string) metadata := make(map[string]string)
metadata["DeviceId"] = strconv.Itoa(m.deviceId) metadata["DeviceId"] = strconv.Itoa(m.deviceID)
metadata["DeviceSize"] = strconv.FormatUint(m.deviceSize, 10) metadata["DeviceSize"] = strconv.FormatUint(m.deviceSize, 10)
metadata["DeviceName"] = m.deviceName metadata["DeviceName"] = m.deviceName
return metadata, nil return metadata, nil
} }
// Cleanup unmounts a device.
func (d *Driver) Cleanup() error { func (d *Driver) Cleanup() error {
err := d.DeviceSet.Shutdown() err := d.DeviceSet.Shutdown()
@ -116,6 +123,7 @@ func (d *Driver) Cleanup() error {
return err return err
} }
// Create adds a device with a given id and the parent.
func (d *Driver) Create(id, parent string) error { func (d *Driver) Create(id, parent string) error {
if err := d.DeviceSet.AddDevice(id, parent); err != nil { if err := d.DeviceSet.AddDevice(id, parent); err != nil {
return err return err
@ -124,6 +132,7 @@ func (d *Driver) Create(id, parent string) error {
return nil return nil
} }
// Remove removes a device with a given id, unmounts the filesystem.
func (d *Driver) Remove(id string) error { func (d *Driver) Remove(id string) error {
if !d.DeviceSet.HasDevice(id) { if !d.DeviceSet.HasDevice(id) {
// Consider removing a non-existing device a no-op // Consider removing a non-existing device a no-op
@ -145,6 +154,7 @@ func (d *Driver) Remove(id string) error {
return nil return nil
} }
// Get mounts a device with given id into the root filesystem
func (d *Driver) Get(id, mountLabel string) (string, error) { func (d *Driver) Get(id, mountLabel string) (string, error) {
mp := path.Join(d.home, "mnt", id) mp := path.Join(d.home, "mnt", id)
@ -177,6 +187,7 @@ func (d *Driver) Get(id, mountLabel string) (string, error) {
return rootFs, nil return rootFs, nil
} }
// Put unmounts a device and removes it.
func (d *Driver) Put(id string) error { func (d *Driver) Put(id string) error {
err := d.DeviceSet.UnmountDevice(id) err := d.DeviceSet.UnmountDevice(id)
if err != nil { if err != nil {
@ -185,6 +196,7 @@ func (d *Driver) Put(id string) error {
return err return err
} }
// Exists checks to see if the device is mounted.
func (d *Driver) Exists(id string) bool { func (d *Driver) Exists(id string) bool {
return d.DeviceSet.HasDevice(id) return d.DeviceSet.HasDevice(id)
} }

View File

@ -13,6 +13,7 @@ import (
// FIXME: this is copy-pasted from the aufs driver. // FIXME: this is copy-pasted from the aufs driver.
// It should be moved into the core. // It should be moved into the core.
// Mounted returns true if a mount point exists.
func Mounted(mountpoint string) (bool, error) { func Mounted(mountpoint string) (bool, error) {
mntpoint, err := os.Stat(mountpoint) mntpoint, err := os.Stat(mountpoint)
if err != nil { if err != nil {
@ -36,6 +37,7 @@ type probeData struct {
offset uint64 offset uint64
} }
// ProbeFsType returns the filesystem name for the given device id.
func ProbeFsType(device string) (string, error) { func ProbeFsType(device string) (string, error) {
probes := []probeData{ probes := []probeData{
{"btrfs", "_BHRfS_M", 0x10040}, {"btrfs", "_BHRfS_M", 0x10040},

View File

@ -19,6 +19,7 @@ packages=(
daemon/execdriver/native daemon/execdriver/native
daemon/execdriver/native/template daemon/execdriver/native/template
daemon/graphdriver/aufs daemon/graphdriver/aufs
daemon/graphdriver/devmapper
daemon/network daemon/network
docker docker
dockerinit dockerinit