-
Notifications
You must be signed in to change notification settings - Fork 261
store: use canonical image mapping when mounting #2285
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
store: use canonical image mapping when mounting #2285
Conversation
e0af89b
to
6287869
Compare
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
6287869
to
a0412cc
Compare
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
so this seems to fix the problem: containers/podman#25606 |
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 understand ~nothing about the problem space.
With idmapped mounts, there is no extra cost to change the IDs at runtime when using overlay.
This code has no condition for “using overlay”, so I don’t know how that relates. Doesn’t it break the other graph drivers?
This allows the image to be mounted directly with VFS, avoiding any mismatch that could occur when it was previously created with an explicit ID mapping.
AFAICS for non-writeable == image layers, uidMap
, gidMap
come from the options passed by c/image; and c/image passes nothing, so the existing condition is ~equivalent to Driver.SupportsShifting
. That sounds, intuitively, about right? (See above about “using overlay”).
Also, assuming that uidMap
/gidMap
are always nil
during pulls, the two if
cases only differ in Host?IDMapping
fields … and those fields are not used anywhere in the callees, AFAICS. So how does this make a difference? [Reusing the same types for different purposes is a mess…]
So… I’m confused. I appreciate that there are test PRs that suggest this does something, but just looking at this PR, I can’t see what, or how it possibly could.
(If other reviewers understand what is going on, that’s fine, this does not need to block on me.)
the reason why we have this code is that if you run something like:
and the IMAGE is not present in the local storage, it is pulled directly with the specified mapping. In this way we don't need to create another copy of the image before running the container. This is not an issue anymore with overlay, since with idmapped mounts we already store the "canonical" image, since With VFS it does not matter, because for the container we always need to create a full copy anyway. The issue we had in Podman is that if you run something like:
we would end up mounting the image with the mapping A:B:C, which is of course wrong. An alternative solution would be to create a copy of the image at I've picked this alternative because it is easier to implement as we already have the logic to handle it, and because I don't see the value in doing this anymore, since the driver we care the most about (overlay) can do the mapping at runtime without any additional setup cost. |
Oh, I see what I missed: if !options.HostUIDMapping && len(options.UIDMap) == 0 {
uidMap = s.uidMap
} in |
Is that true for rootless? I thought rootless can never use idmapped mounts (unless we use fuse-overlayfs). As such this optimization would be lost for rootless pulls then? |
that is a good point! No that is not true for rootless and it might impact toolbx |
So, approximately, The current approach ~relies on But what about And I see a Podman caller of
The issue I have with this (if I understand things, which is unlikely) is that it is extremely indirect and invisible to readers of the code.
I’m all for simplifying things and not processing irrelevant options on unreachable code paths. But then the code paths should be recognizably unreachable. E.g. deprecate the public I suppose that’s a lot of work, quite possibly more work than making the top-level mapping work as expected for this use case. But then again, I understand very little about all this code. |
… and if either of the graph drivers decided to change these features (maybe VFS grew some kind of “fast copy” that required the UID maps to match), how would anyone notice that this |
I don't know much about these drivers. If changes in c/storage would depend on these drivers we would just stop doing any. Your analysis is correct, with containers we use |
Interesting. Making a (potentially very expensive) copy in the primary store on a “mount” would be unexpected… and would we try to delete it again on unmount?
On second thought, that should be fine, because we would be mounting not an image layer, but the container’s layer, which is already ID-shifted, isn’t it? I think the VFS situation can be modeled ~precisely by:
And we would let the other graph drivers do what they have always done, blindly hoping that it is correct. But I don’t see how this is desirable for the overlay cases where shifting is not available. |
I don't think we want to keep the current behavior in any case, an optimization makes sense only when the result is correct. If I run |
I agree “all image layers are always using the default mapping” is a reasonable and consistent design, in general. Now that we have the other one, switching could potentially have performance implications, by requiring the ID-mapped container layer to be now expensively created. I don’t know how much we care and I don’t know how to tell. (Does not doing any mapping for image layers work for rootless? I guess it does because everything happens inside a namespace, but just to confirm.) |
a0412cc
to
c7cf6cf
Compare
5097732
to
3c6a71a
Compare
pushed a new version, now a canonical mapping is created by MountImage if one doesn't already exist. It fails if the image exists only in an additional image store without the canonical mapping, but I think that is a weird configuration anyway. |
Sounds reasonable to me, can you please test this version again in podman to make sure there is no new regression. |
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
I’d much rather add a specialized One reason is the general design aspect: it’s better to make precisely the promise the caller cares about, and not expose implementation details that affect that promise but don’t exactly match, where we wouldn’t notice when changing c/storage that the Podman CLI also needs updating. An equally important reason is that we have all these conversations about redesigning the layer store backing (bootc), and redesigning layer identities (sha512); both almost certainly require changes to the driver API, so I’m thinking we should make it internal-only and deprecate the public |
3bcc709
to
b8e65cf
Compare
@mtrmac fine to merge? |
@nalind ok to merge (together with containers/common#2374)? |
store.go
Outdated
var imageHomeStore roImageStore // Set if image != "" | ||
var cimage *Image // Set if image != "" |
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 Set if image != ""
comments are not applicable here.
(Non-blocking nit: The variables could be moved immediately before their first use (or, in case of cimage
, use :=`).)
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 primary thing I’d like to see fixed here is removing the incorrect/inapplicable comments.
b8e65cf
to
997b284
Compare
for _, layerID := range img.MappedTopLayers { | ||
l, err := rlstore.Get(layerID) | ||
if err != nil { | ||
return false, 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.
The previous version silently ignored ErrLayerUnknown
. Is the change intentional?
I don’t have much of an opinion, failing immediately could be argued to be better, I just want to avoid accidents.
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.
before we were running without keeping the lock, so that error was expected. Now, I am not sure we should ignore it.
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, good point.
We are back to loading the image, unlocking, and then looking at layers, so we might again hit a race here. Should this go back to the previous behavior?
997b284
to
c79c89f
Compare
c79c89f
to
13b082b
Compare
b315a18
to
0b13549
Compare
podman tests pass with the last version |
the vfs driver does not create any mount, so it doesn't accept any argument passed to MountImage. Drop the arguments so mount image can be used in the tests suite. Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
0b13549
to
c606848
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.
LGTM.
Please consider #2285 (comment) , and #2285 (comment) .
And after looking at that, feel free to merge without another review.
Ensure that a mapped layer with the canonical mapping is created if one doesn't already exist. Previously, any layer was used regardless of its mapping, which resulted in the mounted image having incorrect file ownership, depending on what mapping was found. Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
c606848
to
360c002
Compare
thanks, pushed a new version. I'll merge once the CI is green. Fine to merge containers/common#2374 too? |
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
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: giuseppe, mtrmac The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Ensure that a mapped layer with the canonical mapping is created if one doesn't already exist. Previously, any layer was used regardless of its mapping, which resulted in the mounted image having incorrect file ownership, depending on what mapping was found.