Merge "Move cookie tag bpf map dump to NetworkStatsService"
This commit is contained in:
@@ -53,6 +53,7 @@ import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID_TAG
|
||||
import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_XT;
|
||||
import static android.os.Trace.TRACE_TAG_NETWORK;
|
||||
import static android.system.OsConstants.ENOENT;
|
||||
import static android.system.OsConstants.R_OK;
|
||||
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
import static android.text.format.DateUtils.DAY_IN_MILLIS;
|
||||
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
|
||||
@@ -130,6 +131,7 @@ import android.provider.Settings.Global;
|
||||
import android.service.NetworkInterfaceProto;
|
||||
import android.service.NetworkStatsServiceDumpProto;
|
||||
import android.system.ErrnoException;
|
||||
import android.system.Os;
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.SubscriptionPlan;
|
||||
import android.text.TextUtils;
|
||||
@@ -156,6 +158,7 @@ import com.android.net.module.util.IBpfMap;
|
||||
import com.android.net.module.util.LocationPermissionChecker;
|
||||
import com.android.net.module.util.NetworkStatsUtils;
|
||||
import com.android.net.module.util.PermissionUtils;
|
||||
import com.android.net.module.util.Struct;
|
||||
import com.android.net.module.util.Struct.U32;
|
||||
import com.android.net.module.util.Struct.U8;
|
||||
import com.android.net.module.util.bpf.CookieTagMapKey;
|
||||
@@ -2698,6 +2701,21 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
mUidTagRecorder.dumpLocked(pw, fullHistory);
|
||||
pw.decreaseIndent();
|
||||
}
|
||||
|
||||
pw.println();
|
||||
pw.println("BPF map status:");
|
||||
pw.increaseIndent();
|
||||
dumpMapStatus(pw);
|
||||
pw.decreaseIndent();
|
||||
pw.println();
|
||||
|
||||
// Following BPF map content dump contains uid and tag regardless of the flags because
|
||||
// following dumps are moved from TrafficController and bug report already contains this
|
||||
// information.
|
||||
pw.println("BPF map content:");
|
||||
pw.increaseIndent();
|
||||
dumpCookieTagMapLocked(pw);
|
||||
pw.decreaseIndent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2732,6 +2750,48 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private <K extends Struct, V extends Struct> String getMapStatus(
|
||||
final IBpfMap<K, V> map, final String path) {
|
||||
if (map != null) {
|
||||
return "OK";
|
||||
}
|
||||
try {
|
||||
Os.access(path, R_OK);
|
||||
return "NULL(map is pinned to " + path + ")";
|
||||
} catch (ErrnoException e) {
|
||||
return "NULL(map is not pinned to " + path + ": " + Os.strerror(e.errno) + ")";
|
||||
}
|
||||
}
|
||||
|
||||
private void dumpMapStatus(final IndentingPrintWriter pw) {
|
||||
pw.println("mCookieTagMap: " + getMapStatus(mCookieTagMap, COOKIE_TAG_MAP_PATH));
|
||||
}
|
||||
|
||||
@GuardedBy("mStatsLock")
|
||||
private void dumpCookieTagMapLocked(final IndentingPrintWriter pw) {
|
||||
if (mCookieTagMap == null) {
|
||||
return;
|
||||
}
|
||||
pw.println("mCookieTagMap:");
|
||||
pw.increaseIndent();
|
||||
try {
|
||||
mCookieTagMap.forEach((key, value) -> {
|
||||
// value could be null if there is a concurrent entry deletion.
|
||||
// http://b/220084230.
|
||||
if (value != null) {
|
||||
pw.println("cookie=" + key.socketCookie
|
||||
+ " tag=0x" + Long.toHexString(value.tag)
|
||||
+ " uid=" + value.uid);
|
||||
} else {
|
||||
pw.println("Entry is deleted while dumping, iterating from first entry");
|
||||
}
|
||||
});
|
||||
} catch (ErrnoException e) {
|
||||
pw.println("mCookieTagMap dump end with error: " + Os.strerror(e.errno));
|
||||
}
|
||||
pw.decreaseIndent();
|
||||
}
|
||||
|
||||
private NetworkStats readNetworkStatsSummaryDev() {
|
||||
try {
|
||||
return mStatsFactory.readNetworkStatsSummaryDev();
|
||||
|
||||
@@ -612,8 +612,6 @@ void TrafficController::dump(int fd, bool verbose) {
|
||||
ScopedIndent indentPreBpfModule(dw);
|
||||
|
||||
dw.blankline();
|
||||
dw.println("mCookieTagMap status: %s",
|
||||
getMapStatus(mCookieTagMap.getMap(), COOKIE_TAG_MAP_PATH).c_str());
|
||||
dw.println("mUidCounterSetMap status: %s",
|
||||
getMapStatus(mUidCounterSetMap.getMap(), UID_COUNTERSET_MAP_PATH).c_str());
|
||||
dw.println("mAppUidStatsMap status: %s",
|
||||
@@ -653,18 +651,6 @@ void TrafficController::dump(int fd, bool verbose) {
|
||||
|
||||
ScopedIndent indentForMapContent(dw);
|
||||
|
||||
// Print CookieTagMap content.
|
||||
dumpBpfMap("mCookieTagMap", dw, "");
|
||||
const auto printCookieTagInfo = [&dw](const uint64_t& key, const UidTagValue& value,
|
||||
const BpfMap<uint64_t, UidTagValue>&) {
|
||||
dw.println("cookie=%" PRIu64 " tag=0x%x uid=%u", key, value.tag, value.uid);
|
||||
return base::Result<void>();
|
||||
};
|
||||
base::Result<void> res = mCookieTagMap.iterateWithValue(printCookieTagInfo);
|
||||
if (!res.ok()) {
|
||||
dw.println("mCookieTagMap print end with error: %s", res.error().message().c_str());
|
||||
}
|
||||
|
||||
// Print UidCounterSetMap content.
|
||||
dumpBpfMap("mUidCounterSetMap", dw, "");
|
||||
const auto printUidInfo = [&dw](const uint32_t& key, const uint8_t& value,
|
||||
@@ -672,7 +658,7 @@ void TrafficController::dump(int fd, bool verbose) {
|
||||
dw.println("%u %u", key, value);
|
||||
return base::Result<void>();
|
||||
};
|
||||
res = mUidCounterSetMap.iterateWithValue(printUidInfo);
|
||||
base::Result<void> res = mUidCounterSetMap.iterateWithValue(printUidInfo);
|
||||
if (!res.ok()) {
|
||||
dw.println("mUidCounterSetMap print end with error: %s", res.error().message().c_str());
|
||||
}
|
||||
|
||||
@@ -791,8 +791,6 @@ TEST_F(TrafficControllerTest, TestDumpsys) {
|
||||
// ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes rxPackets txBytes txPackets
|
||||
// 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),
|
||||
"mUidCounterSetMap:",
|
||||
fmt::format("{} {}", TEST_UID3, TEST_COUNTERSET),
|
||||
"mAppUidStatsMap::", // TODO@: fix double colon
|
||||
@@ -833,7 +831,6 @@ TEST_F(TrafficControllerTest, dumpsysInvalidMaps) {
|
||||
"Read value of map -1 failed: Bad file descriptor";
|
||||
|
||||
std::vector<std::string> expectedLines = {
|
||||
fmt::format("mCookieTagMap {}", kErrIterate),
|
||||
fmt::format("mUidCounterSetMap {}", kErrIterate),
|
||||
fmt::format("mAppUidStatsMap {}", kErrIterate),
|
||||
fmt::format("mStatsMapA {}", kErrIterate),
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server.net;
|
||||
|
||||
import static android.Manifest.permission.DUMP;
|
||||
import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
|
||||
import static android.Manifest.permission.UPDATE_DEVICE_STATS;
|
||||
import static android.app.usage.NetworkStatsManager.PREFIX_DEV;
|
||||
@@ -156,7 +157,10 @@ import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Clock;
|
||||
@@ -283,6 +287,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
||||
case PERMISSION_MAINLINE_NETWORK_STACK:
|
||||
case READ_NETWORK_USAGE_HISTORY:
|
||||
case UPDATE_DEVICE_STATS:
|
||||
case DUMP:
|
||||
return PERMISSION_GRANTED;
|
||||
default:
|
||||
return PERMISSION_DENIED;
|
||||
@@ -2317,4 +2322,25 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
||||
assertTrue(mAppUidStatsMap.containsKey(new UidStatsMapKey(UID_RED)));
|
||||
assertTrue(mUidCounterSetMap.containsKey(new U32(UID_RED)));
|
||||
}
|
||||
|
||||
private void assertDumpContains(final String dump, final String message) {
|
||||
assertTrue(String.format("dump(%s) does not contain '%s'", dump, message),
|
||||
dump.contains(message));
|
||||
}
|
||||
|
||||
private String getDump() {
|
||||
final StringWriter sw = new StringWriter();
|
||||
mService.dump(new FileDescriptor(), new PrintWriter(sw), new String[]{});
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDumpCookieTagMap() throws ErrnoException {
|
||||
initBpfMapsWithTagData(UID_BLUE);
|
||||
|
||||
final String dump = getDump();
|
||||
assertDumpContains(dump, "mCookieTagMap: OK");
|
||||
assertDumpContains(dump, "cookie=2002 tag=0x1 uid=1002");
|
||||
assertDumpContains(dump, "cookie=3002 tag=0x2 uid=1002");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user