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
ebpf: delete existing pinned map if incompatible with the spec #15832
Conversation
3736a82
to
6ae9714
Compare
test-me-please |
retest-net-next |
// There already exists a pinned map but it has a different | ||
// configuration (e.g different type, k/v size or flags). | ||
// Try to delete and recreate 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.
Is it safe to do this for all maps? I also assume this can't be done "atomically"?
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.
Is it safe to do this for all maps?
That's what we are already doing with all the other maps that are opened using the bpf.OpenOrCreate()
method:
Lines 503 to 505 in 648f4f0
// the Map. If the existing map's attributes such as map type, key/value size, | |
// capacity, etc. do not match the Map's attributes, then the map will be | |
// deleted and reopened without any attempt to retain its previous contents. |
I'm not saying that this is necessarily the best approach, but since the aim of the ebpf
package is to (at least initially) mimic the bpf
package (to avoid introducing another dimension of complexity while we migrate to that) I think we should stick with this approach for now
edit: I just found that the bpf
package has also an Open()
method (in addition to the OpenOrCreate()
) which will return an error in case the map's spec is incompatible with the existing map
I also assume this can't be done "atomically"?
That's my understanding, yes
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 haven't looked deeply at the code yet, but I glanced quickly and couldn't tell if the PR addresses this comment: #15629 (comment)
See my previous comment #15832 (comment) In case the existing map is incompatible with the provided spec and we want to error on that, I believe we should use the |
@joestringer will provide a look at this PR to understand the implications of it. |
Thanks, I'll quickly recap all the context around this change as I fear it might be scattered around at this point:
|
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, one minor nit
6ae9714
to
400de83
Compare
test-me-please |
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 the recap, that was useful framing to consider these changes.
I went through the call stack for both cases and noticed a couple of remaining minor differences which I've highlighted below.
@@ -70,13 +71,42 @@ func (m *Map) OpenOrCreate() error { | |||
mapType := bpf.GetMapType(bpf.MapType(m.spec.Type)) | |||
m.spec.Flags = m.spec.Flags | bpf.GetPreAllocateMapFlags(mapType) | |||
|
|||
path := bpf.MapPath(m.spec.Name) |
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 we're still missing one other difference between the implementations: pkg/bpf/bpf_linux.go:OpenOrCreateMap()
will attempt to create the parent directory here before pinning; from a brief search through the ebpf library I didn't see the same logic.
Might not be too relevant for this PR depending on the order of map creation but we'll want to fix this up at some point before we fully switch libraries over.
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.
Yep, I initially ignored it as cilium_metrics
is not the first pinned map opened by the agent, but since we are on it I just added the logic to ebpf.OpenOrCreate()
Signed-off-by: Gilberto Bertin <gilberto@isovalent.com>
Signed-off-by: Gilberto Bertin <gilberto@isovalent.com>
400de83
to
aad4311
Compare
test-me-please |
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, just one remaining nit (with a few occurrences; we used to lint this out of the codebase but it seems we lost that linter somewhere along the way). Once that's addressed, LGTM.
pkg/ebpf/map.go
Outdated
log.WithField("map", m.spec.Name). | ||
Warnf("Removing map to allow for property upgrade (expect map data loss): %v", errors.Unwrap(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.
Usually we use .WithError()
to include an individual error, so that if a log shows up multiple times with different parameters, it is possible to correlate the common pieces in structured logging systems (eg the message is the same across all, but the error itself may vary). This can also help with grepping for an error as we can always tell that the msg=
part is static text:
log.WithField("map", m.spec.Name). | |
Warnf("Removing map to allow for property upgrade (expect map data loss): %v", errors.Unwrap(err)) | |
log.WithField("map", m.spec.Name). | |
WithError(err).Warn("Removing map to allow for property upgrade (expect map data loss)") |
ref. #14156
This commit updates the OpenOrCreate() method of the ebpf package to gracefully handle the case of a pinned map that is incompatible with the map's spec passed to the method. Rather than just returning the error returned by NewMapWithOptions(), we now log a warning and try to delete and recreate the pinned map. This mimics the behaviour of the old OpenOrCreate() method of the bpf package. Fixes: #15629 Signed-off-by: Gilberto Bertin <gilberto@isovalent.com>
When dealing with a pinned map in the ebpf.OpenOrCreate method, make sure the map's parent directory does exist (and try to create it in case it doesn't). Signed-off-by: Gilberto Bertin <gilberto@isovalent.com>
aad4311
to
320014e
Compare
test-me-please |
This PR updates the OpenOrCreate() method of the ebpf package to
gracefully handle the case of a pinned map that is incompatible with the
map's spec passed to the method.
Rather than just returning the error returned by NewMapWithOptions(), we
now log a warning and try to delete and recreate the pinned map.
This mimics the behaviour of the old OpenOrCreate() method of the bpf
package.
Fixes: #15629