diff options
author | Lennart Poettering <lennart@poettering.net> | 2021-02-09 17:41:10 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2021-02-10 12:22:21 +0100 |
commit | 4016281c4faac40541a80be9d44b3a81ce830981 (patch) | |
tree | e36abfeb53491f1654c71f95cf0c8512987a6957 /src/coredump | |
parent | man: document new coredumpctl features (diff) | |
download | systemd-4016281c4faac40541a80be9d44b3a81ce830981.tar.xz systemd-4016281c4faac40541a80be9d44b3a81ce830981.zip |
coredumpctl: include coredump size in output
This improves the output of the "list" and "info" verbs and adds
coredump size information to the output.
For doing that a common helper function is added that analyzes the
coredump file on disk.
Diffstat (limited to 'src/coredump')
-rw-r--r-- | src/coredump/coredumpctl.c | 112 |
1 files changed, 80 insertions, 32 deletions
diff --git a/src/coredump/coredumpctl.c b/src/coredump/coredumpctl.c index 883923f8b3..46183451de 100644 --- a/src/coredump/coredumpctl.c +++ b/src/coredump/coredumpctl.c @@ -405,6 +405,59 @@ static int print_field(FILE* file, sd_journal *j) { continue; \ } +static void analyze_coredump_file( + const char *path, + const char **ret_state, + const char **ret_color, + uint64_t *ret_size) { + + _cleanup_close_ int fd = -1; + struct stat st; + int r; + + assert(path); + assert(ret_state); + assert(ret_color); + assert(ret_size); + + fd = open(path, O_PATH|O_CLOEXEC); + if (fd < 0) { + if (errno == ENOENT) { + *ret_state = "missing"; + *ret_color = ansi_grey(); + *ret_size = UINT64_MAX; + return; + } + + r = -errno; + } else + r = access_fd(fd, R_OK); + if (ERRNO_IS_PRIVILEGE(r)) { + *ret_state = "inaccessible"; + *ret_color = ansi_highlight_yellow(); + *ret_size = UINT64_MAX; + return; + } + if (r < 0) + goto error; + + if (fstat(fd, &st) < 0) + goto error; + + if (!S_ISREG(st.st_mode)) + goto error; + + *ret_state = "present"; + *ret_color = NULL; + *ret_size = st.st_size; + return; + +error: + *ret_state = "error"; + *ret_color = ansi_highlight_red(); + *ret_size = UINT64_MAX; +} + static int print_list(FILE* file, sd_journal *j, Table *t) { _cleanup_free_ char *mid = NULL, *pid = NULL, *uid = NULL, *gid = NULL, @@ -414,7 +467,8 @@ static int print_list(FILE* file, sd_journal *j, Table *t) { size_t l; usec_t ts; int r, signal_as_int = 0; - const char *present, *color; + const char *present = NULL, *color = NULL; + uint64_t size = UINT64_MAX; bool normal_coredump; uid_t uid_as_int = UID_INVALID; gid_t gid_as_int = GID_INVALID; @@ -453,18 +507,7 @@ static int print_list(FILE* file, sd_journal *j, Table *t) { normal_coredump = streq_ptr(mid, SD_MESSAGE_COREDUMP_STR); if (filename) - if (access(filename, R_OK) == 0) - present = "present"; - else if (errno == ENOENT) { - present = "missing"; - color = ansi_grey(); - } else if (ERRNO_IS_PRIVILEGE(errno)) { - present = "access denied"; - color = ansi_highlight_yellow(); - } else { - present = "error"; - color = ansi_highlight_red(); - } + analyze_coredump_file(filename, &present, &color, &size); else if (coredump) present = "journal"; else if (normal_coredump) { @@ -485,7 +528,8 @@ static int print_list(FILE* file, sd_journal *j, Table *t) { TABLE_SIGNAL, normal_coredump ? signal_as_int : 0, TABLE_STRING, present, TABLE_SET_COLOR, color, - TABLE_STRING, exe ?: comm ?: cmdline); + TABLE_STRING, exe ?: comm ?: cmdline, + TABLE_SIZE, size); if (r < 0) return table_log_add_error(r); @@ -646,24 +690,27 @@ static int print_info(FILE *file, sd_journal *j, bool need_space) { fprintf(file, " Hostname: %s\n", hostname); if (filename) { - bool inacc, trunc; - - inacc = access(filename, R_OK) < 0; - trunc = truncated && parse_boolean(truncated) > 0; - - if (inacc || trunc) - fprintf(file, " Storage: %s%s (%s%s%s)%s\n", - ansi_highlight_red(), - filename, - inacc ? "inaccessible" : "", - inacc && trunc ? ", " : "", - trunc ? "truncated" : "", - ansi_normal()); - else - fprintf(file, " Storage: %s\n", filename); - } + const char *state = NULL, *color = NULL; + uint64_t size = UINT64_MAX; + char buf[FORMAT_BYTES_MAX]; - else if (coredump) + analyze_coredump_file(filename, &state, &color, &size); + + if (STRPTR_IN_SET(state, "present", "journal") && truncated && parse_boolean(truncated) > 0) + state = "truncated"; + + fprintf(file, + " Storage: %s%s (%s)%s\n", + strempty(color), + filename, + state, + ansi_normal()); + + if (size != UINT64_MAX) + fprintf(file, + " Disk Size: %s\n", + format_bytes(buf, sizeof(buf), size)); + } else if (coredump) fprintf(file, " Storage: journal\n"); else fprintf(file, " Storage: none\n"); @@ -726,13 +773,14 @@ static int dump_list(int argc, char **argv, void *userdata) { (void) sd_journal_set_data_threshold(j, 4096); if (!verb_is_info && !arg_field) { - t = table_new("time", "pid", "uid", "gid", "sig", "corefule", "exe"); + t = table_new("time", "pid", "uid", "gid", "sig", "corefile", "exe", "size"); if (!t) return log_oom(); (void) table_set_align_percent(t, TABLE_HEADER_CELL(1), 100); (void) table_set_align_percent(t, TABLE_HEADER_CELL(2), 100); (void) table_set_align_percent(t, TABLE_HEADER_CELL(3), 100); + (void) table_set_align_percent(t, TABLE_HEADER_CELL(7), 100); (void) table_set_empty_string(t, "-"); } else |