blob: be934bc89d74cfeb74b930d5c27c40a48c2707be [file] [log] [blame]
Hector Dearman355d7ba2017-10-24 15:44:43 +01001#!/usr/bin/env python
2# Copyright (C) 2017 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16from __future__ import print_function
17import argparse
18import datetime
19import os
20import subprocess
21import sys
Hector Dearman355d7ba2017-10-24 15:44:43 +010022"""Pulls all format files from an Android device.
23
24Usage: ./tools/pull_ftrace_format_files.py [-s serial] [-p directory_prefix]
25"""
26
27ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
28ADB_PATH = os.path.join(ROOT_DIR, 'buildtools/android_sdk/platform-tools/adb')
29
Primiano Tucci834fdc72019-10-04 11:33:44 +010030
Hector Dearman355d7ba2017-10-24 15:44:43 +010031def adb(*cmd, **kwargs):
32 serial = kwargs.get('serial', None)
33 prefix = [ADB_PATH]
34 if serial:
35 prefix += ['-s', serial]
36 cmd = prefix + list(cmd)
Hector Dearman7d5b2532017-10-26 16:55:51 +010037 output = subprocess.check_output(cmd).replace('\r', '')
Hector Dearman355d7ba2017-10-24 15:44:43 +010038 return output
39
40
41def get_devices():
42 # adb devices output looks like:
43 # List of devices attached
44 # 557dccd8\tdevice
45 # With a trailing newline.
46 serials = [s.split('\t')[0] for s in adb('devices').split('\n')[1:] if s]
47 return serials
48
49
50def ensure_output_directory_empty(path):
51 if os.path.isfile(path):
52 print('The output directory {} exists as a file.'.format(path))
53 sys.exit(1)
54
55 if os.path.isdir(path) and os.listdir(path):
56 print('The output directory {} exists but is not empty.'.format(path))
57 sys.exit(1)
58
59 if not os.path.isdir(path):
60 os.makedirs(path)
61
62
63def ensure_dir(path):
64 try:
65 os.makedirs(path)
66 except OSError:
67 if not os.path.isdir(path):
68 raise
69
70
71def ensure_single_device(serial):
72 serials = get_devices()
73 if serial is None and len(serials) == 1:
74 return serials[0]
75
76 if serial in serials:
77 return serial
78
79 if not serials:
80 print('No devices connected.')
81 elif serial is None:
82 print('More than one device connected, use -s.')
83 else:
84 print('No device with serial {} found.'.format(serial))
85 sys.exit(1)
86
87
88def pull_format_files(serial, output_directory):
89 # Pulling each file individually is 100x slower so we pipe all together then
90 # split them on the host.
Hector Dearmane02ebe12017-11-22 16:19:23 +000091 cmd = "find /sys/kernel/debug/tracing/ " \
92 "-name available_events -o " \
Hector Dearman355d7ba2017-10-24 15:44:43 +010093 "-name format -o " \
94 "-name header_event -o " \
95 "-name header_page | " \
Hector Dearman7f37dc82018-01-25 12:25:40 +000096 "grep -v '/instances/' | " \
Hector Dearman355d7ba2017-10-24 15:44:43 +010097 "while read f; do echo 'path:' $f; cat $f; done"
98
99 output = adb('shell', cmd, serial=serial)
Hector Dearmane02ebe12017-11-22 16:19:23 +0000100 sections = output.split('path: /sys/kernel/debug/tracing/')
Hector Dearman355d7ba2017-10-24 15:44:43 +0100101 for section in sections:
102 if not section:
103 continue
104 path, rest = section.split('\n', 1)
105 path = os.path.join(output_directory, path)
106 ensure_dir(os.path.dirname(path))
107 with open(path, 'wb') as f:
108 f.write(rest)
109
110
111# Produces output of the form: prefix_android_seed_N2F62_3.10.49
Hector Dearman7d5b2532017-10-26 16:55:51 +0100112def get_output_directory(prefix=None, serial=None):
113 build_id = adb('shell', 'getprop', 'ro.build.id', serial=serial).strip()
114 product = adb('shell', 'getprop', 'ro.build.product', serial=serial).strip()
115 kernel = adb('shell', 'uname', '-r', serial=serial).split('-')[0].strip()
Hector Dearman355d7ba2017-10-24 15:44:43 +0100116 parts = ['android', product, build_id, kernel]
117 if prefix:
118 parts = [prefix] + parts
119 return '_'.join(parts)
120
121
122def main():
123 parser = argparse.ArgumentParser(description='Pull format files.')
Primiano Tucci834fdc72019-10-04 11:33:44 +0100124 parser.add_argument(
125 '-p', dest='prefix', default=None, help='the output directory prefix')
126 parser.add_argument(
127 '-s',
128 dest='serial',
129 default=None,
130 help='use device with the given serial')
Hector Dearman355d7ba2017-10-24 15:44:43 +0100131 args = parser.parse_args()
132
133 prefix = args.prefix
134 serial = args.serial
135
136 serial = ensure_single_device(serial)
Hector Dearman7d5b2532017-10-26 16:55:51 +0100137 output_directory = get_output_directory(prefix, serial)
Hector Dearman355d7ba2017-10-24 15:44:43 +0100138
139 ensure_output_directory_empty(output_directory)
140 pull_format_files(serial, output_directory)
141
142 return 0
143
144
145if __name__ == '__main__':
Primiano Tucci834fdc72019-10-04 11:33:44 +0100146 sys.exit(main())