-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Support of overlayfs metacopy option #7141
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
Conversation
|
Hi @artqzn. Thanks for your PR. I'm waiting for a containerd member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
|
Dear reviewer/maintainers @AkihiroSuda @dmcgowan @rata, could you please check if the approach is ok for you? Original issue #7141. |
| metacopyState = MetacopyDefault | ||
| } else { | ||
| metacopyState = MetacopySupported | ||
| } |
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 the parameter is read successfully, could it just return here?
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.
Yes, reasonable, will fix. Thank you!
rata
left a comment
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.
@artqzn Thanks! I left some comments, overall looks fine to me :D
| } | ||
|
|
||
| const ( | ||
| MetacopyDefault = 0 |
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.
Maybe use iota here? Or do we need it to be these specific numbers?
EDIT: as I mentioned in the other comment, I think SupportsMetacopy can just return a bool instead of these. If that happens to be true, ignore this comment :)
snapshots/overlay/overlay.go
Outdated
| metacopyState: metacopyState, | ||
| } | ||
|
|
||
| logMetacopyState(s) |
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 it make sense to log inside overlayutils.SupportsMetacopy() instead of here?
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.
Yes, reasonable, will fix.
snapshots/overlay/overlay.go
Outdated
| useMetacopy: config.metacopy, | ||
| metacopyState: metacopyState, |
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.
Do we really need both here? Can't we just save a bool here that is: config.metacopy && metacopySupported and change metacopyState to return true/false to signal if metacopy is supported or not?
Maybe I'm being overly simplistic and missing something? I think if metacopy is supported, then we can always append the metacopy=on/off to the mount point, and if it is not supported then we don't append anything.
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.
Yes, we can do like this. In case of CONFIG_OVERLAY_FS_METACOPY=y the metacopy=on option is just ignored and not shown in mount options, the same for CONFIG_OVERLAY_FS_METACOPY=n the metacopy=off. I'll update this place.
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.
Oh, sounds great then! :)
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.
One note here, I think that we need to keep three states for metacopy field (Enabled, Disabled, Not supported). We need this because of in case of old kernels the mount operation can fail due to metacopy=on/off option is unsupported.
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.
But if metacopy is unsupported, we won't add the option, right? What is the issue, then? I don't follow
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'm saying we don't need both fields in this struct. We need just one bool that is: config.Metacopy && metacopySupported. IOW, this bool is true only if metacopy is requested in the config and supported in the kernel. Othweise is false
We need to know if the metacopy was enabled in the config and we need to know if the kernel supports metacopy. But we don't need to store both things as different bools here, we just need to store one bool with the AND of both.
Is it clear what I say now? Am I missing something?
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.
First case:
Metacopy supported by kernel and CONFIG_OVERLAY_FS_METACOPY=Y.
In this case overlayfs mounts will be created with metacopy support even if we don't pass metacopy=on option to mount() system call.
config.Metacopy = false.
As result:
config.Metacopy = false && metacopySupported = true == false -> mount with metacopy=off-> ok, metacopy disabled for this mount point
Second case:
Metacopy is not supported by kernel.
config.Metacopy = false.
As result:
config.Metacopy = false && metacopySupported = false == false -> mount with metacopy=off -> mount failed
We need third state to distinguish between these situations.
In your approach if CONFIG_OVERLAY_FS_METACOPY=Y and config.Metacopy = false we just don't add metacopy=on/off option to mount system call and metacopy will be silently enabled for containers without containerd request.
In case of assumption that nobody set CONFIG_OVERLAY_FS_METACOPY=Y, yes, we no need third state.
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.
Oh, right, brain fart here (it was implied in the "f metacopy is supported" that I was wrong, as we lost that data combining the bools).
I do think, though, that we don't need the enum state. We need to know if it is supported and if it was enabled, then we can just add the on/off unconditionally. IMHO it seems simpler (less things to know and reason about) and avoids races like the sysfs value changed just between when we read it and when the overlayfs was mounted.
Does it make sense?
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.
In fact the first iteration use two booleans, one for on/off and one for supported/unsupported. From my point of view it doesn't matter enum or booleans, for me enum is more clear just maybe because of I am mostly C programmer ). I'll just compare what option looks better and publish better version.
Regarding sysfs, we can just use stat for /sys/modules/overlay/parameters/metacopy to check supported or not and yes, add on/off unconditionally. This should be race-free.
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.
SGTM
| testData := "Let me use metacopy!" | ||
|
|
||
| testDir, err := os.MkdirTemp(root, "metacopy_test") |
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.
Just curious, in which case can we fail to check via the sysfs files and we want to do a test mount to see if it is available? When sysfs is not mounted? Is there some other case?
I'm ignorant here, but do we care about sysfs not being mounted? Maybe it is common in some scenarios that I don't know about?
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.
Yes, this is for the cases when there is no sysfs mounted or there are some specific LSM policies. But I also not sure that this is the case. So, maybe I will simplify this check to use sysfs only and move this to integration test.
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 don't have a strong opinion here, not sure if in other parts of the code we already rely on sysfs maybe? I'd let others weight in. Maybe @dmcgowan that also reviewed this?
Note, however, if you are adding an early return here as @dmcgowan suggested, it would not check the LSM and those things you mentioned. Right?
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.
Yes, in this case it will work like this:
check via sysfs is ok? -> return, otherwise -> slowpath, check via xattrs
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 don't have a strong opinion here, not sure if in other parts of the code we already rely on sysfs maybe? I'd let others weight in. Maybe @dmcgowan that also reviewed this?
Another argument for simplification is the next:
overlay snapshotter already use sysfs to check overlay "index=off" option.
containerd/snapshots/overlay/overlay.go
Line 569 in 681aaf6
func supportsIndex() bool {
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.
@artqzn right, I think that is what I was thinking about that we already use it. My vote is to remove all of the rest, then.
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.
Ok, great, will do like this.
| if _, err := os.Stat("/sys/module/overlay/parameters/metacopy"); err == nil { | ||
| metacopy, err := os.ReadFile("/sys/module/overlay/parameters/metacopy") |
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 seems the stat is not used. Can't we just remove the first if to stat, and try to read the file? If it doesn't exist, then it should return an error
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.
Hmm, or maybe we don't need to read the file and just stat it with the other simplifications. If the file exists, we can clearly use metacopy in the mounts and that is all we need to know, we don't need to know the content (after the simplifications are done). Right?
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 support the case when metacopy enabled by default in Linux kernel (CONFIG_OVERLAY_FS_METACOPY=Y) and we would like to disable it by passing metacopy=off to overlay mount point we can do like this.
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 think this will become more clear once you push the next iteration. We can discuss it then, if needed :)
362826e to
091b59f
Compare
snapshots/overlay/overlay.go
Outdated
| } | ||
|
|
||
| // metacopyState returns the "metacopy" option according to kernel support and containerd config. | ||
| func metacopyState(state bool) int { |
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 are keeping the enum, I think this should not be an int but it's own type? I don't know, int seems weird, but no strong opinion.
In any case, I think changing this to return a bool instead seems simpler. Like func metacopySupported() bool (or whatever is a good name, haven't thought about it).
Then, if it is supported, we add the on/off as it was requested on the params. Otherwise, we don't add those params and just log.
Does it make sense?
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've updated the PR. I think that enum is better, especially after comment from @AkihiroSuda #7141 (comment), due to it would be good to hide all checks in one small function that return 3-state metacopy configuration and then use simple switch to provide right mount option. I think it is just more readable and clear.
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 point, SGTM! Thanks!
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.
Thanks for review Rodrigo!
rata
left a comment
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.
Just one more idea, let me know what you think
| case metacopyDisabled: | ||
| options = append(options, "metacopy=off") | ||
| } | ||
|
|
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.
userxattr and metacopy=on cannot be specified together
https://github.com/torvalds/linux/blob/4b0986a3613c92f4ec1bdc7f60ec66fea135991f/fs/overlayfs/super.c#L734
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.
Yes, thanks, I'll add this check
091b59f to
de43a9d
Compare
rata
left a comment
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 :)
Left one small doubt, but on a cursory look, seems fine for me :)
snapshots/overlay/overlay.go
Outdated
| return metacopyDisabled | ||
| } | ||
| if userxattr { | ||
| logrus.Warnf("userxattr, and metacopy=on can't be used together. Metacopy disabled.") |
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'm unsure which is is the right behavior: (a) logging and continue or (b) returning an error. But no strong opinion, I lack the context about how userxattr is set
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.
The userxattr option is set in case of we try to create unprivileged mount point of overlayfs, for example in case of containerd is running inside user namespace under user that is not a real root. @AkihiroSuda, please correct me if I am wrong. In this case we will be unable to create overlayfs mount point with metacopy=on.
Regarding error handling I've just following the userxattr option handling approach.
If mounting of rootfs with metacopy=on is impossible, this is not a critical failure. So, we can log warning here.
Dear reviewers @AkihiroSuda @dmcgowan , could you please share your opinion here?
Thanks.
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.
Also, maybe it is necessary to add a sanity check for redirect_dir, due to metacopy=on will not work if redirect_dir={off|nofollow|follow(*)}. This is from https://www.kernel.org/doc/Documentation/filesystems/overlayfs.txt.
But currently containerd doesn't touch redirect_dir, due to this fact I drop this check.
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.
Warn looks good
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.
Thanks @AkihiroSuda!
snapshots/overlay/overlay.go
Outdated
|
|
||
| if !metacopy { | ||
| logrus.Infof("Metacopy disabled.") | ||
| return metacopyDisabled |
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.
Our recommendation has been to use the system parameters here. If you had previously enabled then upgraded with this change, would it become disabled by default with no configuration change?
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.
Yes, with no configuration change metacopy will be disabled, even it was enabled by CONFIG_OVERLAY_FS_METACOPY=Y in Linux kernel. The CONFIG_OVERLAY_FS_METACOPY option is usually disabled by default, but yes, we can have customized installation or customized overlay.ko that contains CONFIG_OVERLAY_FS_METACOPY = Y.
Possibly we can do like this:
In case of metacopy=true in /etc/containerd/config.toml we add metacopy=on option to overlayfs mount point if metacopy is supported. Otherwise, don't add any option to overlayfs mount point and use system defaults. In this case it will be safe to use default configuration if CONFIG_OVERLAY_FS_METACOPY=Y
With such approach we will be unable to switch metacopy support off for overlayfs snapshotter if metacopy is enabled system-wide. But looks like this is not our goal.
I'll update the logic If such approach is ok.
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.
Maybe we can just have the config field be a *bool instead? We know when it is not set (it is nil) and we don't change anything, or when it is set to true/false and do the right thing.
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.
@rata Good idea, it would be bad to introduce string field in config or something like this to enable 3-state configuration. Will test and update PR. Thanks!
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.
Hi, I've updated the implementation. Now, if there is no metacopy option in /etc/containerd/config.toml the overlayfs module configuration is used, and containerd doesn't override system default.
Also, in case of *bool config option for metacopy support it is better to use booleans in snapshotter config instead of enum, due to it simplify options conversion.
@rata, @AkihiroSuda, @dmcgowan, could you have a look please.
Thank you in advance!
de43a9d to
82b3bf9
Compare
rata
left a comment
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.
@artqzn thanks! This looks okay to me, left some nit comments. But maybe they are too much about personal taste :)
snapshots/overlay/overlay.go
Outdated
| return false | ||
| } | ||
|
|
||
| // supportsIndex checks whether the "metacopy" option is supported by the kernel. |
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.
| // supportsIndex checks whether the "metacopy" option is supported by the kernel. | |
| // supportsMetacopy checks whether the "metacopy" option is supported by the kernel. |
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.
Thanks fixed
snapshots/overlay/plugin/plugin.go
Outdated
| if config.Metacopy != nil { | ||
| oOpts = append(oOpts, overlay.WithMetacopyCtrl) | ||
| if *config.Metacopy { | ||
| oOpts = append(oOpts, overlay.WithMetacopy) | ||
| } | ||
| } |
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'm not convinced still that making the field in SnapshotterConfig a *bool isn't simpler. We just assign it here (we won't need two "overlay.WithMetacopy..." functions), and then we test for not nil in other parts of the code (instead of metacopyCtr) and that is it.
Just my personal taste (and I'm no maintainer here), definitely not a must.
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.
Here I agree, but I just don't want to change the original behavior. Currently the parameters for func NewSnapshotter(root string, opts ...Opt) (snapshots.Snapshotter, error) function are passed using "ops", like
// WithUpperdirLabel adds as an optional label
// "containerd.io/snapshot/overlay.upperdir". This stores the location
// of the upperdir that contains the changeset between the labelled
// snapshot and its parent.
func WithUpperdirLabel(config *SnapshotterConfig) error {
config.upperdirLabel = true
return nil
}
We can pass SnapshotterConfig structure directly to NewSnapshotter, but in this case it should be prepared in plugin.go.
I can do this, not a problem, if there no objections from other reviewers, due to I don't know the story, why current approach was used.
snapshots/overlay/overlay.go
Outdated
| if config.metacopyCtrl { | ||
| if metacopyOn { |
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 are keeping the two bools, then this is redundant. metacopyOn is true if config.metacopyCtrl.
Of course, you can't just change that for if metacopyOn as the else case would be broken (we can add when it is not supported). But it seems like this could be simplified.
Maybe the if should be: if config.metacopyCtrl && supportsMetacopy() and inside that you test for metacopyOn and userxattr?
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.
This is just debug leftover, I'll remove it, thanks!
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 think you introduced the bug I mentioned it is easy to introduce here. But let's move the conversation to: https://github.com/containerd/containerd/pull/7141/files#r929864915
|
Question; what's the behavior if this option is enabled (or disabled) while existing state (snapshots) exist? Must the snapshotter be aware of how the snapshot was created (with this option enabled or disabled) in order to properly handle it? |
82b3bf9 to
a545b1d
Compare
snapshots/overlay/overlay.go
Outdated
| if o.metacopyOn { | ||
| options = append(options, "metacopy=on") | ||
| } else { | ||
| options = append(options, "metacopy=off") |
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.
But with this change, then, it has the bug that I mentioned here: #7141 (comment)
If metacopy is set to false in the config but the kernel doesn't support it, we will append the metacopy=off option. I'm not sure that is incorrect (the user asked for it), but the true value is only used when it is also supported.
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.
Yes, sorry, fixed.
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.
Current version is ok.
metacopyCtrl := config.metacopyCtrl && supportsMetacopy() - true only if metacopy is supported, so we add metacopy=on/off only in case we have support from overlayfs.
Hi, there is one possible problem, but I am not sure if this can be the real case. Solutions:
Thanks! |
a545b1d to
c17babf
Compare
|
Thanks! Right, so from that information, it seems indeed that some state / metadata should be preserved somewhere. I must admit I'm not familiar enough with options where to store additional metadata like this. A simple file could perhaps work (and the advantage that it's easy to read without much overhead), but perhaps it should be something more generic, and generic enough for possible uses by other snapshotters? Maybe others have an opinion / idea on that. For completeness; IIUC, there will be three possible states;
Which, basically means; if no FWIW (and not sure if needed for this feature) a PR from @neersighted was merged recently in Moby to perform detection of metacopy support; see moby/moby#43557 |
Thanks! The file definitely should work, but yes, maybe somebody will be able to suggest the right place for storing metacopy state.
Unfortunately I don't have a lot of information about use cases here, the question is if it is possible that
Agreed, but here again looks like we just should follow snapshot metadata. If we preserve metacopy state in snapshot metadata we should deploy snapshot according it and fail if metacopy is not supported. Please correct me if I am wrong here.
Here I am not sure. Looks like it is enough to check if Thanks! |
To test if metacopy is supported, it should be sufficient to check if the parameter exists on the kernel module. The purpose of the Moby PR is to check if metacopy is on at runtime, as Moby never explicitly enables or disables it. Metacopy being on or off can be useful for debugging disk usage or permissions issues (on old kernels that had a bug in metacopy), but if you're explicitly managing it I don't see a reason to create a mount and test. |
@neersighted Thanks for clarification! In this case it should be enough to just use |
snapshots/overlay/overlay.go
Outdated
| metacopyOn *bool | ||
| ) | ||
| if config.metacopyOn != nil { | ||
| if metacopyKernel, err = overlayutils.SupportsMetacopy(); err != nil && !os.IsExist(err) { |
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 !os.IsExist here? (Should it be IsNotExist?) And shouldn't we treat it as "failed to check for kernel option" as well?
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.
And shouldn't we treat it as "failed to check for kernel option" as well?
It's reasonable, if a user specified metacopy option then we expect that there's support from the kernel, otherwise just error out. I'll fix this in the next iteration. Thanks!
snapshots/overlay/overlay.go
Outdated
| upperdirLabel bool | ||
| indexOff bool | ||
| userxattr bool // whether to enable "userxattr" mount option | ||
| metacopyOn *bool |
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 can't this be a bool? In other words, is there any difference between metacopyOn == nil and *metacopyOn == false?
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.
There are three options:
metacopy=onby config.metacopy=offby config.- metacopy option wasn't specified.
In previous version it was:
type snapshotter struct {
root string
ms *storage.MetaStore
asyncRemove bool
upperdirLabel bool
indexOff bool
userxattr bool // whether to enable "userxattr" mount option
metacopyOn bool
metacopyCtrl bool
}if metacopy option specified -- metacopyCtrl = true if it's not -- metacopyCtrl = false. We decided to make metacopyOn a simple *bool only for the sake of simplicity, so now if metacopyOn = nil that means a user didn't specify metacopy option.
041b130 to
07f1d29
Compare
| if err != nil { | ||
| t.Fatal(err) | ||
| } else if userxattr { | ||
| expected = append(expected, "userxattr") |
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.
This looks wrong to me, actually testOverlayOverlayMount does the same, but according to the sequence in snapshots/overlay/overlay.go if userxattr and index is supported then we should have m.Options = ["userxattr", "index=off"], but expected = ["index=off", "userxattr"]?
|
@dmcgowan , @AkihiroSuda , @rata PTAL |
07f1d29 to
9a08295
Compare
This patch introduces support of metacopy optimization for overlayfs mount points. (https://www.kernel.org/doc/Documentation/filesystems/overlayfs.txt). Metacopy support for containerd can be enabled by new option "metacopy=on/off" in configuration file (/etc/containerd/config.toml). The metacopy option is located in overlayfs snapshotter configuration section: [plugins."io.containerd.snapshotter.v1.overlayfs"] root_path = "" upperdir_label = false mount_options = ["metacopy=on/off"] If /etc/containerd/config.toml doesn't provide metacopy option, containerd doesn't override system configuration and overlayfs module defaults are used. Signed-off-by: Artem Kuzin <[email protected]> Signed-off-by: Ilya Hanov <[email protected]>
Signed-off-by: Artem Kuzin <[email protected]> Signed-off-by: Ilya Hanov <[email protected]>
9a08295 to
151b86d
Compare
| // check one more time because user may not specify the option but above we did it. | ||
| if hasOption(config.mountOptions, "metacopy=on", false) { | ||
| if hasOption(config.mountOptions, "userxattr", false) { | ||
| logrus.Warnf("cannot apply \"metacopy=on\" when \"userxattr\" is set") |
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.
What is the conflict with userxattr?
The docs only say
Note: redirect_dir={off|nofollow|follow[*]} and nfs_export=on mount options conflict with metacopy=on, and will result in an error.
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.
Maybe docs aren't complete, check this. I need to re-read the docs.
[480303.568757] overlayfs: conflicting options: userxattr,metacopy=on
|
/ok-to-test |
|
/retest |
|
@artqzn: The following test failed, say
Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
|
This potentially has quite a lot of implications for buildkit. One case is the overlay-specific differ that walks the upper dir. This would need to understand the origin xattr or it would create bogus file content in the layer blobs. Another case is the DiffOp (and MergeOp?), where layers can be accessed without parents. If some of such layers will be metadata-only stubs then that will not produce correct content. Not against the concept as a whole, but we need to think through all such possible cases and patch where needed. |
Agreed, I think the baseline for all the impacted buildkit features would be to just disable the optimizations when metacopy is being used in a given image layer. Then we can re-incorporate support for metacopy into the features over time. However, one immediate concern remains which is that MergeOp/DiffOp specifically work with both local layers and remote layers (lazy references to them). To disable optimizations when metacopy is being used, we'd need to know whether a layer is using it, which is easy enough for local layers but unclear for remote layers. Is it possible (or already implemented) to include OCI annotations in layers that indicate they use metacopy? That would let us grab the remote metadata without having to pull the entire layer locally, unpack it and scan it for any metacopy usage. Apologies if this is already addressed previously in this PR/discussion or otherwise missing something obvious, I'm just dropping in with little context after being pinged 😅 |
I don't agree. This PR tries to prevent few of dead cases and has nothing to do with breaking any existent behavior. We only enable metacopy if it already is or we have no containers (which means you're free to disable it on system-wide level before creating snapshots or so). The dead case that is not controlled at all is that a user may disable metacopy if there already are some containers with metacopy=on which means a possibility of losing content in upperdir, but if a user still want to do it we just rely on system's choice (which means we do almost nothing). So, this PR tries to enable metacopy only if it is safe, otherwise user can change it as s(he) wishes. @tonistiigi , the cases you mentioned make sense and I agree that they must be controlled, but this PR doesn't touch them. It should be different story.
@sipsma , I'm not very familiar with OCI annotations and its implementation, but looks like it is possible because those layers have metacopy xattr, so you're free to check it and include an annotation. |
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.
Circling back to register a -1 for now; after extensive discussion on how to integrate metacopy with higher-level tools e.g. BuildKit with @tonistiigi, I have concerns about adding integration points for other tools (e.g. custom differs).
I also find the code in overlay.go to be too imperative; I think we need to very carefully define each and every circumstance this code handles and make it more clear up front.
I'm going to try to find some time to review this in more detail and provide more actionable feedback/a PR against the PR.
|
PR needs rebase. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
|
This PR is stale because it has been open 90 days with no activity. This PR will be closed in 7 days unless new comments are made or the stale label is removed. |
|
This PR was closed because it has been stalled for 7 days with no activity. |
Hi, this is implementation of metadata copy only functionality for overlayfs snapshotter,
issue #6310 (comment).
To enable/disable metacopy functionality the new configuration option for containerd
overlayfs snapshotter was introduced into /etc/containerd/config.toml, (metacopy=true/false).
The "metacopy" option of overlayfs snapshotter controls overlayfs behavior according to the
next table:
Thanks!