summaryrefslogtreecommitdiff
path: root/ioblame/androidFsParser.py
diff options
context:
space:
mode:
Diffstat (limited to 'ioblame/androidFsParser.py')
-rw-r--r--ioblame/androidFsParser.py175
1 files changed, 0 insertions, 175 deletions
diff --git a/ioblame/androidFsParser.py b/ioblame/androidFsParser.py
deleted file mode 100644
index 6ea38dc3..00000000
--- a/ioblame/androidFsParser.py
+++ /dev/null
@@ -1,175 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (C) 2022 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-"""Trace parser for android_fs traces."""
-
-import collections
-import re
-
-# ex) bt_stack_manage-21277 [000] .... 5879.043608: android_fs_datawrite_start: entry_name /misc/bluedroid/bt_config.bak.new, offset 0, bytes 408, cmdline bt_stack_manage, pid 21277, i_size 0, ino 9103
-RE_WRITE_START = r".+-([0-9]+).*\s+([0-9]+\.[0-9]+):\s+android_fs_datawrite_start:\sentry_name\s(\S+)\,\soffset\s([0-9]+)\,\sbytes\s([0-9]+)\,\scmdline\s(\S+)\,\spid\s([0-9]+)\,\si_size\s([0-9]+)\,\sino\s([0-9]+)"
-
-# ex) dumpsys-21321 [001] .... 5877.599324: android_fs_dataread_start: entry_name /system/lib64/libbinder.so, offset 311296, bytes 4096, cmdline dumpsys, pid 21321, i_size 848848, ino 2397
-RE_READ_START = r".+-([0-9]+).*\s+([0-9]+\.[0-9]+):\s+android_fs_dataread_start:\sentry_name\s(\S+)\,\soffset\s([0-9]+)\,\sbytes\s([0-9]+)\,\scmdline\s(\S+)\,\spid\s([0-9]+)\,\si_size\s([0-9]+)\,\sino\s([0-9]+)"
-
-MIN_PID_BYTES = 1024 * 1024 # 1 MiB
-SMALL_FILE_BYTES = 1024 # 1 KiB
-
-
-class ProcessTrace:
-
- def __init__(self, cmdLine, filename, numBytes):
- self.cmdLine = cmdLine
- self.totalBytes = numBytes
- self.bytesByFiles = {filename: numBytes}
-
- def add_file_trace(self, filename, numBytes):
- self.totalBytes += numBytes
- if filename in self.bytesByFiles:
- self.bytesByFiles[filename] += numBytes
- else:
- self.bytesByFiles[filename] = numBytes
-
- def dump(self, mode, outputFile):
- smallFileCnt = 0
- smallFileBytes = 0
- for _, numBytes in self.bytesByFiles.items():
- if numBytes < SMALL_FILE_BYTES:
- smallFileCnt += 1
- smallFileBytes += numBytes
-
- if (smallFileCnt != 0):
- outputFile.write(
- "Process: {}, Traced {} KB: {}, Small file count: {}, Small file KB: {}\n"
- .format(self.cmdLine, mode, to_kib(self.totalBytes), smallFileCnt,
- to_kib(smallFileBytes)))
-
- else:
- outputFile.write("Process: {}, Traced {} KB: {}\n".format(
- self.cmdLine, mode, to_kib(self.totalBytes)))
-
- if (smallFileCnt == len(self.bytesByFiles)):
- return
-
- sortedEntries = collections.OrderedDict(
- sorted(
- self.bytesByFiles.items(), key=lambda item: item[1], reverse=True))
-
- for i in range(len(sortedEntries)):
- filename, numBytes = sortedEntries.popitem(last=False)
- if numBytes < SMALL_FILE_BYTES:
- # Entries are sorted by bytes. So, break on the first small file entry.
- break
-
- outputFile.write("File: {}, {} KB: {}\n".format(filename, mode,
- to_kib(numBytes)))
-
-
-class UidTrace:
-
- def __init__(self, uid, cmdLine, filename, numBytes):
- self.uid = uid
- self.packageName = ""
- self.totalBytes = numBytes
- self.traceByProcess = {cmdLine: ProcessTrace(cmdLine, filename, numBytes)}
-
- def add_process_trace(self, cmdLine, filename, numBytes):
- self.totalBytes += numBytes
- if cmdLine in self.traceByProcess:
- self.traceByProcess[cmdLine].add_file_trace(filename, numBytes)
- else:
- self.traceByProcess[cmdLine] = ProcessTrace(cmdLine, filename, numBytes)
-
- def dump(self, mode, outputFile):
- outputFile.write("Traced {} KB: {}\n\n".format(mode,
- to_kib(self.totalBytes)))
-
- if self.totalBytes < MIN_PID_BYTES:
- return
-
- sortedEntries = collections.OrderedDict(
- sorted(
- self.traceByProcess.items(),
- key=lambda item: item[1].totalBytes,
- reverse=True))
- totalEntries = len(sortedEntries)
- for i in range(totalEntries):
- _, processTrace = sortedEntries.popitem(last=False)
- if processTrace.totalBytes < MIN_PID_BYTES:
- # Entries are sorted by bytes. So, break on the first small PID entry.
- break
-
- processTrace.dump(mode, outputFile)
- if i < totalEntries - 1:
- outputFile.write("\n")
-
-
-class AndroidFsParser:
-
- def __init__(self, re_string, uidProcessMapper):
- self.traceByUid = {} # Key: uid, Value: UidTrace
- if (re_string == RE_WRITE_START):
- self.mode = "write"
- else:
- self.mode = "read"
- self.re_matcher = re.compile(re_string)
- self.uidProcessMapper = uidProcessMapper
- self.totalBytes = 0
-
- def parse(self, line):
- match = self.re_matcher.match(line)
- if not match:
- return False
- try:
- self.do_parse_start(line, match)
- except Exception:
- print("cannot parse: {}".format(line))
- raise
- return True
-
- def do_parse_start(self, line, match):
- pid = int(match.group(1))
- # start_time = float(match.group(2)) * 1000 #ms
- filename = match.group(3)
- # offset = int(match.group(4))
- numBytes = int(match.group(5))
- cmdLine = match.group(6)
- pid = int(match.group(7))
- # isize = int(match.group(8))
- # ino = int(match.group(9))
- self.totalBytes += numBytes
- uid = self.uidProcessMapper.get_uid(cmdLine, pid)
-
- if uid in self.traceByUid:
- self.traceByUid[uid].add_process_trace(cmdLine, filename, numBytes)
- else:
- self.traceByUid[uid] = UidTrace(uid, cmdLine, filename, numBytes)
-
- def dumpTotal(self, outputFile):
- if self.totalBytes > 0:
- outputFile.write("Traced system-wide {} KB: {}\n\n".format(
- self.mode, to_kib(self.totalBytes)))
-
- def dump(self, uid, outputFile):
- if uid not in self.traceByUid:
- return
-
- uidTrace = self.traceByUid[uid]
- uidTrace.dump(self.mode, outputFile)
-
-
-def to_kib(bytes):
- return bytes / 1024