diff options
author | Lennart Poettering <lennart@poettering.net> | 2013-12-11 22:04:03 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2013-12-11 22:04:03 +0100 |
commit | b6741478e7661c7e580e5dcfd6a6fccd1899c1d0 (patch) | |
tree | b29e463c8113c914a21b45226a845424214ece21 /src/journal | |
parent | 842129f58752864d4433792c9c47d40508c4439a (diff) |
journal: add ability to browse journals of running OS containers
This adds the new library call sd_journal_open_container() and a new
"-M" switch to journalctl. Particular care is taken that journalctl's
"-b" switch resolves to the current boot ID of the container, not the
host.
Diffstat (limited to 'src/journal')
-rw-r--r-- | src/journal/journalctl.c | 17 | ||||
-rw-r--r-- | src/journal/libsystemd-journal.sym | 5 | ||||
-rw-r--r-- | src/journal/sd-journal.c | 66 |
3 files changed, 70 insertions, 18 deletions
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index f74dde9c48..5d12c2b162 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -93,6 +93,7 @@ static bool arg_catalog = false; static bool arg_reverse = false; static int arg_journal_type = 0; static const char *arg_root = NULL; +static const char *arg_machine = NULL; static enum { ACTION_SHOW, @@ -120,6 +121,7 @@ static int help(void) { "Flags:\n" " --system Show only the system journal\n" " --user Show only the user journal for current user\n" + " -M --machine=CONTAINER Operate on local container\n" " --since=DATE Start showing entries newer or of the specified date\n" " --until=DATE Stop showing entries older or of the specified date\n" " -c --cursor=CURSOR Start showing entries from specified cursor\n" @@ -247,6 +249,7 @@ static int parse_argv(int argc, char *argv[]) { { "dump-catalog", no_argument, NULL, ARG_DUMP_CATALOG }, { "update-catalog", no_argument, NULL, ARG_UPDATE_CATALOG }, { "reverse", no_argument, NULL, 'r' }, + { "machine", required_argument, NULL, 'M' }, {} }; @@ -255,7 +258,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "hefo:aln::qmb::kD:p:c:u:F:xr", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "hefo:aln::qmb::kD:p:c:u:F:xrM:", options, NULL)) >= 0) { switch (c) { @@ -389,6 +392,10 @@ static int parse_argv(int argc, char *argv[]) { arg_journal_type |= SD_JOURNAL_CURRENT_USER; break; + case 'M': + arg_machine = optarg; + break; + case 'D': arg_directory = optarg; break; @@ -576,8 +583,8 @@ static int parse_argv(int argc, char *argv[]) { if (arg_follow && !arg_no_tail && arg_lines < 0) arg_lines = 10; - if (arg_directory && arg_file) { - log_error("Please specify either -D/--directory= or --file=, not both."); + if (!!arg_directory + !!arg_file + !!arg_machine > 1) { + log_error("Please specify either -D/--directory= or --file= or -M/--machine=, not more than one."); return -EINVAL; } @@ -881,7 +888,7 @@ static int add_boot(sd_journal *j) { return 0; if (!arg_boot_descriptor) - return add_match_this_boot(j); + return add_match_this_boot(j, arg_machine); if (strlen(arg_boot_descriptor) >= 32) { char tmp = arg_boot_descriptor[32]; @@ -1460,6 +1467,8 @@ int main(int argc, char *argv[]) { r = sd_journal_open_directory(&j, arg_directory, arg_journal_type); else if (arg_file) r = sd_journal_open_files(&j, (const char**) arg_file, 0); + else if (arg_machine) + r = sd_journal_open_container(&j, arg_machine, 0); else r = sd_journal_open(&j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type); if (r < 0) { diff --git a/src/journal/libsystemd-journal.sym b/src/journal/libsystemd-journal.sym index 4eb15910d2..7f10f633f6 100644 --- a/src/journal/libsystemd-journal.sym +++ b/src/journal/libsystemd-journal.sym @@ -109,3 +109,8 @@ LIBSYSTEMD_JOURNAL_205 { global: sd_journal_open_files; } LIBSYSTEMD_JOURNAL_202; + +LIBSYSTEMD_JOURNAL_209 { +global: + sd_journal_open_container; +} LIBSYSTEMD_JOURNAL_205; diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 2ba7ca4559..b55cf37e50 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -41,6 +41,7 @@ #include "missing.h" #include "catalog.h" #include "replace-var.h" +#include "fileio.h" #define JOURNAL_FILES_MAX 1024 @@ -1465,7 +1466,7 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname) return 0; } -static int add_root_directory(sd_journal *j, const char *p) { +static int add_root_directory(sd_journal *j, const char *p, const char *prefix) { _cleanup_closedir_ DIR *d = NULL; Directory *m; int r; @@ -1477,6 +1478,9 @@ static int add_root_directory(sd_journal *j, const char *p) { !path_startswith(p, "/run")) return -EINVAL; + if (prefix) + p = strappenda(prefix, p); + d = opendir(p); if (!d) return -errno; @@ -1576,7 +1580,7 @@ static int remove_directory(sd_journal *j, Directory *d) { return 0; } -static int add_search_paths(sd_journal *j) { +static int add_search_paths(sd_journal *j, const char *prefix) { int r; const char search_paths[] = "/run/log/journal\0" @@ -1589,7 +1593,7 @@ static int add_search_paths(sd_journal *j) { * what's actually accessible, and ignore the rest. */ NULSTR_FOREACH(p, search_paths) { - r = add_root_directory(j, p); + r = add_root_directory(j, p, prefix); if (r < 0 && r != -ENOENT) { r = set_put_error(j, r); if (r < 0) @@ -1619,7 +1623,7 @@ static int add_current_paths(sd_journal *j) { if (!dir) return -ENOMEM; - r = add_root_directory(j, dir); + r = add_root_directory(j, dir, NULL); if (r < 0) { set_put_error(j, r); return r; @@ -1684,18 +1688,13 @@ _public_ int sd_journal_open(sd_journal **ret, int flags) { int r; assert_return(ret, -EINVAL); - - if (flags & ~(SD_JOURNAL_LOCAL_ONLY| - SD_JOURNAL_RUNTIME_ONLY| - SD_JOURNAL_SYSTEM| - SD_JOURNAL_CURRENT_USER)) - return -EINVAL; + assert_return((flags & ~(SD_JOURNAL_LOCAL_ONLY|SD_JOURNAL_RUNTIME_ONLY|SD_JOURNAL_SYSTEM|SD_JOURNAL_CURRENT_USER)) == 0, -EINVAL); j = journal_new(flags, NULL); if (!j) return -ENOMEM; - r = add_search_paths(j); + r = add_search_paths(j, NULL); if (r < 0) goto fail; @@ -1708,6 +1707,45 @@ fail: return r; } +_public_ int sd_journal_open_container(sd_journal **ret, const char *machine, int flags) { + _cleanup_free_ char *root = NULL, *class = NULL; + sd_journal *j; + char *p; + int r; + + assert_return(machine, -EINVAL); + assert_return(ret, -EINVAL); + assert_return((flags & ~(SD_JOURNAL_LOCAL_ONLY|SD_JOURNAL_SYSTEM)) == 0, -EINVAL); + assert_return(filename_is_safe(machine), -EINVAL); + + p = strappenda("/run/systemd/machines/", machine); + r = parse_env_file(p, NEWLINE, "ROOT", &root, "CLASS", &class, NULL); + if (r == -ENOENT) + return -EHOSTDOWN; + if (r < 0) + return r; + if (!root) + return -ENODATA; + + if (!streq_ptr(class, "container")) + return -EIO; + + j = journal_new(flags, NULL); + if (!j) + return -ENOMEM; + + r = add_search_paths(j, root); + if (r < 0) + goto fail; + + *ret = j; + return 0; + +fail: + sd_journal_close(j); + return r; +} + _public_ int sd_journal_open_directory(sd_journal **ret, const char *path, int flags) { sd_journal *j; int r; @@ -1720,7 +1758,7 @@ _public_ int sd_journal_open_directory(sd_journal **ret, const char *path, int f if (!j) return -ENOMEM; - r = add_root_directory(j, path); + r = add_root_directory(j, path, NULL); if (r < 0) { set_put_error(j, r); goto fail; @@ -2083,9 +2121,9 @@ _public_ int sd_journal_get_fd(sd_journal *j) { if (j->no_new_files) r = add_current_paths(j); else if (j->path) - r = add_root_directory(j, j->path); + r = add_root_directory(j, j->path, NULL); else - r = add_search_paths(j); + r = add_search_paths(j, NULL); if (r < 0) return r; |