summaryrefslogtreecommitdiffstats
path: root/src/coredump
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2021-02-09 17:41:10 +0100
committerLennart Poettering <lennart@poettering.net>2021-02-10 12:22:21 +0100
commit4016281c4faac40541a80be9d44b3a81ce830981 (patch)
treee36abfeb53491f1654c71f95cf0c8512987a6957 /src/coredump
parentman: document new coredumpctl features (diff)
downloadsystemd-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.c112
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