-
Notifications
You must be signed in to change notification settings - Fork 67
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
fs: add DiffDirChanges function to get changeset fast #145
Conversation
The original issue is from moby/buildkit#1192. The docker uses graphdriver to retrieve the layer diff based on AUFS/OverlayFS and it is fast than containerd Compare API which walks the whole rootfs directory. The github.com/containerd/continuity/fs package provides the |
ade3c4b
to
3214e3b
Compare
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.
@fuweid Are you still working on this?
Fixing slow diff has been gathering demand in the community (moby/buildkit#1704, moby/buildkit#1192).
Can we move this forward?
fs/diff.go
Outdated
case DiffSourceAUFS: | ||
o = &diffDirOptions{ | ||
skipChange: skipAUFSMetadata, | ||
} |
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 snapshotter is deprecated since containerd v1.5. Could we focus on overlayfs in this PR?
yeah. will update it in days~ Thanks! |
Why was this never merged? |
I think this can be just merged after rebasing and removing AUFS codes |
oops. Will update it later. Thanks for remider |
3214e3b
to
b9af6a9
Compare
// CreateDeviceFile provides creates devices Applier. | ||
func CreateDeviceFile(name string, mode os.FileMode, maj, min int) Applier { | ||
return applyFn(func(root string) error { | ||
return errors.New("Not implemented") |
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.
Nit: should we use errdefs.ErrNotImplemented
?
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.
Good catch. Let me handle it in the follow-up. (Use containerd/errdefs repo to handle this).
fs/diff_test.go
Outdated
@@ -350,7 +397,38 @@ func testDiffWithoutBase(t testing.TB, apply fstest.Applier, expected []TestChan | |||
return checkChanges(tmp, changes, expected) | |||
} | |||
|
|||
func testDiffDirChange(base, diff fstest.Applier, source DiffSource, expected []TestChange) error { | |||
baseTmp, err := ioutil.TempDir("", "fast-diff-base-") |
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.
ioutil is deprecated
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.
Updated
fs/diff_test.go
Outdated
func (tcs TestChanges) Len() int { return len(tcs) } | ||
func (tcs TestChanges) Less(i, j int) bool { return tcs[i].Path < tcs[j].Path } | ||
func (tcs TestChanges) Swap(i, j int) { tcs[i], tcs[j] = tcs[j], tcs[i] } | ||
|
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.
Can we just use sort.Slice
?
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.
Updated.
fs/diff.go
Outdated
|
||
if f.IsDir() { | ||
originalPath := filepath.Join(diffDir, path) | ||
opaque, err := sysx.LGetxattr(originalPath, "trusted.overlay.opaque") |
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.
user.overlay.*
has to be checked too
torvalds/linux@2d2f2d7
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.
Updated. Please take a look.
fs/diff.go
Outdated
originalPath := filepath.Join(diffDir, path) | ||
opaque, err := sysx.LGetxattr(originalPath, "trusted.overlay.opaque") | ||
if err != nil { | ||
if err == unix.ENODATA { |
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.
errors.Is
is more preferable over directly using the =
operator
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.
Updated.
b9af6a9
to
349dea6
Compare
349dea6
to
7e2b2a4
Compare
bcc5706
to
2545354
Compare
Many Thanks for the quick turnaround. |
2545354
to
19f4218
Compare
deletedFile := false | ||
|
||
if o.deleteChange != nil { | ||
deletedFile, err = o.deleteChange(diffDir, path, f, changeFn) |
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.
nilt: We don't need to mark this file as "deleted" if this file doesn't exist in the base 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.
good catch. Let me think how to handle this
fs/diff_linux.go
Outdated
// FIXME(fuweid): In spite of that .wh..wh..opq might not be | ||
// existing, mark it as faked delete change so that changeFn | ||
// will add whiteout prefix for this faked file. It requires | ||
// that changeFn callback must not read the os.FileInfo | ||
// parameter. |
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.
So the convention introduced here is that if 3rd arg is nil then changeFn
must make the dir opaque, right? Could we add this explanation to godoc of DiffDirChanges?
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.
Good catch. Sorry for late reply. Let me think about how to remove FIXME
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.
If we don't want to introduce a new convention, another approach might be starting a new doubleWalkDiffer on the opaque directory to make changeFn opaque-agnostic.
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.
Updated. Please take a look.
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.
For deleted file, 3rd one is nil. FYI
Is it possible to get this change to a previous version of containerd when it gets released? |
Unlikely, due to potential risk of regression. |
Is it possible to merge this soon? It will help us compile our own containerd. OTherwise I think we will need some code changes in containerd to use this branch or another fork. Thanks again for the quick turnaround. |
I created a (https://github.com/containerd/containerd/pull/9699/files) that essentially does not temp mount both upper and lower but only the lower. And then compares with the upper. It seems to work with the continuity changes in this pull request. Is this the correct approach? It is a pretty small change, just newline changes make it look large. |
6a68270
to
d3a8156
Compare
Since AUFS/OverlayFS can persist changeset in diff directory, DiffDirChanges function can retrieve layer changeset from diff directory without walking the whole rootfs directory. Signed-off-by: Wei Fu <fuweid89@gmail.com>
d3a8156
to
8b312bd
Compare
Since AUFS/OverlayFS can persist changeset in diff directory,
DiffDirChanges function can retrieve layer changeset from diff directory
without walking the whole rootfs directory.
Signed-off-by: Wei Fu fuweid89@gmail.com