Signed-off-by: Liu Hua <sdu.liu@huawei.com>
| ... | ... |
@@ -2115,7 +2115,7 @@ func (devices *DeviceSet) MountDevice(hash, path, mountLabel string) error {
|
| 2115 | 2115 |
} |
| 2116 | 2116 |
|
| 2117 | 2117 |
// UnmountDevice unmounts the device and removes it from hash. |
| 2118 |
-func (devices *DeviceSet) UnmountDevice(hash string) error {
|
|
| 2118 |
+func (devices *DeviceSet) UnmountDevice(hash, mountPath string) error {
|
|
| 2119 | 2119 |
logrus.Debugf("[devmapper] UnmountDevice(hash=%s)", hash)
|
| 2120 | 2120 |
defer logrus.Debugf("[devmapper] UnmountDevice(hash=%s) END", hash)
|
| 2121 | 2121 |
|
| ... | ... |
@@ -2130,17 +2130,22 @@ func (devices *DeviceSet) UnmountDevice(hash string) error {
|
| 2130 | 2130 |
devices.Lock() |
| 2131 | 2131 |
defer devices.Unlock() |
| 2132 | 2132 |
|
| 2133 |
- if info.mountCount == 0 {
|
|
| 2134 |
- return fmt.Errorf("UnmountDevice: device not-mounted id %s", hash)
|
|
| 2135 |
- } |
|
| 2133 |
+ // If there are running containers when daemon crashes, during daemon |
|
| 2134 |
+ // restarting, it will kill running contaienrs and will finally call |
|
| 2135 |
+ // Put() without calling Get(). So info.MountCount may become negative. |
|
| 2136 |
+ // if info.mountCount goes negative, we do the unmount and assign |
|
| 2137 |
+ // it to 0. |
|
| 2136 | 2138 |
|
| 2137 | 2139 |
info.mountCount-- |
| 2138 | 2140 |
if info.mountCount > 0 {
|
| 2139 | 2141 |
return nil |
| 2142 |
+ } else if info.mountCount < 0 {
|
|
| 2143 |
+ logrus.Warnf("[devmapper] Mount count of device went negative. Put() called without matching Get(). Resetting count to 0")
|
|
| 2144 |
+ info.mountCount = 0 |
|
| 2140 | 2145 |
} |
| 2141 | 2146 |
|
| 2142 |
- logrus.Debugf("[devmapper] Unmount(%s)", info.mountPath)
|
|
| 2143 |
- if err := syscall.Unmount(info.mountPath, syscall.MNT_DETACH); err != nil {
|
|
| 2147 |
+ logrus.Debugf("[devmapper] Unmount(%s)", mountPath)
|
|
| 2148 |
+ if err := syscall.Unmount(mountPath, syscall.MNT_DETACH); err != nil {
|
|
| 2144 | 2149 |
return err |
| 2145 | 2150 |
} |
| 2146 | 2151 |
logrus.Debugf("[devmapper] Unmount done")
|
| ... | ... |
@@ -186,7 +186,7 @@ func (d *Driver) Get(id, mountLabel string) (string, error) {
|
| 186 | 186 |
|
| 187 | 187 |
rootFs := path.Join(mp, "rootfs") |
| 188 | 188 |
if err := idtools.MkdirAllAs(rootFs, 0755, uid, gid); err != nil && !os.IsExist(err) {
|
| 189 |
- d.DeviceSet.UnmountDevice(id) |
|
| 189 |
+ d.DeviceSet.UnmountDevice(id, mp) |
|
| 190 | 190 |
return "", err |
| 191 | 191 |
} |
| 192 | 192 |
|
| ... | ... |
@@ -195,7 +195,7 @@ func (d *Driver) Get(id, mountLabel string) (string, error) {
|
| 195 | 195 |
// Create an "id" file with the container/image id in it to help reconscruct this in case |
| 196 | 196 |
// of later problems |
| 197 | 197 |
if err := ioutil.WriteFile(idFile, []byte(id), 0600); err != nil {
|
| 198 |
- d.DeviceSet.UnmountDevice(id) |
|
| 198 |
+ d.DeviceSet.UnmountDevice(id, mp) |
|
| 199 | 199 |
return "", err |
| 200 | 200 |
} |
| 201 | 201 |
} |
| ... | ... |
@@ -205,7 +205,8 @@ func (d *Driver) Get(id, mountLabel string) (string, error) {
|
| 205 | 205 |
|
| 206 | 206 |
// Put unmounts a device and removes it. |
| 207 | 207 |
func (d *Driver) Put(id string) error {
|
| 208 |
- err := d.DeviceSet.UnmountDevice(id) |
|
| 208 |
+ mp := path.Join(d.home, "mnt", id) |
|
| 209 |
+ err := d.DeviceSet.UnmountDevice(id, mp) |
|
| 209 | 210 |
if err != nil {
|
| 210 | 211 |
logrus.Errorf("Error unmounting device %s: %s", id, err)
|
| 211 | 212 |
} |