mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-11 05:17:44 +03:00
coredumpctl: Add support for the --root option
With this option, coredumpctl looks for journal files under the specified root directory
This commit is contained in:
parent
07faa4990f
commit
71bdc96ab7
@ -248,6 +248,13 @@
|
|||||||
</para></listitem>
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--root=<replaceable>ROOT</replaceable></option></term>
|
||||||
|
|
||||||
|
<listitem><para>Use root directory <option>ROOT</option> when searching for coredumps.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>-q</option></term>
|
<term><option>-q</option></term>
|
||||||
<term><option>--quiet</option></term>
|
<term><option>--quiet</option></term>
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "bus-error.h"
|
#include "bus-error.h"
|
||||||
#include "bus-locator.h"
|
#include "bus-locator.h"
|
||||||
#include "bus-util.h"
|
#include "bus-util.h"
|
||||||
|
#include "chase-symlinks.h"
|
||||||
#include "compress.h"
|
#include "compress.h"
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
@ -49,6 +50,7 @@ static const char* arg_field = NULL;
|
|||||||
static const char *arg_debugger = NULL;
|
static const char *arg_debugger = NULL;
|
||||||
static char **arg_debugger_args = NULL;
|
static char **arg_debugger_args = NULL;
|
||||||
static const char *arg_directory = NULL;
|
static const char *arg_directory = NULL;
|
||||||
|
static char *arg_root = NULL;
|
||||||
static char **arg_file = NULL;
|
static char **arg_file = NULL;
|
||||||
static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
|
static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
|
||||||
static PagerFlags arg_pager_flags = 0;
|
static PagerFlags arg_pager_flags = 0;
|
||||||
@ -121,6 +123,10 @@ static int acquire_journal(sd_journal **ret, char **matches) {
|
|||||||
r = sd_journal_open_directory(&j, arg_directory, 0);
|
r = sd_journal_open_directory(&j, arg_directory, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to open journals in directory: %s: %m", arg_directory);
|
return log_error_errno(r, "Failed to open journals in directory: %s: %m", arg_directory);
|
||||||
|
} else if (arg_root) {
|
||||||
|
r = sd_journal_open_directory(&j, arg_root, SD_JOURNAL_OS_ROOT);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to open journals in root directory: %s: %m", arg_root);
|
||||||
} else if (arg_file) {
|
} else if (arg_file) {
|
||||||
r = sd_journal_open_files(&j, (const char**)arg_file, 0);
|
r = sd_journal_open_files(&j, (const char**)arg_file, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -205,6 +211,7 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
ARG_JSON,
|
ARG_JSON,
|
||||||
ARG_DEBUGGER,
|
ARG_DEBUGGER,
|
||||||
ARG_FILE,
|
ARG_FILE,
|
||||||
|
ARG_ROOT,
|
||||||
ARG_ALL,
|
ARG_ALL,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -226,6 +233,7 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
{ "until", required_argument, NULL, 'U' },
|
{ "until", required_argument, NULL, 'U' },
|
||||||
{ "quiet", no_argument, NULL, 'q' },
|
{ "quiet", no_argument, NULL, 'q' },
|
||||||
{ "json", required_argument, NULL, ARG_JSON },
|
{ "json", required_argument, NULL, ARG_JSON },
|
||||||
|
{ "root", required_argument, NULL, ARG_ROOT },
|
||||||
{ "all", no_argument, NULL, ARG_ALL },
|
{ "all", no_argument, NULL, ARG_ALL },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
@ -316,6 +324,12 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
arg_directory = optarg;
|
arg_directory = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ARG_ROOT:
|
||||||
|
r = parse_path_argument(optarg, false, &arg_root);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'r':
|
case 'r':
|
||||||
arg_reverse = true;
|
arg_reverse = true;
|
||||||
break;
|
break;
|
||||||
@ -347,6 +361,9 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
"--since= must be before --until=.");
|
"--since= must be before --until=.");
|
||||||
|
|
||||||
|
if ((!!arg_directory + !!arg_root) > 1)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Please specify either --root= or -D/--directory=, the combination of these options is not supported.");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -467,6 +484,26 @@ error:
|
|||||||
*ret_size = UINT64_MAX;
|
*ret_size = UINT64_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int resolve_filename(const char *path, const char *root, char **ret) {
|
||||||
|
char *resolved = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (!path)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r = chase_symlinks(path, root, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &resolved, NULL);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to resolve \"%s%s\": %m", strempty(root), path);
|
||||||
|
|
||||||
|
free_and_replace(*ret, resolved);
|
||||||
|
|
||||||
|
/* chase_symlinks() witth flag CHASE_NONEXISTENT
|
||||||
|
* will return 0 if the file doesn't exist and 1 if it does.
|
||||||
|
* Return that to the caller
|
||||||
|
*/
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static int print_list(FILE* file, sd_journal *j, Table *t) {
|
static int print_list(FILE* file, sd_journal *j, Table *t) {
|
||||||
_cleanup_free_ char
|
_cleanup_free_ char
|
||||||
*mid = NULL, *pid = NULL, *uid = NULL, *gid = NULL,
|
*mid = NULL, *pid = NULL, *uid = NULL, *gid = NULL,
|
||||||
@ -515,9 +552,13 @@ static int print_list(FILE* file, sd_journal *j, Table *t) {
|
|||||||
|
|
||||||
normal_coredump = streq_ptr(mid, SD_MESSAGE_COREDUMP_STR);
|
normal_coredump = streq_ptr(mid, SD_MESSAGE_COREDUMP_STR);
|
||||||
|
|
||||||
if (filename)
|
if (filename) {
|
||||||
|
r = resolve_filename(filename, arg_root, &filename);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
analyze_coredump_file(filename, &present, &color, &size);
|
analyze_coredump_file(filename, &present, &color, &size);
|
||||||
else if (coredump)
|
} else if (coredump)
|
||||||
present = "journal";
|
present = "journal";
|
||||||
else if (normal_coredump) {
|
else if (normal_coredump) {
|
||||||
present = "none";
|
present = "none";
|
||||||
@ -701,6 +742,10 @@ static int print_info(FILE *file, sd_journal *j, bool need_space) {
|
|||||||
fprintf(file, " Hostname: %s\n", hostname);
|
fprintf(file, " Hostname: %s\n", hostname);
|
||||||
|
|
||||||
if (filename) {
|
if (filename) {
|
||||||
|
r = resolve_filename(filename, arg_root, &filename);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
const char *state = NULL, *color = NULL;
|
const char *state = NULL, *color = NULL;
|
||||||
uint64_t size = UINT64_MAX;
|
uint64_t size = UINT64_MAX;
|
||||||
|
|
||||||
@ -915,13 +960,18 @@ static int save_core(sd_journal *j, FILE *file, char **path, bool *unlink_temp)
|
|||||||
/* Look for a coredump on disk first. */
|
/* Look for a coredump on disk first. */
|
||||||
r = sd_journal_get_data(j, "COREDUMP_FILENAME", (const void**) &data, &len);
|
r = sd_journal_get_data(j, "COREDUMP_FILENAME", (const void**) &data, &len);
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
|
_cleanup_free_ char *resolved = NULL;
|
||||||
|
|
||||||
r = retrieve(data, len, "COREDUMP_FILENAME", &filename);
|
r = retrieve(data, len, "COREDUMP_FILENAME", &filename);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
assert(r > 0);
|
assert(r > 0);
|
||||||
|
|
||||||
if (access(filename, R_OK) < 0)
|
r = chase_symlinks_and_access(filename, arg_root, CHASE_PREFIX_ROOT, F_OK, &resolved, NULL);
|
||||||
return log_error_errno(errno, "File \"%s\" is not readable: %m", filename);
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Cannot access \"%s%s\": %m", strempty(arg_root), filename);
|
||||||
|
|
||||||
|
free_and_replace(filename, resolved);
|
||||||
|
|
||||||
if (path && !ENDSWITH_SET(filename, ".xz", ".lz4", ".zst")) {
|
if (path && !ENDSWITH_SET(filename, ".xz", ".lz4", ".zst")) {
|
||||||
*path = TAKE_PTR(filename);
|
*path = TAKE_PTR(filename);
|
||||||
@ -1142,6 +1192,10 @@ static int run_debug(int argc, char **argv, void *userdata) {
|
|||||||
return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
|
return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
|
||||||
"Binary is not an absolute path.");
|
"Binary is not an absolute path.");
|
||||||
|
|
||||||
|
r = resolve_filename(exe, arg_root, &exe);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
r = save_core(j, NULL, &path, &unlink_path);
|
r = save_core(j, NULL, &path, &unlink_path);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -1150,6 +1204,24 @@ static int run_debug(int argc, char **argv, void *userdata) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
|
if (arg_root) {
|
||||||
|
if (streq(arg_debugger, "gdb")) {
|
||||||
|
const char *sysroot_cmd;
|
||||||
|
sysroot_cmd = strjoina("set sysroot ", arg_root);
|
||||||
|
|
||||||
|
r = strv_extend_strv(&debugger_call, STRV_MAKE("-iex", sysroot_cmd), false);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
} else if (streq(arg_debugger, "lldb")) {
|
||||||
|
const char *sysroot_cmd;
|
||||||
|
sysroot_cmd = strjoina("platform select --sysroot ", arg_root, " host");
|
||||||
|
|
||||||
|
r = strv_extend_strv(&debugger_call, STRV_MAKE("-O", sysroot_cmd), false);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Don't interfere with gdb and its handling of SIGINT. */
|
/* Don't interfere with gdb and its handling of SIGINT. */
|
||||||
(void) ignore_signals(SIGINT);
|
(void) ignore_signals(SIGINT);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user