dumpstate.c revision 54aa577ea28999de2f30bc34daed0cc821934409
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor#include <errno.h>
1852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor#include <fcntl.h>
1952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor#include <limits.h>
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h>
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h>
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h>
2352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor#include <sys/resource.h>
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/stat.h>
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/time.h>
2652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor#include <unistd.h>
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor#include <cutils/properties.h>
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor#include "private/android_filesystem_config.h"
31f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato
32bb6fa17558ff9212a48bd4be24aef235814b944eMike Lockwood#define LOG_TAG "dumpstate"
33bb6fa17558ff9212a48bd4be24aef235814b944eMike Lockwood#include <utils/Log.h>
34bb6fa17558ff9212a48bd4be24aef235814b944eMike Lockwood
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "dumpstate.h"
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor/* read before root is shed */
3852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnorstatic char cmdline_buf[16384] = "(unknown)";
3952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnorstatic const char *dump_traces_path = NULL;
4030b9f57c8b2c1e3d0b3d2668ad04980ea0050d04San Mehat
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* dumps the current system state to stdout */
4252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnorstatic void dumpstate() {
4352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    time_t now = time(NULL);
4452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    char build[PROPERTY_VALUE_MAX], fingerprint[PROPERTY_VALUE_MAX];
4552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    char radio[PROPERTY_VALUE_MAX], bootloader[PROPERTY_VALUE_MAX];
4652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    char network[PROPERTY_VALUE_MAX], date[80];
4752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
4852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    property_get("ro.build.display.id", build, "(unknown)");
4952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    property_get("ro.build.fingerprint", fingerprint, "(unknown)");
5052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    property_get("ro.baseband", radio, "(unknown)");
5152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    property_get("ro.bootloader", bootloader, "(unknown)");
5252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    property_get("gsm.operator.alpha", network, "(unknown)");
5352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&now));
5452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
5552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("========================================================\n");
5652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("== dumpstate: %s\n", date);
5752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("========================================================\n");
5852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
5952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("\n");
6052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("Build: %s\n", build);
6152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("Bootloader: %s\n", bootloader);
6252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("Radio: %s\n", radio);
6352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("Network: %s\n", network);
6452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
6552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("Kernel: ");
6652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file(NULL, "/proc/version");
6752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("Command line: %s\n", strtok(cmdline_buf, "\n"));
6852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("\n");
6952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
7052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("MEMORY INFO", "/proc/meminfo");
7152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-t", NULL);
7252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("PROCRANK", 20, "procrank", NULL);
7352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("VIRTUAL MEMORY STATS", "/proc/vmstat");
7452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("VMALLOC INFO", "/proc/vmallocinfo");
7552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("SLAB INFO", "/proc/slabinfo");
7652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("ZONEINFO", "/proc/zoneinfo");
7752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
7852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("SYSTEM LOG", 20, "logcat", "-v", "time", "-d", "*:v", NULL);
7952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
8052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    /* show the traces we collected in main(), if that was done */
8152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    if (dump_traces_path != NULL) {
8252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        dump_file("VM TRACES JUST NOW", dump_traces_path);
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
8552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    /* only show ANR traces if they're less than 15 minutes old */
8652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    struct stat st;
8752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    char anr_traces_path[PATH_MAX];
8852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    property_get("dalvik.vm.stack-trace-file", anr_traces_path, "");
8952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    if (anr_traces_path[0] && !stat(anr_traces_path, &st) && time(NULL) - st.st_mtime < 15 * 60) {
9052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        dump_file("VM TRACES AT LAST ANR", anr_traces_path);
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    // dump_file("EVENT LOG TAGS", "/etc/event-log-tags");
9452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("EVENT LOG", 20, "logcat", "-b", "events", "-v", "time", "-d", "*:v", NULL);
9552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("RADIO LOG", 20, "logcat", "-b", "radio", "-v", "time", "-d", "*:v", NULL);
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("NETWORK INTERFACES", 10, "netcfg", NULL);
9852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("NETWORK ROUTES", "/proc/net/route");
9984b72ec3b455a016fcb7a7c8d02959fc6b5b88d2Dmitry Shmidt    dump_file("ARP CACHE", "/proc/net/arp");
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor#ifdef FWDUMP_bcm4329
10252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("DUMP WIFI FIRMWARE LOG", 60,
10352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            "dhdutil", "-i", "eth0", "upload", "/data/local/tmp/wlan_crash.dump", NULL);
10452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor#endif
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    print_properties();
10752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
10852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("KERNEL LOG", 20, "dmesg", NULL);
10952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
11052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("KERNEL WAKELOCKS", "/proc/wakelocks");
11152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state");
11252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
11354aa577ea28999de2f30bc34daed0cc821934409San Mehat    run_command("SECURE CONTAINERS", 10, "vdc", "asec", "list", NULL);
11454aa577ea28999de2f30bc34daed0cc821934409San Mehat    run_command("MOUNTED FILESYSTEMS", 10, "df", NULL);
11554aa577ea28999de2f30bc34daed0cc821934409San Mehat
11652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("PROCESSES", 10, "ps", "-P", NULL);
11752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("PROCESSES AND THREADS", 10, "ps", "-t", "-p", "-P", NULL);
11852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("LIBRANK", 10, "librank", NULL);
11952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
12052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("BINDER FAILED TRANSACTION LOG", "/proc/binder/failed_transaction_log");
12152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("BINDER TRANSACTION LOG", "/proc/binder/transaction_log");
12252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("BINDER TRANSACTIONS", "/proc/binder/transactions");
12352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("BINDER STATS", "/proc/binder/stats");
12452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("BINDER PROCESS STATE", 10, "sh", "-c", "cat /proc/binder/proc/*");
12552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
12652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("FILESYSTEMS & FREE SPACE", 10, "df", NULL);
12752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
12852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("PACKAGE SETTINGS", "/data/system/packages.xml");
12952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("PACKAGE UID ERRORS", "/data/system/uiderrors.txt");
13052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
13152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("LAST KMSG", "/proc/last_kmsg");
13252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("LAST RADIO LOG", 10, "parse_radio_log", "/proc/last_radio_log", NULL);
13352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("LAST PANIC CONSOLE", "/data/dontpanic/apanic_console");
13452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("LAST PANIC THREADS", "/data/dontpanic/apanic_threads");
13552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
136ea11654e684cb91252487f697c72e76da507f7beDan Egnor    printf("------ BACKLIGHTS ------\n");
13752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("LCD brightness=");
13852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file(NULL, "/sys/class/leds/lcd-backlight/brightness");
13952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("Button brightness=");
14052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file(NULL, "/sys/class/leds/button-backlight/brightness");
14152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("Keyboard brightness=");
14252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file(NULL, "/sys/class/leds/keyboard-backlight/brightness");
14352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("ALS mode=");
14452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file(NULL, "/sys/class/leds/lcd-backlight/als");
14552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("LCD driver registers:\n");
14652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file(NULL, "/sys/class/leds/lcd-backlight/registers");
14752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("\n");
14852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
14952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("========================================================\n");
15052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("== Android Framework Services\n");
15152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("========================================================\n");
15252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
15352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    /* the full dumpsys is starting to take a long time, so we need
15452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor       to increase its timeout.  we really need to do the timeouts in
15552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor       dumpsys itself... */
15652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("DUMPSYS", 60, "dumpsys", NULL);
15752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor}
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
16052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnorstatic void usage() {
16152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    fprintf(stderr, "usage: dumpstate [-d] [-o file] [-s] [-z]\n"
16252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            "  -d: append date to filename (requires -o)\n"
16352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            "  -o: write to file (instead of stdout)\n"
16452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            "  -s: write output to control socket (for init)\n"
16552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            "  -z: gzip output (requires -o)\n");
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint main(int argc, char *argv[]) {
16952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    int do_add_date = 0;
17052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    int do_compress = 0;
17152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    char* use_outfile = 0;
17252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    int use_socket = 0;
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
174bb6fa17558ff9212a48bd4be24aef235814b944eMike Lockwood    LOGI("begin\n");
175bb6fa17558ff9212a48bd4be24aef235814b944eMike Lockwood
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* set as high priority, and protect from OOM killer */
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    setpriority(PRIO_PROCESS, 0, -20);
17852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    FILE *oom_adj = fopen("/proc/self/oom_adj", "w");
17952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    if (oom_adj) {
18052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        fputs("-17", oom_adj);
18152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        fclose(oom_adj);
18252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    }
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    /* very first thing, collect VM traces from Dalvik (needs root) */
18552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_traces_path = dump_vm_traces();
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    int c;
18852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    while ((c = getopt(argc, argv, "dho:svz")) != -1) {
1898d5337301b87ba84a45327f355aa768c864de021Mike Lockwood        switch (c) {
19052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            case 'd': do_add_date = 1;       break;
19152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            case 'o': use_outfile = optarg;  break;
19252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            case 's': use_socket = 1;        break;
19352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            case 'v': break;  // compatibility no-op
19452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            case 'z': do_compress = 6;       break;
19552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            case '?': printf("\n");
19652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            case 'h':
19752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor                usage();
1988d5337301b87ba84a45327f355aa768c864de021Mike Lockwood                exit(1);
1998d5337301b87ba84a45327f355aa768c864de021Mike Lockwood        }
20052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    }
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    /* open the vibrator before dropping root */
20352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    FILE *vibrator = fopen("/sys/class/timed_output/vibrator/enable", "w");
20452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    if (vibrator) fcntl(fileno(vibrator), F_SETFD, FD_CLOEXEC);
20552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
20652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    /* read /proc/cmdline before dropping root */
20752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    FILE *cmdline = fopen("/proc/cmdline", "r");
20852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    if (cmdline != NULL) {
20952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        fgets(cmdline_buf, sizeof(cmdline_buf), cmdline);
21052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        fclose(cmdline);
21152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    }
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* switch to non-root user and group */
21454aa577ea28999de2f30bc34daed0cc821934409San Mehat    gid_t groups[] = { AID_LOG, AID_SDCARD_RW, AID_MOUNT };
215472be48007f8c3a9b462b8c9024cb4a0a0beac04Mike Lockwood    setgroups(sizeof(groups)/sizeof(groups[0]), groups);
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    setuid(AID_SHELL);
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    char path[PATH_MAX], tmp_path[PATH_MAX];
21952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    pid_t gzip_pid = -1;
22052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
22152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    if (use_socket) {
22252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        redirect_to_socket(stdout, "dumpstate");
22352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    } else if (use_outfile) {
22452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        strlcpy(path, use_outfile, sizeof(path));
22552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        if (do_add_date) {
22652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            char date[80];
22752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            time_t now = time(NULL);
22852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            strftime(date, sizeof(date), "-%Y-%m-%d-%H-%M-%S", localtime(&now));
22952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            strlcat(path, date, sizeof(path));
2308d5337301b87ba84a45327f355aa768c864de021Mike Lockwood        }
23152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        strlcat(path, ".txt", sizeof(path));
23252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        if (do_compress) strlcat(path, ".gz", sizeof(path));
23352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        strlcpy(tmp_path, path, sizeof(tmp_path));
23452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        strlcat(tmp_path, ".tmp", sizeof(tmp_path));
23552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        gzip_pid = redirect_to_file(stdout, tmp_path, do_compress);
23652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    }
2378d5337301b87ba84a45327f355aa768c864de021Mike Lockwood
23852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    /* bzzzzzz */
23952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    if (vibrator) {
24052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        fputs("150", vibrator);
24152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        fflush(vibrator);
24252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    }
2438d5337301b87ba84a45327f355aa768c864de021Mike Lockwood
24452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dumpstate();
24552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
24652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    /* bzzz bzzz bzzz */
24752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    if (vibrator) {
24852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        int i;
24952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        for (i = 0; i < 3; i++) {
25052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            fputs("75\n", vibrator);
25152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            fflush(vibrator);
25252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            usleep((75 + 50) * 1000);
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
25452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        fclose(vibrator);
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    /* wait for gzip to finish, otherwise it might get killed when we exit */
25852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    if (gzip_pid > 0) {
25952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        fclose(stdout);
26052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        waitpid(gzip_pid, NULL, 0);
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    /* rename the (now complete) .tmp file to its final location */
26452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    if (use_outfile && rename(tmp_path, path)) {
26552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        fprintf(stderr, "rename(%s, %s): %s\n", tmp_path, path, strerror(errno));
26652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    }
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
268bb6fa17558ff9212a48bd4be24aef235814b944eMike Lockwood    LOGI("done\n");
269bb6fa17558ff9212a48bd4be24aef235814b944eMike Lockwood
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
272