Move stats map A/B dump to NetworkStatsService

Map status dump will do access check if map is null.
This could show different message from the current dump output.

Information in map content dump does not change
$ dumpsys connectivity trafficcontroller
....
      mStatsMapA:
      ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes rxPackets txBytes txPackets
      20 wlan0 0x0 1051 0 144 2 312 4
      10 rmnet_data0 0x0 0 0 0 0 48 1
      20 wlan0 0x0 0 0 0 0 136 2
      20 wlan0 0xffffff82 1051 0 144 2 312 4

      mStatsMapB:
      ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes rxPackets txBytes txPackets
....

$ dumpsys netstats
....
  mStatsMapA:
    ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes rxPackets txBytes txPackets
    20 wlan0 0x0 1051 0 144 2 312 4
    10 rmnet_data0 0x0 0 0 0 0 48 1
    20 wlan0 0x0 0 0 0 0 136 2
    20 wlan0 0xffffff82 1051 0 144 2 312 4
  mStatsMapB:
    ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes rxPackets txBytes txPackets
....

Bug: 217624062
Test: dumpsys netstats, dumpstate, atest NetworkStatsServiceTest

Change-Id: Ifbd45f0ad6dd9c519a15a7680cf0ea99fb5f5dcf
This commit is contained in:
Motomu Utsumi
2022-08-16 04:16:25 +00:00
parent 95e095dd0d
commit 608c32c782
4 changed files with 53 additions and 37 deletions

View File

@@ -2755,6 +2755,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
dumpCookieTagMapLocked(pw);
dumpUidCounterSetMapLocked(pw);
dumpAppUidStatsMapLocked(pw);
dumpStatsMapLocked(mStatsMapA, pw, "mStatsMapA");
dumpStatsMapLocked(mStatsMapB, pw, "mStatsMapB");
pw.decreaseIndent();
}
}
@@ -2840,6 +2842,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
pw.println("mUidCounterSetMap: "
+ getMapStatus(mUidCounterSetMap, UID_COUNTERSET_MAP_PATH));
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));
}
@GuardedBy("mStatsLock")
@@ -2876,6 +2880,30 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
+ value.txPackets);
}
@GuardedBy("mStatsLock")
private void dumpStatsMapLocked(final IBpfMap<StatsMapKey, StatsMapValue> statsMap,
final IndentingPrintWriter pw, final String mapName) {
if (statsMap == null) {
return;
}
BpfDump.dumpMap(statsMap, pw, mapName,
"ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes rxPackets txBytes txPackets",
(key, value) -> {
final long ifIndex = key.ifaceIndex;
final String ifName = mInterfaceMapUpdater.getIfNameByIndex(ifIndex);
return ifIndex + " "
+ (ifName != null ? ifName : "unknown") + " "
+ "0x" + Long.toHexString(key.tag) + " "
+ key.uid + " "
+ key.counterSet + " "
+ value.rxBytes + " "
+ value.rxPackets + " "
+ value.txBytes + " "
+ value.txPackets;
});
}
private NetworkStats readNetworkStatsSummaryDev() {
try {
return mStatsFactory.readNetworkStatsSummaryDev();

View File

@@ -647,35 +647,6 @@ void TrafficController::dump(int fd, bool verbose) {
dw.println("mCookieTagMap print end with error: %s", res.error().message().c_str());
}
// Print uidStatsMap content.
std::string statsHeader = StringPrintf("ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes"
" rxPackets txBytes txPackets");
dumpBpfMap("mStatsMapA", dw, statsHeader);
const auto printStatsInfo = [&dw, this](const StatsKey& key, const StatsValue& value,
const BpfMap<StatsKey, StatsValue>&) {
uint32_t ifIndex = key.ifaceIndex;
auto ifname = mIfaceIndexNameMap.readValue(ifIndex);
if (!ifname.ok()) {
ifname = IfaceValue{"unknown"};
}
dw.println("%u %s 0x%x %u %u %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64, ifIndex,
ifname.value().name, key.tag, key.uid, key.counterSet, value.rxBytes,
value.rxPackets, value.txBytes, value.txPackets);
return base::Result<void>();
};
res = mStatsMapA.iterateWithValue(printStatsInfo);
if (!res.ok()) {
dw.println("mStatsMapA print end with error: %s", res.error().message().c_str());
}
// Print TagStatsMap content.
dumpBpfMap("mStatsMapB", dw, statsHeader);
res = mStatsMapB.iterateWithValue(printStatsInfo);
if (!res.ok()) {
dw.println("mStatsMapB print end with error: %s", res.error().message().c_str());
}
// Print ifaceIndexToNameMap content.
dumpBpfMap("mIfaceIndexNameMap", dw, "");
const auto printIfaceNameInfo = [&dw](const uint32_t& key, const IfaceValue& value,

View File

@@ -792,12 +792,7 @@ TEST_F(TrafficControllerTest, TestDumpsys) {
// 999 test0 0x2a 10086 1 100 1 0 0
std::vector<std::string> expectedLines = {
"mCookieTagMap:",
fmt::format("cookie={} tag={:#x} uid={}", TEST_COOKIE, TEST_TAG, TEST_UID),
"mStatsMapA",
"ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes rxPackets txBytes txPackets",
fmt::format("{} {} {:#x} {} {} {} {} {} {}",
TEST_IFINDEX, TEST_IFNAME, TEST_TAG, TEST_UID, TEST_COUNTERSET, RXBYTES,
RXPACKETS, TXBYTES, TXPACKETS)};
fmt::format("cookie={} tag={:#x} uid={}", TEST_COOKIE, TEST_TAG, TEST_UID)};
populateFakeIfaceIndexName(TEST_IFNAME, TEST_IFINDEX);
expectedLines.emplace_back("mIfaceIndexNameMap:");
@@ -829,8 +824,6 @@ TEST_F(TrafficControllerTest, dumpsysInvalidMaps) {
std::vector<std::string> expectedLines = {
fmt::format("mCookieTagMap {}", kErrIterate),
fmt::format("mStatsMapA {}", kErrIterate),
fmt::format("mStatsMapB {}", kErrIterate),
fmt::format("mIfaceIndexNameMap {}", kErrIterate),
fmt::format("mIfaceStatsMap {}", kErrIterate),
fmt::format("mConfigurationMap {}", kErrReadRulesConfig),

View File

@@ -2528,4 +2528,28 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
assertDumpContains(dump, "uid rxBytes rxPackets txBytes txPackets");
assertDumpContains(dump, "1002 10000 10 6000 6");
}
private void doTestDumpStatsMap(final String expectedIfaceName) throws ErrnoException {
initBpfMapsWithTagData(UID_BLUE);
final String dump = getDump();
assertDumpContains(dump, "mStatsMapA: OK");
assertDumpContains(dump, "mStatsMapB: OK");
assertDumpContains(dump,
"ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes rxPackets txBytes txPackets");
assertDumpContains(dump, "10 " + expectedIfaceName + " 0x2 1002 0 5000 5 3000 3");
assertDumpContains(dump, "10 " + expectedIfaceName + " 0x1 1002 0 5000 5 3000 3");
}
@Test
public void testDumpStatsMap() throws ErrnoException {
doReturn("wlan0").when(mBpfInterfaceMapUpdater).getIfNameByIndex(10 /* index */);
doTestDumpStatsMap("wlan0");
}
@Test
public void testDumpStatsMapUnknownInterface() throws ErrnoException {
doReturn(null).when(mBpfInterfaceMapUpdater).getIfNameByIndex(10 /* index */);
doTestDumpStatsMap("unknown");
}
}