Loading cmds/dumpstate/dumpstate.c +62 −1 Original line number Diff line number Diff line Loading @@ -99,6 +99,67 @@ static void dump_dev_files(const char *title, const char *driverpath, const char closedir(d); } static bool skip_not_stat(const char *path) { static const char stat[] = "/stat"; size_t len = strlen(path); if (path[len - 1] == '/') { /* Directory? */ return false; } return strcmp(path + len - sizeof(stat) + 1, stat); /* .../stat? */ } static const char mmcblk0[] = "/sys/block/mmcblk0/"; static int dump_stat_from_fd(const char *title __unused, const char *path, int fd) { unsigned long fields[11], read_perf, write_perf; bool z; char *cp, *buffer = NULL; size_t i = 0; FILE *fp = fdopen(fd, "rb"); getline(&buffer, &i, fp); fclose(fp); if (!buffer) { return -errno; } i = strlen(buffer); while ((i > 0) && (buffer[i - 1] == '\n')) { buffer[--i] = '\0'; } if (!*buffer) { free(buffer); return 0; } z = true; for (cp = buffer, i = 0; i < (sizeof(fields) / sizeof(fields[0])); ++i) { fields[i] = strtol(cp, &cp, 0); if (fields[i] != 0) { z = false; } } if (z) { /* never accessed */ free(buffer); return 0; } if (!strncmp(path, mmcblk0, sizeof(mmcblk0) - 1)) { path += sizeof(mmcblk0) - 1; } printf("%s: %s\n", path, buffer); free(buffer); read_perf = 0; if (fields[3]) { read_perf = 512 * fields[2] / fields[3]; } write_perf = 0; if (fields[7]) { write_perf = 512 * fields[6] / fields[7]; } printf("%s: read: %luKB/s write: %luKB/s\n", path, read_perf, write_perf); return 0; } /* dumps the current system state to stdout */ static void dumpstate() { time_t now = time(NULL); Loading Loading @@ -133,7 +194,7 @@ static void dumpstate() { dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version"); run_command("UPTIME", 10, "uptime", NULL); dump_file("MMC PERF", "/sys/block/mmcblk0/stat"); dump_files("UPTIME MMC PERF", mmcblk0, skip_not_stat, dump_stat_from_fd); dump_file("MEMORY INFO", "/proc/meminfo"); run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-t", NULL); run_command("PROCRANK", 20, "procrank", NULL); Loading cmds/dumpstate/dumpstate.h +10 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,16 @@ int dump_file(const char *title, const char *path); */ int dump_file_from_fd(const char *title, const char *path, int fd); /* calls skip to gate calling dump_from_fd recursively * in the specified directory. dump_from_fd defaults to * dump_file_from_fd above when set to NULL. skip defaults * to false when set to NULL. dump_from_fd will always be * called with title NULL. */ int dump_files(const char *title, const char *dir, bool (*skip)(const char *path), int (*dump_from_fd)(const char *title, const char *path, int fd)); /* forks a command and waits for it to finish -- terminate args with NULL */ int run_command(const char *title, int timeout_seconds, const char *command, ...); Loading cmds/dumpstate/utils.c +69 −0 Original line number Diff line number Diff line Loading @@ -310,6 +310,75 @@ int dump_file(const char *title, const char *path) { return _dump_file_from_fd(title, path, fd); } /* calls skip to gate calling dump_from_fd recursively * in the specified directory. dump_from_fd defaults to * dump_file_from_fd above when set to NULL. skip defaults * to false when set to NULL. dump_from_fd will always be * called with title NULL. */ int dump_files(const char *title, const char *dir, bool (*skip)(const char *path), int (*dump_from_fd)(const char *title, const char *path, int fd)) { DIR *dirp; struct dirent *d; char *newpath = NULL; char *slash = "/"; int fd, retval = 0; if (title) { printf("------ %s (%s) ------\n", title, dir); } if (dir[strlen(dir) - 1] == '/') { ++slash; } dirp = opendir(dir); if (dirp == NULL) { retval = -errno; fprintf(stderr, "%s: %s\n", dir, strerror(errno)); return retval; } if (!dump_from_fd) { dump_from_fd = dump_file_from_fd; } for (; ((d = readdir(dirp))); free(newpath), newpath = NULL) { if ((d->d_name[0] == '.') && (((d->d_name[1] == '.') && (d->d_name[2] == '\0')) || (d->d_name[1] == '\0'))) { continue; } asprintf(&newpath, "%s%s%s%s", dir, slash, d->d_name, (d->d_type == DT_DIR) ? "/" : ""); if (!newpath) { retval = -errno; continue; } if (skip && (*skip)(newpath)) { continue; } if (d->d_type == DT_DIR) { int ret = dump_files(NULL, newpath, skip, dump_from_fd); if (ret < 0) { retval = ret; } continue; } fd = TEMP_FAILURE_RETRY(open(newpath, O_RDONLY | O_NONBLOCK | O_CLOEXEC)); if (fd < 0) { retval = fd; printf("*** %s: %s\n", newpath, strerror(errno)); continue; } (*dump_from_fd)(NULL, newpath, fd); } closedir(dirp); if (title) { printf("\n"); } return retval; } /* fd must have been opened with the flag O_NONBLOCK. With this flag set, * it's possible to avoid issues where opening the file itself can get * stuck. Loading Loading
cmds/dumpstate/dumpstate.c +62 −1 Original line number Diff line number Diff line Loading @@ -99,6 +99,67 @@ static void dump_dev_files(const char *title, const char *driverpath, const char closedir(d); } static bool skip_not_stat(const char *path) { static const char stat[] = "/stat"; size_t len = strlen(path); if (path[len - 1] == '/') { /* Directory? */ return false; } return strcmp(path + len - sizeof(stat) + 1, stat); /* .../stat? */ } static const char mmcblk0[] = "/sys/block/mmcblk0/"; static int dump_stat_from_fd(const char *title __unused, const char *path, int fd) { unsigned long fields[11], read_perf, write_perf; bool z; char *cp, *buffer = NULL; size_t i = 0; FILE *fp = fdopen(fd, "rb"); getline(&buffer, &i, fp); fclose(fp); if (!buffer) { return -errno; } i = strlen(buffer); while ((i > 0) && (buffer[i - 1] == '\n')) { buffer[--i] = '\0'; } if (!*buffer) { free(buffer); return 0; } z = true; for (cp = buffer, i = 0; i < (sizeof(fields) / sizeof(fields[0])); ++i) { fields[i] = strtol(cp, &cp, 0); if (fields[i] != 0) { z = false; } } if (z) { /* never accessed */ free(buffer); return 0; } if (!strncmp(path, mmcblk0, sizeof(mmcblk0) - 1)) { path += sizeof(mmcblk0) - 1; } printf("%s: %s\n", path, buffer); free(buffer); read_perf = 0; if (fields[3]) { read_perf = 512 * fields[2] / fields[3]; } write_perf = 0; if (fields[7]) { write_perf = 512 * fields[6] / fields[7]; } printf("%s: read: %luKB/s write: %luKB/s\n", path, read_perf, write_perf); return 0; } /* dumps the current system state to stdout */ static void dumpstate() { time_t now = time(NULL); Loading Loading @@ -133,7 +194,7 @@ static void dumpstate() { dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version"); run_command("UPTIME", 10, "uptime", NULL); dump_file("MMC PERF", "/sys/block/mmcblk0/stat"); dump_files("UPTIME MMC PERF", mmcblk0, skip_not_stat, dump_stat_from_fd); dump_file("MEMORY INFO", "/proc/meminfo"); run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-t", NULL); run_command("PROCRANK", 20, "procrank", NULL); Loading
cmds/dumpstate/dumpstate.h +10 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,16 @@ int dump_file(const char *title, const char *path); */ int dump_file_from_fd(const char *title, const char *path, int fd); /* calls skip to gate calling dump_from_fd recursively * in the specified directory. dump_from_fd defaults to * dump_file_from_fd above when set to NULL. skip defaults * to false when set to NULL. dump_from_fd will always be * called with title NULL. */ int dump_files(const char *title, const char *dir, bool (*skip)(const char *path), int (*dump_from_fd)(const char *title, const char *path, int fd)); /* forks a command and waits for it to finish -- terminate args with NULL */ int run_command(const char *title, int timeout_seconds, const char *command, ...); Loading
cmds/dumpstate/utils.c +69 −0 Original line number Diff line number Diff line Loading @@ -310,6 +310,75 @@ int dump_file(const char *title, const char *path) { return _dump_file_from_fd(title, path, fd); } /* calls skip to gate calling dump_from_fd recursively * in the specified directory. dump_from_fd defaults to * dump_file_from_fd above when set to NULL. skip defaults * to false when set to NULL. dump_from_fd will always be * called with title NULL. */ int dump_files(const char *title, const char *dir, bool (*skip)(const char *path), int (*dump_from_fd)(const char *title, const char *path, int fd)) { DIR *dirp; struct dirent *d; char *newpath = NULL; char *slash = "/"; int fd, retval = 0; if (title) { printf("------ %s (%s) ------\n", title, dir); } if (dir[strlen(dir) - 1] == '/') { ++slash; } dirp = opendir(dir); if (dirp == NULL) { retval = -errno; fprintf(stderr, "%s: %s\n", dir, strerror(errno)); return retval; } if (!dump_from_fd) { dump_from_fd = dump_file_from_fd; } for (; ((d = readdir(dirp))); free(newpath), newpath = NULL) { if ((d->d_name[0] == '.') && (((d->d_name[1] == '.') && (d->d_name[2] == '\0')) || (d->d_name[1] == '\0'))) { continue; } asprintf(&newpath, "%s%s%s%s", dir, slash, d->d_name, (d->d_type == DT_DIR) ? "/" : ""); if (!newpath) { retval = -errno; continue; } if (skip && (*skip)(newpath)) { continue; } if (d->d_type == DT_DIR) { int ret = dump_files(NULL, newpath, skip, dump_from_fd); if (ret < 0) { retval = ret; } continue; } fd = TEMP_FAILURE_RETRY(open(newpath, O_RDONLY | O_NONBLOCK | O_CLOEXEC)); if (fd < 0) { retval = fd; printf("*** %s: %s\n", newpath, strerror(errno)); continue; } (*dump_from_fd)(NULL, newpath, fd); } closedir(dirp); if (title) { printf("\n"); } return retval; } /* fd must have been opened with the flag O_NONBLOCK. With this flag set, * it's possible to avoid issues where opening the file itself can get * stuck. Loading