#include "bus-error.h"
#include "bus-locator.h"
#include "bus-util.h"
+#include "chase-symlinks.h"
#include "compress.h"
#include "def.h"
#include "fd-util.h"
static const char *arg_debugger = NULL;
static char **arg_debugger_args = NULL;
static const char *arg_directory = NULL;
+static char *arg_root = NULL;
static char **arg_file = NULL;
static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
static PagerFlags arg_pager_flags = 0;
r = sd_journal_open_directory(&j, arg_directory, 0);
if (r < 0)
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) {
r = sd_journal_open_files(&j, (const char**)arg_file, 0);
if (r < 0)
ARG_JSON,
ARG_DEBUGGER,
ARG_FILE,
+ ARG_ROOT,
ARG_ALL,
};
{ "until", required_argument, NULL, 'U' },
{ "quiet", no_argument, NULL, 'q' },
{ "json", required_argument, NULL, ARG_JSON },
+ { "root", required_argument, NULL, ARG_ROOT },
{ "all", no_argument, NULL, ARG_ALL },
{}
};
arg_directory = optarg;
break;
+ case ARG_ROOT:
+ r = parse_path_argument(optarg, false, &arg_root);
+ if (r < 0)
+ return r;
+ break;
+
case 'r':
arg_reverse = true;
break;
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"--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;
}
*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) {
_cleanup_free_ char
*mid = NULL, *pid = NULL, *uid = NULL, *gid = NULL,
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);
- else if (coredump)
+ } else if (coredump)
present = "journal";
else if (normal_coredump) {
present = "none";
fprintf(file, " Hostname: %s\n", hostname);
if (filename) {
+ r = resolve_filename(filename, arg_root, &filename);
+ if (r < 0)
+ return r;
+
const char *state = NULL, *color = NULL;
uint64_t size = UINT64_MAX;
/* Look for a coredump on disk first. */
r = sd_journal_get_data(j, "COREDUMP_FILENAME", (const void**) &data, &len);
if (r == 0) {
+ _cleanup_free_ char *resolved = NULL;
+
r = retrieve(data, len, "COREDUMP_FILENAME", &filename);
if (r < 0)
return r;
assert(r > 0);
- if (access(filename, R_OK) < 0)
- return log_error_errno(errno, "File \"%s\" is not readable: %m", filename);
+ r = chase_symlinks_and_access(filename, arg_root, CHASE_PREFIX_ROOT, F_OK, &resolved, NULL);
+ 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")) {
*path = TAKE_PTR(filename);
return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
"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);
if (r < 0)
return r;
if (r < 0)
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. */
(void) ignore_signals(SIGINT);