X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=src%2Fjournal%2Fjournalctl.c;h=dee25841e1845e315649cef9a00ee4d34034f65c;hb=c004493cdefc1f43a3956ca529e8070f8d70be56;hp=d2c0a03ccb52dabc11b965ac0dea45074d031cfe;hpb=ae691c1d9382995ea7e28317f5c37023229c27ee;p=thirdparty%2Fsystemd.git diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index d2c0a03ccb5..dee25841e18 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -19,48 +19,49 @@ along with systemd; If not, see . ***/ -#include +#include #include #include -#include +#include +#include +#include +#include +#include #include -#include #include -#include #include -#include -#include -#include -#include +#include #include -#include +#include +#include -#include "sd-journal.h" #include "sd-bus.h" -#include "log.h" -#include "logs-show.h" -#include "util.h" +#include "sd-journal.h" + #include "acl-util.h" -#include "path-util.h" +#include "bus-error.h" +#include "bus-util.h" +#include "catalog.h" +#include "fd-util.h" #include "fileio.h" -#include "build.h" -#include "pager.h" -#include "strv.h" -#include "set.h" -#include "sigbus.h" -#include "journal-internal.h" +#include "fsprg.h" +#include "hostname-util.h" +#include "io-util.h" #include "journal-def.h" -#include "journal-verify.h" +#include "journal-internal.h" #include "journal-qrcode.h" #include "journal-vacuum.h" -#include "fsprg.h" -#include "unit-name.h" -#include "catalog.h" +#include "journal-verify.h" +#include "log.h" +#include "logs-show.h" #include "mkdir.h" -#include "bus-util.h" -#include "bus-error.h" +#include "pager.h" +#include "path-util.h" +#include "set.h" +#include "sigbus.h" +#include "strv.h" #include "terminal-util.h" -#include "hostname-util.h" +#include "unit-name.h" #define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE) @@ -105,10 +106,11 @@ static const char *arg_field = NULL; static bool arg_catalog = false; static bool arg_reverse = false; static int arg_journal_type = 0; -static const char *arg_root = NULL; +static char *arg_root = NULL; static const char *arg_machine = NULL; -static off_t arg_vacuum_size = (off_t) -1; -static usec_t arg_vacuum_time = USEC_INFINITY; +static uint64_t arg_vacuum_size = 0; +static uint64_t arg_vacuum_n_files = 0; +static usec_t arg_vacuum_time = 0; static enum { ACTION_SHOW, @@ -122,6 +124,7 @@ static enum { ACTION_UPDATE_CATALOG, ACTION_LIST_BOOTS, ACTION_FLUSH, + ACTION_ROTATE, ACTION_VACUUM, } arg_action = ACTION_SHOW; @@ -193,8 +196,8 @@ static void help(void) { " --system Show the system journal\n" " --user Show the user journal for the current user\n" " -M --machine=CONTAINER Operate on local container\n" - " --since=DATE Show entries not older than the specified date\n" - " --until=DATE Show entries not newer than the specified date\n" + " -S --since=DATE Show entries not older than the specified date\n" + " -U --until=DATE Show entries not newer than the specified date\n" " -c --cursor=CURSOR Show entries starting at the specified cursor\n" " --after-cursor=CURSOR Show entries after the specified cursor\n" " --show-cursor Print the cursor after all the entries\n" @@ -217,7 +220,7 @@ static void help(void) { " -x --catalog Add message explanations where available\n" " --no-full Ellipsize fields\n" " -a --all Show all fields, including long and unprintable\n" - " -q --quiet Do not show privilege warning\n" + " -q --quiet Do not show info messages and privilege warning\n" " --no-pager Do not pipe output into a pager\n" " -m --merge Show entries from all available journals\n" " -D --directory=PATH Show journal files from directory\n" @@ -235,8 +238,10 @@ static void help(void) { " --new-id128 Generate a new 128-bit ID\n" " --disk-usage Show total disk usage of all journal files\n" " --vacuum-size=BYTES Reduce disk usage below specified size\n" - " --vacuum-time=TIME Remove journal files older than specified date\n" + " --vacuum-files=INT Leave only the specified number of journal files\n" + " --vacuum-time=TIME Remove journal files older than specified time\n" " --flush Flush all journal data from /run into /var\n" + " --rotate Request immediate rotation of the journal files\n" " --header Show journal header information\n" " --list-catalog Show all message IDs in the catalog\n" " --dump-catalog Show entries in the message catalog\n" @@ -267,8 +272,6 @@ static int parse_argv(int argc, char *argv[]) { ARG_VERIFY, ARG_VERIFY_KEY, ARG_DISK_USAGE, - ARG_SINCE, - ARG_UNTIL, ARG_AFTER_CURSOR, ARG_SHOW_CURSOR, ARG_USER_UNIT, @@ -278,7 +281,9 @@ static int parse_argv(int argc, char *argv[]) { ARG_FORCE, ARG_UTC, ARG_FLUSH, + ARG_ROTATE, ARG_VACUUM_SIZE, + ARG_VACUUM_FILES, ARG_VACUUM_TIME, }; @@ -318,8 +323,8 @@ static int parse_argv(int argc, char *argv[]) { { "cursor", required_argument, NULL, 'c' }, { "after-cursor", required_argument, NULL, ARG_AFTER_CURSOR }, { "show-cursor", no_argument, NULL, ARG_SHOW_CURSOR }, - { "since", required_argument, NULL, ARG_SINCE }, - { "until", required_argument, NULL, ARG_UNTIL }, + { "since", required_argument, NULL, 'S' }, + { "until", required_argument, NULL, 'U' }, { "unit", required_argument, NULL, 'u' }, { "user-unit", required_argument, NULL, ARG_USER_UNIT }, { "field", required_argument, NULL, 'F' }, @@ -331,7 +336,9 @@ static int parse_argv(int argc, char *argv[]) { { "machine", required_argument, NULL, 'M' }, { "utc", no_argument, NULL, ARG_UTC }, { "flush", no_argument, NULL, ARG_FLUSH }, + { "rotate", no_argument, NULL, ARG_ROTATE }, { "vacuum-size", required_argument, NULL, ARG_VACUUM_SIZE }, + { "vacuum-files", required_argument, NULL, ARG_VACUUM_FILES }, { "vacuum-time", required_argument, NULL, ARG_VACUUM_TIME }, {} }; @@ -341,7 +348,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:t:u:F:xrM:", options, NULL)) >= 0) + while ((c = getopt_long(argc, argv, "hefo:aln::qmb::kD:p:c:S:U:t:u:F:xrM:", options, NULL)) >= 0) switch (c) { @@ -350,9 +357,7 @@ static int parse_argv(int argc, char *argv[]) { return 0; case ARG_VERSION: - puts(PACKAGE_STRING); - puts(SYSTEMD_FEATURES); - return 0; + return version(); case ARG_NO_PAGER: arg_no_pager = true; @@ -502,7 +507,9 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_ROOT: - arg_root = optarg; + r = parse_path_argument_and_warn(optarg, true, &arg_root); + if (r < 0) + return r; break; case 'c': @@ -539,6 +546,16 @@ static int parse_argv(int argc, char *argv[]) { arg_action = ACTION_VACUUM; break; + case ARG_VACUUM_FILES: + r = safe_atou64(optarg, &arg_vacuum_n_files); + if (r < 0) { + log_error("Failed to parse vacuum files: %s", optarg); + return r; + } + + arg_action = ACTION_VACUUM; + break; + case ARG_VACUUM_TIME: r = parse_sec(optarg, &arg_vacuum_time); if (r < 0) { @@ -631,7 +648,7 @@ static int parse_argv(int argc, char *argv[]) { break; } - case ARG_SINCE: + case 'S': r = parse_timestamp(optarg, &arg_since); if (r < 0) { log_error("Failed to parse timestamp: %s", optarg); @@ -640,7 +657,7 @@ static int parse_argv(int argc, char *argv[]) { arg_since_set = true; break; - case ARG_UNTIL: + case 'U': r = parse_timestamp(optarg, &arg_until); if (r < 0) { log_error("Failed to parse timestamp: %s", optarg); @@ -699,6 +716,10 @@ static int parse_argv(int argc, char *argv[]) { arg_action = ACTION_FLUSH; break; + case ARG_ROTATE: + arg_action = ACTION_ROTATE; + break; + case '?': return -EINVAL; @@ -729,7 +750,7 @@ static int parse_argv(int argc, char *argv[]) { return -EINVAL; } - if (arg_action != ACTION_SHOW && optind < argc) { + if (!IN_SET(arg_action, ACTION_SHOW, ACTION_DUMP_CATALOG, ACTION_LIST_CATALOG) && optind < argc) { log_error("Extraneous arguments starting with '%s'", argv[optind]); return -EINVAL; } @@ -1259,8 +1280,7 @@ static int add_units(sd_journal *j) { } } - strv_free(patterns); - patterns = NULL; + patterns = strv_free(patterns); STRV_FOREACH(i, arg_user_units) { _cleanup_free_ char *u = NULL; @@ -1429,8 +1449,7 @@ static int setup_keys(void) { fd = open("/dev/random", O_RDONLY|O_CLOEXEC|O_NOCTTY); if (fd < 0) { - log_error_errno(errno, "Failed to open /dev/random: %m"); - r = -errno; + r = log_error_errno(errno, "Failed to open /dev/random: %m"); goto finish; } @@ -1455,8 +1474,7 @@ static int setup_keys(void) { safe_close(fd); fd = mkostemp_safe(k, O_WRONLY|O_CLOEXEC); if (fd < 0) { - log_error_errno(errno, "Failed to open %s: %m", k); - r = -errno; + r = log_error_errno(errno, "Failed to open %s: %m", k); goto finish; } @@ -1489,23 +1507,22 @@ static int setup_keys(void) { } if (link(k, p) < 0) { - log_error_errno(errno, "Failed to link file: %m"); - r = -errno; + r = log_error_errno(errno, "Failed to link file: %m"); goto finish; } if (on_tty()) { fprintf(stderr, "\n" - "The new key pair has been generated. The " ANSI_HIGHLIGHT_ON "secret sealing key" ANSI_HIGHLIGHT_OFF " has been written to\n" + "The new key pair has been generated. The " ANSI_HIGHLIGHT "secret sealing key" ANSI_NORMAL " has been written to\n" "the following local file. This key file is automatically updated when the\n" "sealing key is advanced. It should not be used on multiple hosts.\n" "\n" "\t%s\n" "\n" - "Please write down the following " ANSI_HIGHLIGHT_ON "secret verification key" ANSI_HIGHLIGHT_OFF ". It should be stored\n" + "Please write down the following " ANSI_HIGHLIGHT "secret verification key" ANSI_NORMAL ". It should be stored\n" "at a safe location and should not be saved locally on disk.\n" - "\n\t" ANSI_HIGHLIGHT_RED_ON, p); + "\n\t" ANSI_HIGHLIGHT_RED, p); fflush(stderr); } for (i = 0; i < seed_size; i++) { @@ -1520,7 +1537,7 @@ static int setup_keys(void) { char tsb[FORMAT_TIMESPAN_MAX], *hn; fprintf(stderr, - ANSI_HIGHLIGHT_OFF "\n" + ANSI_NORMAL "\n" "The sealing key is automatically changed every %s.\n", format_timespan(tsb, sizeof(tsb), arg_interval, 0)); @@ -1584,7 +1601,7 @@ static int verify(sd_journal *j) { /* If the key was invalid give up right-away. */ return k; } else if (k < 0) { - log_warning("FAIL: %s (%s)", f->path, strerror(-k)); + log_warning_errno(k, "FAIL: %s (%m)", f->path); r = k; } else { char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX], c[FORMAT_TIMESPAN_MAX]; @@ -1729,7 +1746,7 @@ static int flush_to_var(void) { /* OK, let's actually do the full logic, send SIGUSR1 to the * daemon and set up inotify to wait for the flushed file to appear */ - r = bus_open_system_systemd(&bus); + r = bus_connect_system_systemd(&bus); if (r < 0) return log_error_errno(r, "Failed to get D-Bus connection: %m"); @@ -1776,6 +1793,30 @@ static int flush_to_var(void) { return 0; } +static int rotate(void) { + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; + int r; + + r = bus_connect_system_systemd(&bus); + if (r < 0) + return log_error_errno(r, "Failed to get D-Bus connection: %m"); + + r = sd_bus_call_method( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "KillUnit", + &error, + NULL, + "ssi", "systemd-journald.service", "main", SIGUSR2); + if (r < 0) + return log_error_errno(r, "Failed to kill journal service: %s", bus_error_message(&error, r)); + + return 0; +} + int main(int argc, char *argv[]) { int r; _cleanup_journal_close_ sd_journal *j = NULL; @@ -1811,6 +1852,11 @@ int main(int argc, char *argv[]) { goto finish; } + if (arg_action == ACTION_ROTATE) { + r = rotate(); + goto finish; + } + if (arg_action == ACTION_SETUP_KEYS) { r = setup_keys(); goto finish; @@ -1835,6 +1881,7 @@ int main(int argc, char *argv[]) { } else { bool oneline = arg_action == ACTION_LIST_CATALOG; + pager_open_if_enabled(); if (optind < argc) r = catalog_list_items(stdout, database, oneline, argv + optind); @@ -1899,9 +1946,9 @@ int main(int argc, char *argv[]) { if (d->is_root) continue; - q = journal_directory_vacuum(d->path, arg_vacuum_size, arg_vacuum_time, NULL, true); + q = journal_directory_vacuum(d->path, arg_vacuum_size, arg_vacuum_n_files, arg_vacuum_time, NULL, true); if (q < 0) { - log_error_errno(q, "Failed to vacuum: %m"); + log_error_errno(q, "Failed to vacuum %s: %m", d->path); r = q; } } @@ -2067,8 +2114,12 @@ int main(int argc, char *argv[]) { goto finish; } if (r == 0) { - printf("-- No entries --\n"); - goto finish; + if (arg_follow) + need_seek = true; + else { + printf("-- No entries --\n"); + goto finish; + } } if (!arg_follow) @@ -2144,7 +2195,7 @@ int main(int argc, char *argv[]) { if (previous_boot_id_valid && !sd_id128_equal(boot_id, previous_boot_id)) printf("%s-- Reboot --%s\n", - ansi_highlight(), ansi_highlight_off()); + ansi_highlight(), ansi_normal()); previous_boot_id = boot_id; previous_boot_id_valid = true; @@ -2200,5 +2251,7 @@ finish: strv_free(arg_system_units); strv_free(arg_user_units); + free(arg_root); + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; }