X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fjournal%2Fjournalctl.c;h=af0f4ba3c8b9f289d0d6a35eb4f61d6ed9b08529;hp=86895b8f5b86c7cd3aaec07d356d694b534f102a;hb=3001c74580c1713bd634990a0b2ab351fdec7a98;hpb=ee531d949c2f62374fc109252f8cbe61c2b8ee39 diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 86895b8f5..af0f4ba3c 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -71,6 +71,7 @@ static bool arg_no_tail = false; static bool arg_quiet = false; static bool arg_merge = false; static bool arg_this_boot = false; +static bool arg_dmesg = false; static const char *arg_cursor = NULL; static const char *arg_directory = NULL; static int arg_priorities = 0xFF; @@ -80,11 +81,12 @@ static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC; #endif static usec_t arg_since, arg_until; static bool arg_since_set = false, arg_until_set = false; -static const char *arg_unit = NULL; -static bool arg_unit_system; +static char **arg_system_units = NULL; +static char **arg_user_units = NULL; 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 enum { @@ -104,10 +106,13 @@ static int help(void) { printf("%s [OPTIONS...] [MATCHES...]\n\n" "Query the journal.\n\n" "Flags:\n" + " --system Show only the system journal\n" + " --user Show only the user journal for current user\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" " -b --this-boot Show data only from current boot\n" + " -k --dmesg Show kmsg log from current boot\n" " -u --unit=UNIT Show data only from the specified unit\n" " --user-unit=UNIT Show data only from the specified user session unit\n" " -p --priority=RANGE Show only messages within the specified priority range\n" @@ -156,6 +161,8 @@ static int parse_argv(int argc, char *argv[]) { ARG_NO_PAGER, ARG_NO_TAIL, ARG_NEW_ID128, + ARG_USER, + ARG_SYSTEM, ARG_ROOT, ARG_HEADER, ARG_FULL, @@ -169,7 +176,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_USER_UNIT, ARG_LIST_CATALOG, ARG_DUMP_CATALOG, - ARG_UPDATE_CATALOG + ARG_UPDATE_CATALOG, }; static const struct option options[] = { @@ -187,6 +194,9 @@ static int parse_argv(int argc, char *argv[]) { { "quiet", no_argument, NULL, 'q' }, { "merge", no_argument, NULL, 'm' }, { "this-boot", no_argument, NULL, 'b' }, + { "dmesg", no_argument, NULL, 'k' }, + { "system", no_argument, NULL, ARG_SYSTEM }, + { "user", no_argument, NULL, ARG_USER }, { "directory", required_argument, NULL, 'D' }, { "root", required_argument, NULL, ARG_ROOT }, { "header", no_argument, NULL, ARG_HEADER }, @@ -215,7 +225,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "hefo:an::qmbD:p:c:u:F:xr", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "hefo:an::qmbkD:p:c:u:F:xr", options, NULL)) >= 0) { switch (c) { @@ -317,6 +327,18 @@ static int parse_argv(int argc, char *argv[]) { arg_this_boot = true; break; + case 'k': + arg_this_boot = arg_dmesg = true; + break; + + case ARG_SYSTEM: + arg_journal_type |= SD_JOURNAL_SYSTEM; + break; + + case ARG_USER: + arg_journal_type |= SD_JOURNAL_CURRENT_USER; + break; + case 'D': arg_directory = optarg; break; @@ -437,13 +459,15 @@ static int parse_argv(int argc, char *argv[]) { break; case 'u': - arg_unit = optarg; - arg_unit_system = true; + r = strv_extend(&arg_system_units, optarg); + if (r < 0) + return log_oom(); break; case ARG_USER_UNIT: - arg_unit = optarg; - arg_unit_system = false; + r = strv_extend(&arg_user_units, optarg); + if (r < 0) + return log_oom(); break; case '?': @@ -542,7 +566,7 @@ static int add_matches(sd_journal *j, char **args) { if (streq(*i, "+")) r = sd_journal_add_disjunction(j); else if (path_is_absolute(*i)) { - char _cleanup_free_ *p, *t = NULL; + _cleanup_free_ char *p, *t = NULL; const char *path; struct stat st; @@ -582,48 +606,67 @@ static int add_matches(sd_journal *j, char **args) { } static int add_this_boot(sd_journal *j) { - char match[9+32+1] = "_BOOT_ID="; - sd_id128_t boot_id; - int r; + if (!arg_this_boot) + return 0; + + return add_match_this_boot(j); +} +static int add_dmesg(sd_journal *j) { + int r; assert(j); - if (!arg_this_boot) + if (!arg_dmesg) return 0; - r = sd_id128_get_boot(&boot_id); + r = sd_journal_add_match(j, "_TRANSPORT=kernel", strlen("_TRANSPORT=kernel")); if (r < 0) { - log_error("Failed to get boot id: %s", strerror(-r)); + log_error("Failed to add match: %s", strerror(-r)); return r; } - sd_id128_to_string(boot_id, match + 9); - r = sd_journal_add_match(j, match, strlen(match)); - if (r < 0) { - log_error("Failed to add match: %s", strerror(-r)); + r = sd_journal_add_conjunction(j); + if (r < 0) return r; - } return 0; } -static int add_unit(sd_journal *j) { +static int add_units(sd_journal *j) { _cleanup_free_ char *u = NULL; int r; + char **i; assert(j); - if (isempty(arg_unit)) - return 0; + STRV_FOREACH(i, arg_system_units) { + u = unit_name_mangle(*i); + if (!u) + return log_oom(); + r = add_matches_for_unit(j, u); + if (r < 0) + return r; + r = sd_journal_add_disjunction(j); + if (r < 0) + return r; + } - u = unit_name_mangle(arg_unit); - if (!u) - return log_oom(); + STRV_FOREACH(i, arg_user_units) { + u = unit_name_mangle(*i); + if (!u) + return log_oom(); - if (arg_unit_system) - r = add_matches_for_unit(j, u); - else r = add_matches_for_user_unit(j, u, getuid()); + if (r < 0) + return r; + + r = sd_journal_add_disjunction(j); + if (r < 0) + return r; + + } + + r = sd_journal_add_conjunction(j); if (r < 0) return r; @@ -633,7 +676,6 @@ static int add_unit(sd_journal *j) { static int add_priorities(sd_journal *j) { char match[] = "PRIORITY=0"; int i, r; - assert(j); if (arg_priorities == 0xFF) @@ -650,6 +692,10 @@ static int add_priorities(sd_journal *j) { } } + r = sd_journal_add_conjunction(j); + if (r < 0) + return r; + return 0; } @@ -808,7 +854,7 @@ static int setup_keys(void) { hn = gethostname_malloc(); if (hn) { - hostname_cleanup(hn); + hostname_cleanup(hn, false); fprintf(stderr, "\nThe keys have been generated for host %s/" SD_ID128_FORMAT_STR ".\n", hn, SD_ID128_FORMAT_VAL(machine)); } else fprintf(stderr, "\nThe keys have been generated for host " SD_ID128_FORMAT_STR ".\n", SD_ID128_FORMAT_VAL(machine)); @@ -1001,7 +1047,7 @@ static int access_check(sd_journal *j) { int main(int argc, char *argv[]) { int r; - sd_journal _cleanup_journal_close_ *j = NULL; + _cleanup_journal_close_ sd_journal*j = NULL; bool need_seek = false; sd_id128_t previous_boot_id; bool previous_boot_id_valid = false, first_line = true; @@ -1032,10 +1078,10 @@ int main(int argc, char *argv[]) { arg_action == ACTION_DUMP_CATALOG) { const char* database = CATALOG_DATABASE; - char _cleanup_free_ *copy = NULL; + _cleanup_free_ char *copy = NULL; if (arg_root) { copy = strjoin(arg_root, "/", CATALOG_DATABASE, NULL); - if (!database) { + if (!copy) { r = log_oom(); goto finish; } @@ -1063,9 +1109,9 @@ int main(int argc, char *argv[]) { } if (arg_directory) - r = sd_journal_open_directory(&j, arg_directory, 0); + r = sd_journal_open_directory(&j, arg_directory, arg_journal_type); else - r = sd_journal_open(&j, arg_merge ? 0 : SD_JOURNAL_LOCAL_ONLY); + r = sd_journal_open(&j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type); if (r < 0) { log_error("Failed to open journal: %s", strerror(-r)); return EXIT_FAILURE; @@ -1102,11 +1148,14 @@ int main(int argc, char *argv[]) { if (r < 0) return EXIT_FAILURE; - r = add_unit(j); + r = add_dmesg(j); if (r < 0) return EXIT_FAILURE; - r = add_matches(j, argv + optind); + r = add_units(j); + strv_free(arg_system_units); + strv_free(arg_user_units); + if (r < 0) return EXIT_FAILURE; @@ -1114,6 +1163,10 @@ int main(int argc, char *argv[]) { if (r < 0) return EXIT_FAILURE; + r = add_matches(j, argv + optind); + if (r < 0) + return EXIT_FAILURE; + /* Opening the fd now means the first sd_journal_wait() will actually wait */ r = sd_journal_get_fd(j); if (r < 0) @@ -1123,6 +1176,12 @@ int main(int argc, char *argv[]) { const void *data; size_t size; + r = sd_journal_set_data_threshold(j, 0); + if (r < 0) { + log_error("Failed to unset data size threshold"); + return EXIT_FAILURE; + } + r = sd_journal_query_unique(j, arg_field); if (r < 0) { log_error("Failed to query unique data objects: %s", strerror(-r)); @@ -1244,11 +1303,10 @@ int main(int argc, char *argv[]) { log_error("Failed to iterate through journal: %s", strerror(-r)); goto finish; } + if (r == 0) + break; } - if (r == 0) - break; - if (arg_until_set && !arg_reverse) { usec_t usec; @@ -1275,12 +1333,14 @@ int main(int argc, char *argv[]) { if (!arg_merge) { sd_id128_t boot_id; + const char *color_on = on_tty() ? ANSI_HIGHLIGHT_ON : "", + *color_off = on_tty() ? ANSI_HIGHLIGHT_OFF : ""; r = sd_journal_get_monotonic_usec(j, NULL, &boot_id); if (r >= 0) { if (previous_boot_id_valid && !sd_id128_equal(boot_id, previous_boot_id)) - printf(ANSI_HIGHLIGHT_ON "-- Reboot --" ANSI_HIGHLIGHT_OFF "\n"); + printf("%s-- Reboot --%s\n", color_on, color_off); previous_boot_id = boot_id; previous_boot_id_valid = true; @@ -1294,10 +1354,12 @@ int main(int argc, char *argv[]) { arg_catalog * OUTPUT_CATALOG; r = output_journal(stdout, j, arg_output, 0, flags); - if (r < 0 || ferror(stdout)) + need_seek = true; + if (r == -EADDRNOTAVAIL) + break; + else if (r < 0 || ferror(stdout)) goto finish; - need_seek = true; n_shown++; }