-
Notifications
You must be signed in to change notification settings - Fork 18.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix error removing diff path #34587
Fix error removing diff path #34587
Conversation
// Atomically remove each directory in turn by first moving it out of the | ||
// way (so that docker doesn't find it anymore) before doing removal of | ||
// the whole tree. | ||
if err := atomicRemove(mountpoint); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the order of deletion changed in here? I think it makes more sense to remove mount before diffs because they are more likely to get EBUSY
(and in some versions, you can't remove diff when it is mounted). And layers last as it should never fail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed this to match the original defer ordering.
I'll double check this later. Fine either way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. This indeed matches the order before #33960
@cpuguy83 to make this easier for cherrypicking in a patch release, can we make this commit as minimal as possible, addressing the removed defer only? I suggest you make it "more readable" in another PR, it's important for the diff to be small. |
Should we add a cleanup of |
@tonistiigi I was about to suggest the same, I think we should for ppl who installed 17.06.1 |
@tonistiigi @vieux shouldn't that be only in the patch release, and not master? |
if ppl go from 17.06.1 -> 17.07.0 they won't get the fix if we put it in the patch release only |
The primary reason I moved it out rather than keeping it all in one function is I needed to add additional error handling for the
|
Would it be suitable to have a unit test in the corresponding aufs_test.go? |
817aeb2
to
84ba209
Compare
Added tests to make sure that there's no |
@tonistiigi @tiborvass LGTY now? Let's get this one in asap |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
daemon/graphdriver/aufs/aufs_test.go
Outdated
@@ -149,6 +151,9 @@ func TestRemoveImage(t *testing.T) { | |||
if _, err := os.Stat(path.Join(tmp, p, "1")); err == nil { | |||
t.Fatalf("Error should not be nil because dirs with id 1 should be delted: %s", p) | |||
} | |||
if _, err := os.Stat(path.Join(tmp, p, "1-removing")); err == nil { | |||
t.Fatalf("Error should not be nil because dirs with id 1-removing should be delted: %s", p) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deleted
In d42dbdd the code was re-arranged to better report errors, and ignore non-errors. In doing so we removed a deferred remove of the AUFS diff path, but did not replace it with a non-deferred one. This fixes the issue and makes the code a bit more readable. Signed-off-by: Brian Goff <cpuguy83@gmail.com>
84ba209
to
276b446
Compare
LGTM |
p := filepath.Join(root, path) | ||
dirs, err := ioutil.ReadDir(p) | ||
if err != nil { | ||
logrus.WithError(err).WithField("dir", p).Error("error reading dir entries") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be great to mention aufs in the error message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless some higher caller already inserts that info
@@ -142,6 +142,23 @@ func Init(root string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap | |||
} | |||
} | |||
|
|||
for _, path := range []string{"mnt", "diff"} { | |||
p := filepath.Join(root, path) | |||
dirs, err := ioutil.ReadDir(p) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a bit confusing to call the variable dirs because they may not all be dirs. Entries?
} | ||
for _, dir := range dirs { | ||
if strings.HasSuffix(dir.Name(), "-removing") { | ||
logrus.WithField("dir", dir.Name()).Debug("Cleaning up stale layer dir") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mention aufs
if strings.HasSuffix(dir.Name(), "-removing") { | ||
logrus.WithField("dir", dir.Name()).Debug("Cleaning up stale layer dir") | ||
if err := system.EnsureRemoveAll(filepath.Join(p, dir.Name())); err != nil { | ||
logrus.WithField("dir", dir.Name()).WithError(err).Error("Error removing stale layer dir") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aufs
@@ -317,31 +334,25 @@ func (a *Driver) Remove(id string) error { | |||
retries++ | |||
logger.Warnf("unmount failed due to EBUSY: retry count: %d", retries) | |||
time.Sleep(100 * time.Millisecond) | |||
continue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I can't see on the phone the whole function. Just want to make sure the return statement at the end the block is wanted and shouldn't instead be a logging statement followed by this removed continue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's a continue at the end of a for loop, it was useless
Test LGTM: I've verified that without this fix, the tests added to
Nit-pick (not required for merge): in the future, it may be more helpful to have changes to tests as a separate git commit to the PR. Also, spelling: |
@andrewhsu the spelling mistake was fixed already. LGTM despite minor nitpicks |
let's do a follow up PR |
@cpuguy83 hi, do you have plan to backport this fix to older version of docker, like 1.10 or 1.12? |
@judtlaputa this is a specific fix for a regression in 17.06.1. |
resolves annoying disk space eater "-removing" regression with aufs/diff moby/moby#34587 moby/moby#21925 (comment) https://stackoverflow.com/a/45798794 moby/moby#22207
In d42dbdd the code was re-arranged to
better report errors, and ignore non-errors.
In doing so we removed a deferred remove of the AUFS diff path, but did
not replace it with a non-deferred one.
This fixes the issue and makes the code a bit more readable.