From cf4b58f98f9da41c2e89d46d6c78bd777710b800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Mon, 13 Jun 2022 17:38:12 -0700 Subject: [PATCH] BpfMap - add BpfMapRO.init() support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Really we need to fix the inheritance to make BpfMapRO the parent class of BpfMap: but that's a far more difficult thing to do, so in the short term we punt like this. This makes BpfMapRO a little bit more usable, and allows a slow transition across the codebase... Test: TreeHugger Signed-off-by: Maciej Żenczykowski Change-Id: I1c5112db70e9e523c113cba536fbe19422b4d3f3 --- .../native/bpf_headers/include/bpf/BpfMap.h | 47 ++++++++++++------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/staticlibs/native/bpf_headers/include/bpf/BpfMap.h b/staticlibs/native/bpf_headers/include/bpf/BpfMap.h index 0054753b04..afb6fdf6a0 100644 --- a/staticlibs/native/bpf_headers/include/bpf/BpfMap.h +++ b/staticlibs/native/bpf_headers/include/bpf/BpfMap.h @@ -103,8 +103,29 @@ class BpfMap { return {}; } + protected: + [[clang::reinitializes]] base::Result init(const char* path, int fd) { + mMapFd.reset(fd); + if (mMapFd == -1) { + return ErrnoErrorf("Pinned map not accessible or does not exist: ({})", path); + } + if (isAtLeastKernelVersion(4, 14, 0)) { + // Normally we should return an error here instead of calling abort, + // but this cannot happen at runtime without a massive code bug (K/V type mismatch) + // and as such it's better to just blow the system up and let the developer fix it. + // Crashes are much more likely to be noticed than logs and missing functionality. + if (bpfGetFdKeySize(mMapFd) != sizeof(Key)) abort(); + if (bpfGetFdValueSize(mMapFd) != sizeof(Value)) abort(); + } + return {}; + } + + public: // Function that tries to get map from a pinned path. - [[clang::reinitializes]] base::Result init(const char* path); + [[clang::reinitializes]] base::Result init(const char* path) { + return init(path, mapRetrieveRW(path)); + } + #ifdef BPF_MAP_MAKE_VISIBLE_FOR_TESTING // due to Android SELinux limitations which prevent map creation by anyone besides the bpfloader @@ -209,23 +230,6 @@ class BpfMap { base::unique_fd mMapFd; }; -template -base::Result BpfMap::init(const char* path) { - mMapFd.reset(mapRetrieveRW(path)); - if (mMapFd == -1) { - return ErrnoErrorf("Pinned map not accessible or does not exist: ({})", path); - } - if (isAtLeastKernelVersion(4, 14, 0)) { - // Normally we should return an error here instead of calling abort, - // but this cannot happen at runtime without a massive code bug (K/V type mismatch) - // and as such it's better to just blow the system up and let the developer fix it. - // Crashes are much more likely to be noticed than logs and missing functionality. - if (bpfGetFdKeySize(mMapFd) != sizeof(Key)) abort(); - if (bpfGetFdValueSize(mMapFd) != sizeof(Value)) abort(); - } - return {}; -} - template base::Result BpfMap::iterate( const std::function(const Key& key, const BpfMap& map)>& @@ -292,8 +296,15 @@ base::Result BpfMap::iterateWithValue( template class BpfMapRO : public BpfMap { public: + BpfMapRO() {}; + explicit BpfMapRO(const char* pathname) : BpfMap(pathname, BPF_F_RDONLY) {} + + // Function that tries to get map from a pinned path. + [[clang::reinitializes]] base::Result init(const char* path) { + return BpfMap::init(path, mapRetrieveRO(path)); + } }; } // namespace bpf