111 lines
3.9 KiB
Diff
111 lines
3.9 KiB
Diff
From ef238d650231f8346078536b6133f147df11283a Mon Sep 17 00:00:00 2001
|
|
From: zhangyu235 <zhangyu235@huawei.com>
|
|
Date: Fri, 18 Jan 2019 19:21:39 +0800
|
|
Subject: [PATCH 059/111] overlay2: avoid middle state while removing
|
|
images under overlay2
|
|
|
|
reason:avoid middle state while removing images under overlay2
|
|
|
|
kill -9 daemon while rmi images may cause some inconsistent state
|
|
of that image
|
|
|
|
if image symlink is removed but the id directory remained. daemon
|
|
restart and load again, the images look fine but create container
|
|
with it will error out:
|
|
`docker: Error response from daemon: error creating overlay
|
|
mount to /var/lib/docker/overlay2/xxx-init/merged:
|
|
no such file or directory`
|
|
|
|
This patch move symlink removal after directory removal, and check
|
|
link file state while daemon restore, to clean up stale links.
|
|
|
|
Change-Id: I44328bc2261c9ec73bcdcbed3d741e569cd4a834
|
|
Signed-off-by: Deng Guangxing <dengguangxing@huawei.com>
|
|
Signed-off-by: zhangyu235 <zhangyu235@huawei.com>
|
|
---
|
|
.../daemon/graphdriver/overlay2/overlay.go | 40 ++++++++++++++++---
|
|
1 file changed, 34 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/components/engine/daemon/graphdriver/overlay2/overlay.go b/components/engine/daemon/graphdriver/overlay2/overlay.go
|
|
index 773d5232cc..cf8993e9f3 100644
|
|
--- a/components/engine/daemon/graphdriver/overlay2/overlay.go
|
|
+++ b/components/engine/daemon/graphdriver/overlay2/overlay.go
|
|
@@ -229,6 +229,8 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
|
|
return nil, fmt.Errorf("Storage Option overlay2.size only supported for backingFS XFS or ext4. Found %v", backingFs)
|
|
}
|
|
|
|
+ d.cleanupLinkDir()
|
|
+
|
|
// figure out whether "index=off" option is recognized by the kernel
|
|
_, err = os.Stat("/sys/module/overlay/parameters/index")
|
|
switch {
|
|
@@ -245,6 +247,19 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
|
|
return d, nil
|
|
}
|
|
|
|
+func (d *Driver) cleanupLinkDir() {
|
|
+ filepath.Walk(path.Join(d.home, linkDir), func(path string, f os.FileInfo, err error) error {
|
|
+ if _, serr := filepath.EvalSymlinks(path); serr != nil {
|
|
+ logrus.Warnf("[overlay2]: remove invalid symlink: %s", path)
|
|
+ os.RemoveAll(path)
|
|
+ }
|
|
+ // always return nil, to walk all the symlink
|
|
+ return nil
|
|
+ })
|
|
+
|
|
+ return
|
|
+}
|
|
+
|
|
func parseOptions(options []string) (*overlayOptions, error) {
|
|
o := &overlayOptions{}
|
|
for _, option := range options {
|
|
@@ -575,8 +590,11 @@ func (d *Driver) Remove(id string) error {
|
|
d.locker.Lock(id)
|
|
defer d.locker.Unlock(id)
|
|
dir := d.dir(id)
|
|
- lid, err := ioutil.ReadFile(path.Join(dir, "link"))
|
|
- if err == nil {
|
|
+ lid, lerr := ioutil.ReadFile(path.Join(dir, "link"))
|
|
+ if err := system.EnsureRemoveAll(dir); err != nil && !os.IsNotExist(err) {
|
|
+ return err
|
|
+ }
|
|
+ if lerr == nil {
|
|
if !verifyID(string(lid), idLength) {
|
|
logrus.WithField("storage-driver", "overlay2").Errorf("refusing to remove empty link for layer %v", id)
|
|
} else if err := os.RemoveAll(path.Join(d.home, linkDir, string(lid))); err != nil {
|
|
@@ -568,9 +586,6 @@ func (d *Driver) Remove(id string) error {
|
|
}
|
|
}
|
|
|
|
- if err := system.EnsureRemoveAll(dir); err != nil && !os.IsNotExist(err) {
|
|
- return err
|
|
- }
|
|
return nil
|
|
}
|
|
|
|
@@ -710,7 +725,20 @@ func (d *Driver) Put(id string) error {
|
|
|
|
// Exists checks to see if the id is already mounted.
|
|
func (d *Driver) Exists(id string) bool {
|
|
- _, rerr := os.Stat(d.dir(id))
|
|
+ var rerr error
|
|
+ defer func() {
|
|
+ if rerr != nil {
|
|
+ logrus.Warnf("layer(%s) not exist: %s", id, rerr)
|
|
+ d.Remove(id)
|
|
+ }
|
|
+ }()
|
|
+
|
|
+ // check if the id directory exist and is valid
|
|
+ // check if link file exist and get link string from it
|
|
+ // check if symlink file exist
|
|
+ // if symlink not exist, create a new one and update link file
|
|
+ // any steps failed ,we will return false and remove this id layer
|
|
+ _, rerr = os.Stat(d.dir(id))
|
|
if rerr == nil {
|
|
lstr, err := ioutil.ReadFile(path.Join(d.dir(id), "link"))
|
|
// link is valid
|
|
--
|
|
2.17.1
|
|
|