From 544b5be235f9a34a5c75a936549bf6d6f2280339 Mon Sep 17 00:00:00 2001 From: jingrui Date: Thu, 3 Jan 2019 15:22:26 +0800 Subject: [PATCH 041/111] devmapper: devmapper: remove broken device when start daemon reason: cherry-pick commits to docker-18.09 cherry-pick from 6104c8e237 | * devmapper: remove broken device when start daemon When use `kill -9 docker-daemon-pid` to stop docker, It may casue that the status of devicemapper devices inconsisitent. eg, we can see the device info use `dmsetup status` command, but the device does not exist in `/dev/mapper` directory. At next time docker start, it will start failed or load container failed. This patch add a check when docker start in `initDevmapper` function. First, we find all devmapper devices in the system. Then If the device name has a prefix with `docker-{major}:{minor}-{inode}` and the length is equal to zero, we use `devicemapper.RemoveDevice` remove the device. Change-Id: I7eccf4e9539751d615b953abf94951b7e94153d1 Signed-off-by: Wang Long Signed-off-by: jingrui --- .../daemon/graphdriver/devmapper/deviceset.go | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/components/engine/daemon/graphdriver/devmapper/deviceset.go b/components/engine/daemon/graphdriver/devmapper/deviceset.go index be48d92e8d..b3e142e2ba 100644 --- a/components/engine/daemon/graphdriver/devmapper/deviceset.go +++ b/components/engine/daemon/graphdriver/devmapper/deviceset.go @@ -1732,6 +1732,29 @@ func (devices *DeviceSet) initDevmapper(doInit bool) (retErr error) { devices.devicePrefix = fmt.Sprintf("docker-%d:%d-%d", major(st.Dev), minor(st.Dev), st.Ino) logger.Debugf("Generated prefix: %s", devices.devicePrefix) + deviceNames, err := devicemapper.GetDeviceList() + if err != nil { + logrus.Debugf("devmapper: Failed to get device list: %s", err) + } + + for _, name := range deviceNames { + if !strings.HasPrefix(name, devices.devicePrefix) { + continue + } + _, length, _, _, err := devicemapper.GetStatus(name) + if err != nil { + logrus.Warnf("devmapper: get device status(%s): %s", name, err) + continue + } + // remove broken device + if length == 0 { + if err := devicemapper.RemoveDevice(name); err != nil { + logrus.Warnf("devmapper: remove broken device(%s): %s", name, err) + } + logrus.Debugf("devmapper: remove broken device: %s", name) + } + } + // Check for the existence of the thin-pool device poolExists, err := devices.thinPoolExists(devices.getPoolName()) if err != nil { -- 2.17.1