Merge pull request #4794 from alexlarsson/dm-better-shutdown

devicemapper: Better/faster shutdown
This commit is contained in:
Victor Vieux 2014-03-25 14:03:00 -07:00
commit 6643cc20fe
1 changed files with 17 additions and 19 deletions

View File

@ -14,6 +14,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"syscall"
"time" "time"
) )
@ -677,6 +678,12 @@ func (devices *DeviceSet) deactivateDevice(hash string) error {
utils.Debugf("[devmapper] deactivateDevice(%s)", hash) utils.Debugf("[devmapper] deactivateDevice(%s)", hash)
defer utils.Debugf("[devmapper] deactivateDevice END") defer utils.Debugf("[devmapper] deactivateDevice END")
// Wait for the unmount to be effective,
// by watching the value of Info.OpenCount for the device
if err := devices.waitClose(hash); err != nil {
utils.Errorf("Warning: error waiting for device %s to close: %s\n", hash, err)
}
info := devices.Devices[hash] info := devices.Devices[hash]
if info == nil { if info == nil {
return fmt.Errorf("Unknown device %s", hash) return fmt.Errorf("Unknown device %s", hash)
@ -799,26 +806,20 @@ func (devices *DeviceSet) Shutdown() error {
for _, info := range devices.Devices { for _, info := range devices.Devices {
info.lock.Lock() info.lock.Lock()
if info.mountCount > 0 { if info.mountCount > 0 {
if err := sysUnmount(info.mountPath, 0); err != nil { // We use MNT_DETACH here in case it is still busy in some running
// container. This means it'll go away from the global scope directly,
// and the device will be released when that container dies.
if err := sysUnmount(info.mountPath, syscall.MNT_DETACH); err != nil {
utils.Debugf("Shutdown unmounting %s, error: %s\n", info.mountPath, err) utils.Debugf("Shutdown unmounting %s, error: %s\n", info.mountPath, err)
} }
if err := devices.deactivateDevice(info.Hash); err != nil {
utils.Debugf("Shutdown deactivate %s , error: %s\n", info.Hash, err)
}
} }
info.lock.Unlock() info.lock.Unlock()
} }
for _, d := range devices.Devices {
d.lock.Lock()
if err := devices.waitClose(d.Hash); err != nil {
utils.Errorf("Warning: error waiting for device %s to unmount: %s\n", d.Hash, err)
}
if err := devices.deactivateDevice(d.Hash); err != nil {
utils.Debugf("Shutdown deactivate %s , error: %s\n", d.Hash, err)
}
d.lock.Unlock()
}
if err := devices.deactivatePool(); err != nil { if err := devices.deactivatePool(); err != nil {
utils.Debugf("Shutdown deactivate pool , error: %s\n", err) utils.Debugf("Shutdown deactivate pool , error: %s\n", err)
} }
@ -920,14 +921,11 @@ func (devices *DeviceSet) UnmountDevice(hash string, mode UnmountMode) error {
return err return err
} }
utils.Debugf("[devmapper] Unmount done") utils.Debugf("[devmapper] Unmount done")
// Wait for the unmount to be effective,
// by watching the value of Info.OpenCount for the device if err := devices.deactivateDevice(hash); err != nil {
if err := devices.waitClose(hash); err != nil {
return err return err
} }
devices.deactivateDevice(hash)
info.mountPath = "" info.mountPath = ""
return nil return nil