Merge pull request #10195 from vbatts/vbatts-dm_udev_sync

device-mapper udev sync
This commit is contained in:
unclejack 2015-01-20 00:06:29 +02:00
commit 2d61a62378
4 changed files with 47 additions and 8 deletions

View File

@ -113,6 +113,7 @@ type Status struct {
Data DiskUsage Data DiskUsage
Metadata DiskUsage Metadata DiskUsage
SectorSize uint64 SectorSize uint64
UdevSyncSupported bool
} }
type DevStatus struct { type DevStatus struct {
@ -947,6 +948,12 @@ func (devices *DeviceSet) initDevmapper(doInit bool) error {
return graphdriver.ErrNotSupported return graphdriver.ErrNotSupported
} }
// https://github.com/docker/docker/issues/4036
if supported := devicemapper.UdevSetSyncSupport(true); !supported {
log.Warnf("WARNING: Udev sync is not supported. This will lead to unexpected behavior, data loss and errors")
}
log.Debugf("devicemapper: udev sync support: %v", devicemapper.UdevSyncSupported())
if err := os.MkdirAll(devices.metadataDir(), 0700); err != nil && !os.IsExist(err) { if err := os.MkdirAll(devices.metadataDir(), 0700); err != nil && !os.IsExist(err) {
return err return err
} }
@ -1572,6 +1579,7 @@ func (devices *DeviceSet) Status() *Status {
status.DataLoopback = devices.dataLoopFile status.DataLoopback = devices.dataLoopFile
status.MetadataFile = devices.MetadataDevicePath() status.MetadataFile = devices.MetadataDevicePath()
status.MetadataLoopback = devices.metadataLoopFile status.MetadataLoopback = devices.metadataLoopFile
status.UdevSyncSupported = devicemapper.UdevSyncSupported()
totalSizeInSectors, _, dataUsed, dataTotal, metadataUsed, metadataTotal, err := devices.poolStatus() totalSizeInSectors, _, dataUsed, dataTotal, metadataUsed, metadataTotal, err := devices.poolStatus()
if err == nil { if err == nil {

View File

@ -74,6 +74,7 @@ func (d *Driver) Status() [][2]string {
{"Data Space Total", fmt.Sprintf("%s", units.HumanSize(float64(s.Data.Total)))}, {"Data Space Total", fmt.Sprintf("%s", units.HumanSize(float64(s.Data.Total)))},
{"Metadata Space Used", fmt.Sprintf("%s", units.HumanSize(float64(s.Metadata.Used)))}, {"Metadata Space Used", fmt.Sprintf("%s", units.HumanSize(float64(s.Metadata.Used)))},
{"Metadata Space Total", fmt.Sprintf("%s", units.HumanSize(float64(s.Metadata.Total)))}, {"Metadata Space Total", fmt.Sprintf("%s", units.HumanSize(float64(s.Metadata.Total)))},
{"Udev Sync Supported", fmt.Sprintf("%v", s.UdevSyncSupported)},
} }
if len(s.DataLoopback) > 0 { if len(s.DataLoopback) > 0 {
status = append(status, [2]string{"Data loop file", s.DataLoopback}) status = append(status, [2]string{"Data loop file", s.DataLoopback})

View File

@ -319,6 +319,26 @@ func GetLibraryVersion() (string, error) {
return version, nil return version, nil
} }
// UdevSyncSupported returns whether device-mapper is able to sync with udev
//
// This is essential otherwise race conditions can arise where both udev and
// device-mapper attempt to create and destroy devices.
func UdevSyncSupported() bool {
return DmUdevGetSyncSupport() != 0
}
// UdevSetSyncSupport allows setting whether the udev sync should be enabled.
// The return bool indicates the state of whether the sync is enabled.
func UdevSetSyncSupport(enable bool) bool {
if enable {
DmUdevSetSyncSupport(1)
} else {
DmUdevSetSyncSupport(0)
}
return UdevSyncSupported()
}
// Useful helper for cleanup // Useful helper for cleanup
func RemoveDevice(name string) error { func RemoveDevice(name string) error {
log.Debugf("[devmapper] RemoveDevice START") log.Debugf("[devmapper] RemoveDevice START")

View File

@ -107,6 +107,8 @@ var (
DmTaskSetRo = dmTaskSetRoFct DmTaskSetRo = dmTaskSetRoFct
DmTaskSetSector = dmTaskSetSectorFct DmTaskSetSector = dmTaskSetSectorFct
DmUdevWait = dmUdevWaitFct DmUdevWait = dmUdevWaitFct
DmUdevSetSyncSupport = dmUdevSetSyncSupportFct
DmUdevGetSyncSupport = dmUdevGetSyncSupportFct
LogWithErrnoInit = logWithErrnoInitFct LogWithErrnoInit = logWithErrnoInitFct
) )
@ -231,6 +233,14 @@ func dmGetNextTargetFct(task *CDmTask, next uintptr, start, length *uint64, targ
return uintptr(nextp) return uintptr(nextp)
} }
func dmUdevSetSyncSupportFct(syncWithUdev int) {
(C.dm_udev_set_sync_support(C.int(syncWithUdev)))
}
func dmUdevGetSyncSupportFct() int {
return int(C.dm_udev_get_sync_support())
}
func dmUdevWaitFct(cookie uint) int { func dmUdevWaitFct(cookie uint) int {
return int(C.dm_udev_wait(C.uint32_t(cookie))) return int(C.dm_udev_wait(C.uint32_t(cookie)))
} }