Loading init/Android.mk +0 −6 Original line number Diff line number Diff line Loading @@ -4,12 +4,6 @@ LOCAL_PATH:= $(call my-dir) # -- ifeq ($(strip $(INIT_BOOTCHART)),true) init_options += -DBOOTCHART=1 else init_options += -DBOOTCHART=0 endif ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT))) init_options += -DALLOW_LOCAL_PROP_OVERRIDE=1 -DALLOW_DISABLE_SELINUX=1 else Loading init/README.BOOTCHART +8 −14 Original line number Diff line number Diff line This version of init contains code to perform "bootcharting", i.e. generating log files that can be later processed by the tools provided by www.bootchart.org. To activate it, you need to define build 'init' with the INIT_BOOTCHART environment variable defined to 'true', for example: touch system/init/init.c m INIT_BOOTCHART=true On the emulator, use the new -bootchart <timeout> option to boot with bootcharting activated for <timeout> seconds. Otherwise, flash your device, and start it. Then create a file on the /data partition with a command like the following: adb shell 'echo $TIMEOUT > /data/bootchart-start' adb shell 'echo $TIMEOUT > /data/bootchart/start' Where the value of $TIMEOUT corresponds to the wanted bootcharted period in seconds; for example, to bootchart for 2 minutes, do: adb shell 'echo 120 > /data/bootchart-start' adb shell 'echo 120 > /data/bootchart/start' Reboot your device, bootcharting will begin and stop after the period you gave. You can also stop the bootcharting at any moment by doing the following: adb shell 'echo 1 > /data/bootchart-stop' adb shell 'echo 1 > /data/bootchart/stop' Note that /data/bootchart-stop is deleted automatically by init at the end of the bootcharting. This is not the case of /data/bootchart-start, so don't forget to delete it Note that /data/bootchart/stop is deleted automatically by init at the end of the bootcharting. This is not the case of /data/bootchart/start, so don't forget to delete it when you're done collecting data: adb shell rm /data/bootchart-start adb shell rm /data/bootchart/start The log files are placed in /data/bootchart/. you must run the script tools/grab-bootchart.sh The log files are placed in /data/bootchart/. You must run the script tools/grab-bootchart.sh which will use ADB to retrieve them and create a bootchart.tgz file that can be used with the bootchart parser/renderer, or even uploaded directly to the form located at: Loading @@ -47,6 +41,6 @@ NOTE: the bootchart.org webform doesn't seem to work at the moment, you can gene technical note: this implementation of bootcharting does use the 'bootchartd' script provided by This implementation of bootcharting does not use the 'bootchartd' script provided by www.bootchart.org, but a C re-implementation that is directly compiled into our init program. init/bootchart.cpp +75 −23 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ */ #include "bootchart.h" #include "keywords.h" #include "log.h" #include <dirent.h> #include <errno.h> Loading @@ -32,6 +34,10 @@ #include <time.h> #include <unistd.h> #define BOOTCHART_POLLING_MS 200 /* polling period in ms */ #define BOOTCHART_DEFAULT_TIME_SEC (2*60) /* default polling time in seconds */ #define BOOTCHART_MAX_TIME_SEC (10*60) /* max polling time in seconds */ #define VERSION "0.8" #define SAMPLE_PERIOD 0.2 #define LOG_ROOT "/data/bootchart" Loading @@ -41,8 +47,23 @@ #define LOG_HEADER LOG_ROOT"/header" #define LOG_ACCT LOG_ROOT"/kernel_pacct" #define LOG_STARTFILE "/data/bootchart-start" #define LOG_STOPFILE "/data/bootchart-stop" #define LOG_STARTFILE LOG_ROOT"/start" #define LOG_STOPFILE LOG_ROOT"/stop" #define FILE_BUFF_SIZE 65536 struct FileBuff { int count; int fd; char data[FILE_BUFF_SIZE]; }; static long long last_bootchart_time; static int g_remaining_samples; static FileBuff log_stat[1]; static FileBuff log_procs[1]; static FileBuff log_disks[1]; static int proc_read(const char* filename, char* buff, size_t buffsize) Loading @@ -57,19 +78,11 @@ proc_read(const char* filename, char* buff, size_t buffsize) return len; } #define FILE_BUFF_SIZE 65536 struct FileBuff { int count; int fd; char data[FILE_BUFF_SIZE]; }; static void file_buff_open( FileBuff* buff, const char* path ) { buff->count = 0; buff->fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0755); buff->fd = open(path, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0755); } static void Loading Loading @@ -248,9 +261,19 @@ do_log_procs(FileBuff* log) do_log_ln(log); } static FileBuff log_stat[1]; static FileBuff log_procs[1]; static FileBuff log_disks[1]; int do_bootchart_init(int nargs, char **args) { g_remaining_samples = bootchart_init(); if (g_remaining_samples < 0) { ERROR("bootcharting init failure\n"); } else if (g_remaining_samples > 0) { NOTICE("bootcharting started (will run for %d ms)\n", g_remaining_samples*BOOTCHART_POLLING_MS); } else { NOTICE("bootcharting ignored\n"); } return 0; } /* called to setup bootcharting */ int bootchart_init( void ) Loading Loading @@ -307,14 +330,13 @@ int bootchart_init( void ) return count; } /* called each time you want to perform a bootchart sampling op */ int bootchart_step( void ) static int bootchart_step( void ) { do_log_file(log_stat, "/proc/stat"); do_log_file(log_disks, "/proc/diskstats"); do_log_procs(log_procs); /* we stop when /data/bootchart-stop contains 1 */ /* we stop when /data/bootchart/stop contains 1 */ { char buff[2]; if (proc_read(LOG_STOPFILE,buff,sizeof(buff)) > 0 && buff[0] == '1') { Loading @@ -325,6 +347,42 @@ int bootchart_step( void ) return 0; } /* called to get time (in ms) used by bootchart */ static long long bootchart_gettime() { return 10LL*get_uptime_jiffies(); } /* called each time you want to perform a bootchart sampling op */ void bootchart_sample(int* timeout) { if (g_remaining_samples > 0) { long long current_time; int elapsed_time, remaining_time; current_time = bootchart_gettime(); elapsed_time = current_time - last_bootchart_time; if (elapsed_time >= BOOTCHART_POLLING_MS) { /* count missed samples */ while (elapsed_time >= BOOTCHART_POLLING_MS) { elapsed_time -= BOOTCHART_POLLING_MS; g_remaining_samples--; } /* count may be negative, take a sample anyway */ last_bootchart_time = current_time; if (bootchart_step() < 0 || g_remaining_samples <= 0) { bootchart_finish(); g_remaining_samples = 0; } } if (g_remaining_samples > 0) { remaining_time = BOOTCHART_POLLING_MS - elapsed_time; if (*timeout < 0 || *timeout > remaining_time) { *timeout = remaining_time; } } } } void bootchart_finish( void ) { unlink( LOG_STOPFILE ); Loading @@ -333,9 +391,3 @@ void bootchart_finish( void ) file_buff_done(log_procs); acct(NULL); } /* called to get time (in ms) used by bootchart */ long long bootchart_gettime( void ) { return 10LL*get_uptime_jiffies(); } init/bootchart.h +3 −8 Original line number Diff line number Diff line Loading @@ -17,13 +17,8 @@ #ifndef _BOOTCHART_H #define _BOOTCHART_H extern int bootchart_init(void); extern int bootchart_step(void); extern void bootchart_finish(void); extern long long bootchart_gettime(void); #define BOOTCHART_POLLING_MS 200 /* polling period in ms */ #define BOOTCHART_DEFAULT_TIME_SEC (2*60) /* default polling time in seconds */ #define BOOTCHART_MAX_TIME_SEC (10*60) /* max polling time in seconds */ int bootchart_init(); void bootchart_sample(int* timeout); void bootchart_finish(); #endif /* _BOOTCHART_H */ init/init.cpp +12 −60 Original line number Diff line number Diff line Loading @@ -63,9 +63,6 @@ struct selabel_handle *sehandle_prop; static int property_triggers_enabled = 0; static int bootchart_count; static long long bootchart_time = 0; static char console[32]; static char bootmode[32]; static char hardware[32]; Loading Loading @@ -857,20 +854,6 @@ static int queue_property_triggers_action(int nargs, char **args) return 0; } static int bootchart_init_action(int nargs, char **args) { bootchart_count = bootchart_init(); if (bootchart_count < 0) { ERROR("bootcharting init failure\n"); } else if (bootchart_count > 0) { NOTICE("bootcharting started (period=%d ms)\n", bootchart_count*BOOTCHART_POLLING_MS); } else { NOTICE("bootcharting ignored\n"); } return 0; } void selinux_init_all_handles(void) { sehandle = selinux_android_file_context_handle(); Loading Loading @@ -988,7 +971,7 @@ static void selinux_initialize(void) int main(int argc, char **argv) { int fd_count = 0; size_t fd_count = 0; struct pollfd ufds[4]; int property_set_fd_init = 0; int signal_fd_init = 0; Loading Loading @@ -1087,13 +1070,7 @@ int main(int argc, char **argv) /* run all property triggers based on current state of the properties */ queue_builtin_action(queue_property_triggers_action, "queue_property_triggers"); if (BOOTCHART) { queue_builtin_action(bootchart_init_action, "bootchart_init"); } for (;;) { int nr, i, timeout = -1; execute_one_command(); restart_processes(); Loading @@ -1119,6 +1096,7 @@ int main(int argc, char **argv) keychord_fd_init = 1; } int timeout = -1; if (process_needs_restart) { timeout = (process_needs_restart - gettime()) * 1000; if (timeout < 0) Loading @@ -1129,51 +1107,25 @@ int main(int argc, char **argv) timeout = 0; } if (BOOTCHART) { if (bootchart_count > 0) { long long current_time; int elapsed_time, remaining_time; bootchart_sample(&timeout); current_time = bootchart_gettime(); elapsed_time = current_time - bootchart_time; if (elapsed_time >= BOOTCHART_POLLING_MS) { /* count missed samples */ while (elapsed_time >= BOOTCHART_POLLING_MS) { elapsed_time -= BOOTCHART_POLLING_MS; bootchart_count--; } /* count may be negative, take a sample anyway */ bootchart_time = current_time; if (bootchart_step() < 0 || bootchart_count <= 0) { bootchart_finish(); bootchart_count = 0; } } if (bootchart_count > 0) { remaining_time = BOOTCHART_POLLING_MS - elapsed_time; if (timeout < 0 || timeout > remaining_time) { timeout = remaining_time; } } } } nr = poll(ufds, fd_count, timeout); if (nr <= 0) int nr = poll(ufds, fd_count, timeout); if (nr <= 0) { continue; } for (i = 0; i < fd_count; i++) { for (size_t i = 0; i < fd_count; i++) { if (ufds[i].revents & POLLIN) { if (ufds[i].fd == get_property_set_fd()) if (ufds[i].fd == get_property_set_fd()) { handle_property_set_fd(); else if (ufds[i].fd == get_keychord_fd()) } else if (ufds[i].fd == get_keychord_fd()) { handle_keychord(); else if (ufds[i].fd == get_signal_fd()) } else if (ufds[i].fd == get_signal_fd()) { handle_signal(); } } } } return 0; } Loading
init/Android.mk +0 −6 Original line number Diff line number Diff line Loading @@ -4,12 +4,6 @@ LOCAL_PATH:= $(call my-dir) # -- ifeq ($(strip $(INIT_BOOTCHART)),true) init_options += -DBOOTCHART=1 else init_options += -DBOOTCHART=0 endif ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT))) init_options += -DALLOW_LOCAL_PROP_OVERRIDE=1 -DALLOW_DISABLE_SELINUX=1 else Loading
init/README.BOOTCHART +8 −14 Original line number Diff line number Diff line This version of init contains code to perform "bootcharting", i.e. generating log files that can be later processed by the tools provided by www.bootchart.org. To activate it, you need to define build 'init' with the INIT_BOOTCHART environment variable defined to 'true', for example: touch system/init/init.c m INIT_BOOTCHART=true On the emulator, use the new -bootchart <timeout> option to boot with bootcharting activated for <timeout> seconds. Otherwise, flash your device, and start it. Then create a file on the /data partition with a command like the following: adb shell 'echo $TIMEOUT > /data/bootchart-start' adb shell 'echo $TIMEOUT > /data/bootchart/start' Where the value of $TIMEOUT corresponds to the wanted bootcharted period in seconds; for example, to bootchart for 2 minutes, do: adb shell 'echo 120 > /data/bootchart-start' adb shell 'echo 120 > /data/bootchart/start' Reboot your device, bootcharting will begin and stop after the period you gave. You can also stop the bootcharting at any moment by doing the following: adb shell 'echo 1 > /data/bootchart-stop' adb shell 'echo 1 > /data/bootchart/stop' Note that /data/bootchart-stop is deleted automatically by init at the end of the bootcharting. This is not the case of /data/bootchart-start, so don't forget to delete it Note that /data/bootchart/stop is deleted automatically by init at the end of the bootcharting. This is not the case of /data/bootchart/start, so don't forget to delete it when you're done collecting data: adb shell rm /data/bootchart-start adb shell rm /data/bootchart/start The log files are placed in /data/bootchart/. you must run the script tools/grab-bootchart.sh The log files are placed in /data/bootchart/. You must run the script tools/grab-bootchart.sh which will use ADB to retrieve them and create a bootchart.tgz file that can be used with the bootchart parser/renderer, or even uploaded directly to the form located at: Loading @@ -47,6 +41,6 @@ NOTE: the bootchart.org webform doesn't seem to work at the moment, you can gene technical note: this implementation of bootcharting does use the 'bootchartd' script provided by This implementation of bootcharting does not use the 'bootchartd' script provided by www.bootchart.org, but a C re-implementation that is directly compiled into our init program.
init/bootchart.cpp +75 −23 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ */ #include "bootchart.h" #include "keywords.h" #include "log.h" #include <dirent.h> #include <errno.h> Loading @@ -32,6 +34,10 @@ #include <time.h> #include <unistd.h> #define BOOTCHART_POLLING_MS 200 /* polling period in ms */ #define BOOTCHART_DEFAULT_TIME_SEC (2*60) /* default polling time in seconds */ #define BOOTCHART_MAX_TIME_SEC (10*60) /* max polling time in seconds */ #define VERSION "0.8" #define SAMPLE_PERIOD 0.2 #define LOG_ROOT "/data/bootchart" Loading @@ -41,8 +47,23 @@ #define LOG_HEADER LOG_ROOT"/header" #define LOG_ACCT LOG_ROOT"/kernel_pacct" #define LOG_STARTFILE "/data/bootchart-start" #define LOG_STOPFILE "/data/bootchart-stop" #define LOG_STARTFILE LOG_ROOT"/start" #define LOG_STOPFILE LOG_ROOT"/stop" #define FILE_BUFF_SIZE 65536 struct FileBuff { int count; int fd; char data[FILE_BUFF_SIZE]; }; static long long last_bootchart_time; static int g_remaining_samples; static FileBuff log_stat[1]; static FileBuff log_procs[1]; static FileBuff log_disks[1]; static int proc_read(const char* filename, char* buff, size_t buffsize) Loading @@ -57,19 +78,11 @@ proc_read(const char* filename, char* buff, size_t buffsize) return len; } #define FILE_BUFF_SIZE 65536 struct FileBuff { int count; int fd; char data[FILE_BUFF_SIZE]; }; static void file_buff_open( FileBuff* buff, const char* path ) { buff->count = 0; buff->fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0755); buff->fd = open(path, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0755); } static void Loading Loading @@ -248,9 +261,19 @@ do_log_procs(FileBuff* log) do_log_ln(log); } static FileBuff log_stat[1]; static FileBuff log_procs[1]; static FileBuff log_disks[1]; int do_bootchart_init(int nargs, char **args) { g_remaining_samples = bootchart_init(); if (g_remaining_samples < 0) { ERROR("bootcharting init failure\n"); } else if (g_remaining_samples > 0) { NOTICE("bootcharting started (will run for %d ms)\n", g_remaining_samples*BOOTCHART_POLLING_MS); } else { NOTICE("bootcharting ignored\n"); } return 0; } /* called to setup bootcharting */ int bootchart_init( void ) Loading Loading @@ -307,14 +330,13 @@ int bootchart_init( void ) return count; } /* called each time you want to perform a bootchart sampling op */ int bootchart_step( void ) static int bootchart_step( void ) { do_log_file(log_stat, "/proc/stat"); do_log_file(log_disks, "/proc/diskstats"); do_log_procs(log_procs); /* we stop when /data/bootchart-stop contains 1 */ /* we stop when /data/bootchart/stop contains 1 */ { char buff[2]; if (proc_read(LOG_STOPFILE,buff,sizeof(buff)) > 0 && buff[0] == '1') { Loading @@ -325,6 +347,42 @@ int bootchart_step( void ) return 0; } /* called to get time (in ms) used by bootchart */ static long long bootchart_gettime() { return 10LL*get_uptime_jiffies(); } /* called each time you want to perform a bootchart sampling op */ void bootchart_sample(int* timeout) { if (g_remaining_samples > 0) { long long current_time; int elapsed_time, remaining_time; current_time = bootchart_gettime(); elapsed_time = current_time - last_bootchart_time; if (elapsed_time >= BOOTCHART_POLLING_MS) { /* count missed samples */ while (elapsed_time >= BOOTCHART_POLLING_MS) { elapsed_time -= BOOTCHART_POLLING_MS; g_remaining_samples--; } /* count may be negative, take a sample anyway */ last_bootchart_time = current_time; if (bootchart_step() < 0 || g_remaining_samples <= 0) { bootchart_finish(); g_remaining_samples = 0; } } if (g_remaining_samples > 0) { remaining_time = BOOTCHART_POLLING_MS - elapsed_time; if (*timeout < 0 || *timeout > remaining_time) { *timeout = remaining_time; } } } } void bootchart_finish( void ) { unlink( LOG_STOPFILE ); Loading @@ -333,9 +391,3 @@ void bootchart_finish( void ) file_buff_done(log_procs); acct(NULL); } /* called to get time (in ms) used by bootchart */ long long bootchart_gettime( void ) { return 10LL*get_uptime_jiffies(); }
init/bootchart.h +3 −8 Original line number Diff line number Diff line Loading @@ -17,13 +17,8 @@ #ifndef _BOOTCHART_H #define _BOOTCHART_H extern int bootchart_init(void); extern int bootchart_step(void); extern void bootchart_finish(void); extern long long bootchart_gettime(void); #define BOOTCHART_POLLING_MS 200 /* polling period in ms */ #define BOOTCHART_DEFAULT_TIME_SEC (2*60) /* default polling time in seconds */ #define BOOTCHART_MAX_TIME_SEC (10*60) /* max polling time in seconds */ int bootchart_init(); void bootchart_sample(int* timeout); void bootchart_finish(); #endif /* _BOOTCHART_H */
init/init.cpp +12 −60 Original line number Diff line number Diff line Loading @@ -63,9 +63,6 @@ struct selabel_handle *sehandle_prop; static int property_triggers_enabled = 0; static int bootchart_count; static long long bootchart_time = 0; static char console[32]; static char bootmode[32]; static char hardware[32]; Loading Loading @@ -857,20 +854,6 @@ static int queue_property_triggers_action(int nargs, char **args) return 0; } static int bootchart_init_action(int nargs, char **args) { bootchart_count = bootchart_init(); if (bootchart_count < 0) { ERROR("bootcharting init failure\n"); } else if (bootchart_count > 0) { NOTICE("bootcharting started (period=%d ms)\n", bootchart_count*BOOTCHART_POLLING_MS); } else { NOTICE("bootcharting ignored\n"); } return 0; } void selinux_init_all_handles(void) { sehandle = selinux_android_file_context_handle(); Loading Loading @@ -988,7 +971,7 @@ static void selinux_initialize(void) int main(int argc, char **argv) { int fd_count = 0; size_t fd_count = 0; struct pollfd ufds[4]; int property_set_fd_init = 0; int signal_fd_init = 0; Loading Loading @@ -1087,13 +1070,7 @@ int main(int argc, char **argv) /* run all property triggers based on current state of the properties */ queue_builtin_action(queue_property_triggers_action, "queue_property_triggers"); if (BOOTCHART) { queue_builtin_action(bootchart_init_action, "bootchart_init"); } for (;;) { int nr, i, timeout = -1; execute_one_command(); restart_processes(); Loading @@ -1119,6 +1096,7 @@ int main(int argc, char **argv) keychord_fd_init = 1; } int timeout = -1; if (process_needs_restart) { timeout = (process_needs_restart - gettime()) * 1000; if (timeout < 0) Loading @@ -1129,51 +1107,25 @@ int main(int argc, char **argv) timeout = 0; } if (BOOTCHART) { if (bootchart_count > 0) { long long current_time; int elapsed_time, remaining_time; bootchart_sample(&timeout); current_time = bootchart_gettime(); elapsed_time = current_time - bootchart_time; if (elapsed_time >= BOOTCHART_POLLING_MS) { /* count missed samples */ while (elapsed_time >= BOOTCHART_POLLING_MS) { elapsed_time -= BOOTCHART_POLLING_MS; bootchart_count--; } /* count may be negative, take a sample anyway */ bootchart_time = current_time; if (bootchart_step() < 0 || bootchart_count <= 0) { bootchart_finish(); bootchart_count = 0; } } if (bootchart_count > 0) { remaining_time = BOOTCHART_POLLING_MS - elapsed_time; if (timeout < 0 || timeout > remaining_time) { timeout = remaining_time; } } } } nr = poll(ufds, fd_count, timeout); if (nr <= 0) int nr = poll(ufds, fd_count, timeout); if (nr <= 0) { continue; } for (i = 0; i < fd_count; i++) { for (size_t i = 0; i < fd_count; i++) { if (ufds[i].revents & POLLIN) { if (ufds[i].fd == get_property_set_fd()) if (ufds[i].fd == get_property_set_fd()) { handle_property_set_fd(); else if (ufds[i].fd == get_keychord_fd()) } else if (ufds[i].fd == get_keychord_fd()) { handle_keychord(); else if (ufds[i].fd == get_signal_fd()) } else if (ufds[i].fd == get_signal_fd()) { handle_signal(); } } } } return 0; }