From 809a3160350700f03e2a7032c39f188e14494a92 Mon Sep 17 00:00:00 2001 From: Motomu Utsumi Date: Tue, 16 Aug 2022 08:50:46 +0000 Subject: [PATCH] Move Interface stats map dump to NetworkStatsService Bug: 217624062 Test: dumpsys netstats, atest NetworkStatsServiceTest Change-Id: Ie0357a79925c0bbb34aa05442f727c776f434f88 --- .../server/net/NetworkStatsService.java | 32 +++++++++++++++++++ service/native/TrafficController.cpp | 19 ----------- service/native/TrafficControllerTest.cpp | 3 +- .../server/net/NetworkStatsServiceTest.java | 29 ++++++++++++++++- 4 files changed, 61 insertions(+), 22 deletions(-) diff --git a/service-t/src/com/android/server/net/NetworkStatsService.java b/service-t/src/com/android/server/net/NetworkStatsService.java index 0da7b6f087..0e4295950b 100644 --- a/service-t/src/com/android/server/net/NetworkStatsService.java +++ b/service-t/src/com/android/server/net/NetworkStatsService.java @@ -254,6 +254,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { "/sys/fs/bpf/netd_shared/map_netd_stats_map_A"; private static final String STATS_MAP_B_PATH = "/sys/fs/bpf/netd_shared/map_netd_stats_map_B"; + private static final String IFACE_STATS_MAP_PATH = + "/sys/fs/bpf/netd_shared/map_netd_iface_stats_map"; /** * DeviceConfig flag used to indicate whether the files should be stored in the apex data @@ -413,6 +415,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private final IBpfMap mStatsMapA; private final IBpfMap mStatsMapB; private final IBpfMap mAppUidStatsMap; + private final IBpfMap mIfaceStatsMap; /** Data layer operation counters for splicing into other structures. */ private NetworkStats mUidOperations = new NetworkStats(0L, 10); @@ -592,6 +595,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mStatsMapA = mDeps.getStatsMapA(); mStatsMapB = mDeps.getStatsMapB(); mAppUidStatsMap = mDeps.getAppUidStatsMap(); + mIfaceStatsMap = mDeps.getIfaceStatsMap(); // TODO: Remove bpfNetMaps creation and always start SkDestroyListener // Following code is for the experiment to verify the SkDestroyListener refactoring. Based @@ -795,6 +799,16 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } } + /** Gets interface stats map */ + public IBpfMap getIfaceStatsMap() { + try { + return new BpfMap(IFACE_STATS_MAP_PATH, + BpfMap.BPF_F_RDWR, S32.class, StatsMapValue.class); + } catch (ErrnoException e) { + throw new IllegalStateException("Failed to open interface stats map", e); + } + } + /** Gets whether the build is userdebug. */ public boolean isDebuggable() { return Build.isDebuggable(); @@ -2763,6 +2777,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { dumpAppUidStatsMapLocked(pw); dumpStatsMapLocked(mStatsMapA, pw, "mStatsMapA"); dumpStatsMapLocked(mStatsMapB, pw, "mStatsMapB"); + dumpIfaceStatsMapLocked(pw); pw.decreaseIndent(); } } @@ -2850,6 +2865,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { pw.println("mAppUidStatsMap: " + getMapStatus(mAppUidStatsMap, APP_UID_STATS_MAP_PATH)); pw.println("mStatsMapA: " + getMapStatus(mStatsMapA, STATS_MAP_A_PATH)); pw.println("mStatsMapB: " + getMapStatus(mStatsMapB, STATS_MAP_B_PATH)); + // mIfaceStatsMap is always not null but dump status to be consistent with other maps. + pw.println("mIfaceStatsMap: " + getMapStatus(mIfaceStatsMap, IFACE_STATS_MAP_PATH)); } @GuardedBy("mStatsLock") @@ -2909,6 +2926,21 @@ public class NetworkStatsService extends INetworkStatsService.Stub { }); } + @GuardedBy("mStatsLock") + private void dumpIfaceStatsMapLocked(final IndentingPrintWriter pw) { + BpfDump.dumpMap(mIfaceStatsMap, pw, "mIfaceStatsMap", + "ifaceIndex ifaceName rxBytes rxPackets txBytes txPackets", + (key, value) -> { + final String ifName = mInterfaceMapUpdater.getIfNameByIndex(key.val); + return key.val + " " + + (ifName != null ? ifName : "unknown") + " " + + value.rxBytes + " " + + value.rxPackets + " " + + value.txBytes + " " + + value.txPackets; + }); + } + private NetworkStats readNetworkStatsSummaryDev() { try { return mStatsFactory.readNetworkStatsSummaryDev(); diff --git a/service/native/TrafficController.cpp b/service/native/TrafficController.cpp index 245b9d8d9c..fc76ae5eed 100644 --- a/service/native/TrafficController.cpp +++ b/service/native/TrafficController.cpp @@ -647,25 +647,6 @@ void TrafficController::dump(int fd, bool verbose) { dw.println("mCookieTagMap print end with error: %s", res.error().message().c_str()); } - // Print ifaceStatsMap content - std::string ifaceStatsHeader = StringPrintf("ifaceIndex ifaceName rxBytes rxPackets txBytes" - " txPackets"); - dumpBpfMap("mIfaceStatsMap:", dw, ifaceStatsHeader); - const auto printIfaceStatsInfo = [&dw, this](const uint32_t& key, const StatsValue& value, - const BpfMap&) { - auto ifname = mIfaceIndexNameMap.readValue(key); - if (!ifname.ok()) { - ifname = IfaceValue{"unknown"}; - } - dw.println("%u %s %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64, key, ifname.value().name, - value.rxBytes, value.rxPackets, value.txBytes, value.txPackets); - return base::Result(); - }; - res = mIfaceStatsMap.iterateWithValue(printIfaceStatsInfo); - if (!res.ok()) { - dw.println("mIfaceStatsMap print end with error: %s", res.error().message().c_str()); - } - dw.blankline(); } diff --git a/service/native/TrafficControllerTest.cpp b/service/native/TrafficControllerTest.cpp index 2f5960fd3e..6cb094034a 100644 --- a/service/native/TrafficControllerTest.cpp +++ b/service/native/TrafficControllerTest.cpp @@ -805,8 +805,7 @@ TEST_F(TrafficControllerTest, dumpsysInvalidMaps) { "Read value of map -1 failed: Bad file descriptor"; std::vector expectedLines = { - fmt::format("mCookieTagMap {}", kErrIterate), - fmt::format("mIfaceStatsMap {}", kErrIterate)}; + fmt::format("mCookieTagMap {}", kErrIterate)}; EXPECT_TRUE(expectDumpsysContains(expectedLines)); } diff --git a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java index 644881948f..2ceb00a8b2 100644 --- a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java +++ b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java @@ -263,7 +263,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { StatsMapValue.class); private TestBpfMap mAppUidStatsMap = new TestBpfMap<>( UidStatsMapKey.class, StatsMapValue.class); - + private TestBpfMap mIfaceStatsMap = new TestBpfMap<>( + S32.class, StatsMapValue.class); private NetworkStatsService mService; private INetworkStatsSession mSession; private AlertObserver mAlertObserver; @@ -502,6 +503,11 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { return mAppUidStatsMap; } + @Override + public IBpfMap getIfaceStatsMap() { + return mIfaceStatsMap; + } + @Override public boolean isDebuggable() { return mIsDebuggable == Boolean.TRUE; @@ -2552,4 +2558,25 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { doReturn(null).when(mBpfInterfaceMapUpdater).getIfNameByIndex(10 /* index */); doTestDumpStatsMap("unknown"); } + + void doTestDumpIfaceStatsMap(final String expectedIfaceName) throws Exception { + mIfaceStatsMap.insertEntry(new S32(10), new StatsMapValue(3, 3000, 3, 3000)); + + final String dump = getDump(); + assertDumpContains(dump, "mIfaceStatsMap: OK"); + assertDumpContains(dump, "ifaceIndex ifaceName rxBytes rxPackets txBytes txPackets"); + assertDumpContains(dump, "10 " + expectedIfaceName + " 3000 3 3000 3"); + } + + @Test + public void testDumpIfaceStatsMap() throws Exception { + doReturn("wlan0").when(mBpfInterfaceMapUpdater).getIfNameByIndex(10 /* index */); + doTestDumpIfaceStatsMap("wlan0"); + } + + @Test + public void testDumpIfaceStatsMapUnknownInterface() throws Exception { + doReturn(null).when(mBpfInterfaceMapUpdater).getIfNameByIndex(10 /* index */); + doTestDumpIfaceStatsMap("unknown"); + } }