From db91ea32aa223d1b087d99811226a9c59a1bb281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 9 Jan 2013 19:14:32 -0500 Subject: journald: use automatic cleanup --- src/journal/journald-server.c | 96 ++++++++++++------------------------------- 1 file changed, 26 insertions(+), 70 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 43ffe75560..60e5a913a7 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -91,13 +91,14 @@ DEFINE_STRING_TABLE_LOOKUP(split_mode, SplitMode); DEFINE_CONFIG_PARSE_ENUM(config_parse_split_mode, split_mode, SplitMode, "Failed to parse split mode setting"); static uint64_t available_space(Server *s) { - char ids[33], *p; + char ids[33]; + char _cleanup_free_ *p = NULL; const char *f; sd_id128_t machine; struct statvfs ss; uint64_t sum = 0, avail = 0, ss_avail = 0; int r; - DIR *d; + DIR _cleanup_closedir_ *d = NULL; usec_t ts; JournalMetrics *m; @@ -125,13 +126,11 @@ static uint64_t available_space(Server *s) { return 0; d = opendir(p); - free(p); - if (!d) return 0; if (fstatvfs(dirfd(d), &ss) < 0) - goto finish; + return 0; for (;;) { struct stat st; @@ -170,9 +169,6 @@ static uint64_t available_space(Server *s) { s->cached_available_space = avail; s->cached_available_space_timestamp = ts; -finish: - closedir(d); - return avail; } @@ -396,7 +392,8 @@ void server_vacuum(Server *s) { static char *shortened_cgroup_path(pid_t pid) { int r; - char *process_path, *init_path, *path; + char _cleanup_free_ *process_path = NULL, *init_path = NULL; + char *path; assert(pid > 0); @@ -405,10 +402,8 @@ static char *shortened_cgroup_path(pid_t pid) { return NULL; r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &init_path); - if (r < 0) { - free(process_path); + if (r < 0) return NULL; - } if (endswith(init_path, "/system")) init_path[strlen(init_path) - 7] = 0; @@ -416,23 +411,12 @@ static char *shortened_cgroup_path(pid_t pid) { init_path[0] = 0; if (startswith(process_path, init_path)) { - char *p; - - p = strdup(process_path + strlen(init_path)); - if (!p) { - free(process_path); - free(init_path); - return NULL; - } - path = p; + path = strdup(process_path + strlen(init_path)); } else { path = process_path; process_path = NULL; } - free(process_path); - free(init_path); - return path; } @@ -519,7 +503,7 @@ static void dispatch_message_real( const char *label, size_t label_len, const char *unit_id) { - char *pid = NULL, *uid = NULL, *gid = NULL, + char _cleanup_free_ *pid = NULL, *uid = NULL, *gid = NULL, *source_time = NULL, *boot_id = NULL, *machine_id = NULL, *comm = NULL, *cmdline = NULL, *hostname = NULL, *audit_session = NULL, *audit_loginuid = NULL, @@ -679,24 +663,6 @@ static void dispatch_message_real( s->split_mode == SPLIT_NONE ? 0 : (s->split_mode == SPLIT_UID ? realuid : (realuid == 0 ? 0 : loginuid)), iovec, n); - - free(pid); - free(uid); - free(gid); - free(comm); - free(exe); - free(cmdline); - free(source_time); - free(boot_id); - free(machine_id); - free(hostname); - free(audit_session); - free(audit_loginuid); - free(cgroup); - free(session); - free(owner_uid); - free(unit); - free(selinux_context); } void server_driver_message(Server *s, sd_id128_t message_id, const char *format, ...) { @@ -744,7 +710,8 @@ void server_dispatch_message( int priority) { int rl; - char *path = NULL, *c; + char _cleanup_free_ *path = NULL; + char *c; assert(s); assert(iovec || n == 0); @@ -778,18 +745,16 @@ void server_dispatch_message( } } - rl = journal_rate_limit_test(s->rate_limit, path, priority & LOG_PRIMASK, available_space(s)); + rl = journal_rate_limit_test(s->rate_limit, path, + priority & LOG_PRIMASK, available_space(s)); - if (rl == 0) { - free(path); + if (rl == 0) return; - } /* Write a suppression message if we suppressed something */ if (rl > 1) - server_driver_message(s, SD_MESSAGE_JOURNAL_DROPPED, "Suppressed %u messages from %s", rl - 1, path); - - free(path); + server_driver_message(s, SD_MESSAGE_JOURNAL_DROPPED, + "Suppressed %u messages from %s", rl - 1, path); finish: dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len, unit_id); @@ -1234,7 +1199,8 @@ static int open_signalfd(Server *s) { } static int server_parse_proc_cmdline(Server *s) { - char *line, *w, *state; + char _cleanup_free_ *line = NULL; + char *w, *state; int r; size_t l; @@ -1248,13 +1214,11 @@ static int server_parse_proc_cmdline(Server *s) { } FOREACH_WORD_QUOTED(w, l, line, state) { - char *word; + char _cleanup_free_ *word; word = strndup(w, l); - if (!word) { - r = -ENOMEM; - goto finish; - } + if (!word) + return -ENOMEM; if (startswith(word, "systemd.journald.forward_to_syslog=")) { r = parse_boolean(word + 35); @@ -1276,25 +1240,18 @@ static int server_parse_proc_cmdline(Server *s) { s->forward_to_console = r; } else if (startswith(word, "systemd.journald")) log_warning("Invalid systemd.journald parameter. Ignoring."); - - free(word); } - r = 0; - -finish: - free(line); - return r; + return 0; } static int server_parse_config_file(Server *s) { - FILE *f; - const char *fn; + static const char *fn = "/etc/systemd/journald.conf"; + FILE _cleanup_fclose_ *f = NULL; int r; assert(s); - fn = "/etc/systemd/journald.conf"; f = fopen(fn, "re"); if (!f) { if (errno == ENOENT) @@ -1304,12 +1261,11 @@ static int server_parse_config_file(Server *s) { return -errno; } - r = config_parse(fn, f, "Journal\0", config_item_perf_lookup, (void*) journald_gperf_lookup, false, s); + r = config_parse(fn, f, "Journal\0", config_item_perf_lookup, + (void*) journald_gperf_lookup, false, s); if (r < 0) log_warning("Failed to parse configuration file: %s", strerror(-r)); - fclose(f); - return r; } -- cgit v1.2.1 From 244692cbfb46df5ff79d07da8fb848a1165bd2fb Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 13 Jan 2013 12:28:38 +0100 Subject: journalctl: quit on I/O error This makes journalctl quit on ferror() conditions on stdout. It fixes an annoying bug if you pipe its output through 'less' and press 'q'. Without this fix journalctl will continue reading all journal data until EOF which can take quite some time. For instance on my machine: david-nb ~ # time journalctl | wc -l 327240 real 1m13.039s user 1m0.217s sys 0m10.467s However, expected behavior is journalctl to quit when its pager closed the output pipe. Signed-off-by: David Herrmann --- src/journal/journalctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index a74d43be7f..45543a5013 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -1077,7 +1077,7 @@ int main(int argc, char *argv[]) { arg_catalog * OUTPUT_CATALOG; r = output_journal(stdout, j, arg_output, 0, flags); - if (r < 0) + if (r < 0 || ferror(stdout)) goto finish; need_seek = true; -- cgit v1.2.1 From 9bdbc2e2ec523dbefe1c1c7e164b5544aff0b185 Mon Sep 17 00:00:00 2001 From: Lukas Nykryn Date: Mon, 14 Jan 2013 18:16:50 +0100 Subject: systemctl,loginctl,cgls: do not ellipsize cgroup members when --full is specified New file output.h with output flags and modes. --full parameter also for cgls and loginctl. Include 'all' parameter in flags (show_cgroup_by_path, show_cgroup, show_cgroup_and_extra, show_cgroup_and_extra_by_spec). get_process_cmdline with max_length == 0 will not ellipsize output. Replace LINE_MAX with 0 in some calls of get_process_cmdline. [zj: Default to --full when under pager for clgs. Drop '-f' since it wasn't documented and didn't actually work. Reindent a bit. ] --- src/journal/coredump.c | 2 +- src/journal/journald-server.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/journal') diff --git a/src/journal/coredump.c b/src/journal/coredump.c index a507fc65f8..c989be9b82 100644 --- a/src/journal/coredump.c +++ b/src/journal/coredump.c @@ -205,7 +205,7 @@ int main(int argc, char* argv[]) { IOVEC_SET_STRING(iovec[j++], core_exe); } - if (get_process_cmdline(pid, LINE_MAX, false, &t) >= 0) { + if (get_process_cmdline(pid, 0, false, &t) >= 0) { core_cmdline = strappend("COREDUMP_CMDLINE=", t); free(t); diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 60e5a913a7..ec9be65575 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -556,7 +556,7 @@ static void dispatch_message_real( IOVEC_SET_STRING(iovec[n++], exe); } - r = get_process_cmdline(ucred->pid, LINE_MAX, false, &t); + r = get_process_cmdline(ucred->pid, 0, false, &t); if (r >= 0) { cmdline = strappend("_CMDLINE=", t); free(t); -- cgit v1.2.1 From c54ff8e3586adec9e21c525bf0fa1fa0b73006d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 25 Nov 2012 23:21:22 +0100 Subject: journal-gatewayd: unify two code paths In preparation for adding more options, split out the option handling code. --- src/journal/journal-gatewayd.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c index 63d9744776..9c33218822 100644 --- a/src/journal/journal-gatewayd.c +++ b/src/journal/journal-gatewayd.c @@ -879,22 +879,22 @@ int main(int argc, char *argv[]) { } else if (n > 1) { log_error("Can't listen on more than one socket."); goto finish; - } else if (n > 0) { - d = MHD_start_daemon( - MHD_USE_THREAD_PER_CONNECTION|MHD_USE_POLL|MHD_USE_DEBUG, - 19531, - NULL, NULL, - request_handler, NULL, - MHD_OPTION_LISTEN_SOCKET, SD_LISTEN_FDS_START, - MHD_OPTION_NOTIFY_COMPLETED, request_meta_free, NULL, - MHD_OPTION_END); } else { + struct MHD_OptionItem opts[] = { + { MHD_OPTION_NOTIFY_COMPLETED, + (intptr_t) request_meta_free, NULL }, + { MHD_OPTION_END, 0, NULL }, + { MHD_OPTION_END, 0, NULL }}; + if (n > 0) + opts[1] = (struct MHD_OptionItem) + {MHD_OPTION_LISTEN_SOCKET, SD_LISTEN_FDS_START, NULL}; + d = MHD_start_daemon( - MHD_USE_DEBUG|MHD_USE_THREAD_PER_CONNECTION|MHD_USE_POLL, + MHD_USE_THREAD_PER_CONNECTION|MHD_USE_POLL|MHD_USE_DEBUG, 19531, NULL, NULL, request_handler, NULL, - MHD_OPTION_NOTIFY_COMPLETED, request_meta_free, NULL, + MHD_OPTION_ARRAY, opts, MHD_OPTION_END); } -- cgit v1.2.1 From 858634ff0e158757dfd630f4da72e790a42e60dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 25 Nov 2012 23:26:15 +0100 Subject: journal-gatewayd: SSL support For now the certificates are passed around as options to the program. This might not be the most convenient under "production", but makes for fairly easy testing. --- src/journal/journal-gatewayd.c | 120 +++++++++++++++++++++++++++++++++++------ 1 file changed, 105 insertions(+), 15 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c index 9c33218822..6922ebcf9c 100644 --- a/src/journal/journal-gatewayd.c +++ b/src/journal/journal-gatewayd.c @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -32,6 +33,7 @@ #include "sd-daemon.h" #include "logs-show.h" #include "virt.h" +#include "build.h" typedef struct RequestMeta { sd_journal *journal; @@ -859,19 +861,96 @@ static int request_handler( return respond_error(connection, MHD_HTTP_NOT_FOUND, "Not found.\n"); } -int main(int argc, char *argv[]) { - struct MHD_Daemon *d = NULL; - int r = EXIT_FAILURE, n; +static char *key_pem = NULL; +static char *cert_pem = NULL; + +static int parse_argv(int argc, char *argv[]) { + enum { + ARG_VERSION = 0x100, + ARG_KEY, + ARG_CERT, + }; + + int r, c; + + static const struct option options[] = { + { "version", no_argument, NULL, ARG_VERSION }, + { "key", required_argument, NULL, ARG_KEY }, + { "cert", required_argument, NULL, ARG_CERT }, + { NULL, 0, NULL, 0 } + }; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) + switch(c) { + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(SYSTEMD_FEATURES); + return 0; + + case ARG_KEY: + if (key_pem) { + log_error("Key file specified twice"); + return -EINVAL; + } + r = read_full_file(optarg, &key_pem, NULL); + if (r < 0) { + log_error("Failed to read key file: %s", strerror(-r)); + return r; + } + assert(key_pem); + break; - if (argc > 1) { + case ARG_CERT: + if (cert_pem) { + log_error("Certificate file specified twice"); + return -EINVAL; + } + r = read_full_file(optarg, &cert_pem, NULL); + if (r < 0) { + log_error("Failed to read certificate file: %s", strerror(-r)); + return r; + } + assert(cert_pem); + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + + if (optind < argc) { log_error("This program does not take arguments."); - goto finish; + return -EINVAL; + } + + if (!!key_pem != !!cert_pem) { + log_error("Certificate and key files must be specified together"); + return -EINVAL; } + return 1; +} + +int main(int argc, char *argv[]) { + struct MHD_Daemon *d = NULL; + int r, n; + log_set_target(LOG_TARGET_AUTO); log_parse_environment(); log_open(); + r = parse_argv(argc, argv); + if (r < 0) + return EXIT_FAILURE; + if (r == 0) + return EXIT_SUCCESS; + n = sd_listen_fds(1); if (n < 0) { log_error("Failed to determine passed sockets: %s", strerror(-n)); @@ -884,18 +963,29 @@ int main(int argc, char *argv[]) { { MHD_OPTION_NOTIFY_COMPLETED, (intptr_t) request_meta_free, NULL }, { MHD_OPTION_END, 0, NULL }, + { MHD_OPTION_END, 0, NULL }, + { MHD_OPTION_END, 0, NULL }, { MHD_OPTION_END, 0, NULL }}; + int opts_pos = 1; + int flags = MHD_USE_THREAD_PER_CONNECTION|MHD_USE_POLL|MHD_USE_DEBUG; + if (n > 0) - opts[1] = (struct MHD_OptionItem) - {MHD_OPTION_LISTEN_SOCKET, SD_LISTEN_FDS_START, NULL}; - - d = MHD_start_daemon( - MHD_USE_THREAD_PER_CONNECTION|MHD_USE_POLL|MHD_USE_DEBUG, - 19531, - NULL, NULL, - request_handler, NULL, - MHD_OPTION_ARRAY, opts, - MHD_OPTION_END); + opts[opts_pos++] = (struct MHD_OptionItem) + {MHD_OPTION_LISTEN_SOCKET, SD_LISTEN_FDS_START}; + if (key_pem) { + assert(cert_pem); + opts[opts_pos++] = (struct MHD_OptionItem) + {MHD_OPTION_HTTPS_MEM_KEY, 0, key_pem}; + opts[opts_pos++] = (struct MHD_OptionItem) + {MHD_OPTION_HTTPS_MEM_CERT, 0, cert_pem}; + flags |= MHD_USE_SSL; + } + + d = MHD_start_daemon(flags, 19531, + NULL, NULL, + request_handler, NULL, + MHD_OPTION_ARRAY, opts, + MHD_OPTION_END); } if (!d) { -- cgit v1.2.1 From e64690a85772fc77ba9e825333eb1ced5a202ad1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 25 Nov 2012 23:54:31 +0100 Subject: journal-gatewayd: redirect microhttpd messages to journal A prefix ("microhttpd: ") is added to the log lines to make it easy to distinguish the source. --- src/journal/journal-gatewayd.c | 5 ++++- src/journal/microhttpd-util.c | 37 +++++++++++++++++++++++++++++++++++++ src/journal/microhttpd-util.h | 26 ++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/journal/microhttpd-util.c create mode 100644 src/journal/microhttpd-util.h (limited to 'src/journal') diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c index 6922ebcf9c..bb9bd44c7a 100644 --- a/src/journal/journal-gatewayd.c +++ b/src/journal/journal-gatewayd.c @@ -32,6 +32,7 @@ #include "sd-journal.h" #include "sd-daemon.h" #include "logs-show.h" +#include "microhttpd-util.h" #include "virt.h" #include "build.h" @@ -962,11 +963,13 @@ int main(int argc, char *argv[]) { struct MHD_OptionItem opts[] = { { MHD_OPTION_NOTIFY_COMPLETED, (intptr_t) request_meta_free, NULL }, + { MHD_OPTION_EXTERNAL_LOGGER, + (intptr_t) microhttpd_logger, NULL }, { MHD_OPTION_END, 0, NULL }, { MHD_OPTION_END, 0, NULL }, { MHD_OPTION_END, 0, NULL }, { MHD_OPTION_END, 0, NULL }}; - int opts_pos = 1; + int opts_pos = 2; int flags = MHD_USE_THREAD_PER_CONNECTION|MHD_USE_POLL|MHD_USE_DEBUG; if (n > 0) diff --git a/src/journal/microhttpd-util.c b/src/journal/microhttpd-util.c new file mode 100644 index 0000000000..dc91b81bde --- /dev/null +++ b/src/journal/microhttpd-util.c @@ -0,0 +1,37 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 Zbigniew Jędrzejewski-Szmek + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "microhttpd-util.h" +#include "log.h" +#include "macro.h" +#include "util.h" + +void microhttpd_logger(void *arg, const char *fmt, va_list ap) { + char _cleanup_free_ *f; + if (asprintf(&f, "microhttpd: %s", fmt) <= 0) { + log_oom(); + return; + } + log_metav(LOG_INFO, NULL, 0, NULL, f, ap); +} diff --git a/src/journal/microhttpd-util.h b/src/journal/microhttpd-util.h new file mode 100644 index 0000000000..d4fefa72d3 --- /dev/null +++ b/src/journal/microhttpd-util.h @@ -0,0 +1,26 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 Zbigniew Jędrzejewski-Szmek + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#pragma once + +#include + +void microhttpd_logger(void *arg, const char *fmt, va_list ap); -- cgit v1.2.1 From 9775033d260f62869d29654a27113b809a03dad9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 28 Nov 2012 18:00:09 +0100 Subject: journal-gatewayd: always log oom() in addition to returning error --- src/journal/journal-gatewayd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c index bb9bd44c7a..613b5394a8 100644 --- a/src/journal/journal-gatewayd.c +++ b/src/journal/journal-gatewayd.c @@ -110,7 +110,7 @@ static int open_journal(RequestMeta *m) { } -static int respond_oom(struct MHD_Connection *connection) { +static int respond_oom_internal(struct MHD_Connection *connection) { struct MHD_Response *response; const char m[] = "Out of memory.\n"; int ret; @@ -128,6 +128,8 @@ static int respond_oom(struct MHD_Connection *connection) { return ret; } +#define respond_oom(connection) log_oom(), respond_oom_internal(connection) + static int respond_error( struct MHD_Connection *connection, unsigned code, -- cgit v1.2.1 From 8530a1436a50b3cfb6dc6231834bd04f56118d31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 28 Nov 2012 18:32:01 +0100 Subject: journal-gatewayd: allow pipelining The request must not be answered immediately (at first call to response_handler()), but on the second. This is also important for authentication, which cannot be performed on the first call. Before: % wget -O/dev/null -S https://localhost:19531/ --2012-11-28 18:29:43-- https://localhost:19531/ Resolving localhost (localhost)... 127.0.0.1 Connecting to localhost (localhost)|127.0.0.1|:19531... connected. HTTP request sent, awaiting response... HTTP/1.1 301 Moved Permanently Connection: close Content-Length: 87 Location: /browse Content-Type: text/html Date: Wed, 28 Nov 2012 17:29:44 GMT Location: /browse [following] --2012-11-28 18:29:43-- https://localhost:19531/browse Connecting to localhost (localhost)|127.0.0.1|:19531... connected. HTTP request sent, awaiting response... HTTP/1.1 200 OK Connection: close Content-Length: 23260 Content-Type: text/html Date: Wed, 28 Nov 2012 17:29:44 GMT Length: 23260 (23K) [text/html] After: % wget --no-check-certificate -O/dev/null -S https://localhost:19531/ --2012-11-28 18:30:05-- https://localhost:19531/ Resolving localhost (localhost)... 127.0.0.1 Connecting to localhost (localhost)|127.0.0.1|:19531... connected. HTTP request sent, awaiting response... HTTP/1.1 301 Moved Permanently Content-Length: 87 Location: /browse Content-Type: text/html Date: Wed, 28 Nov 2012 17:30:05 GMT Location: /browse [following] --2012-11-28 18:30:05-- https://localhost:19531/browse Reusing existing connection to localhost:19531. HTTP request sent, awaiting response... HTTP/1.1 200 OK Content-Length: 23260 Content-Type: text/html Date: Wed, 28 Nov 2012 17:30:06 GMT Length: 23260 (23K) [text/html] --- src/journal/journal-gatewayd.c | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c index 613b5394a8..23939ccbca 100644 --- a/src/journal/journal-gatewayd.c +++ b/src/journal/journal-gatewayd.c @@ -482,18 +482,14 @@ static int request_parse_arguments( static int request_handler_entries( struct MHD_Connection *connection, - void **connection_cls) { + void *connection_cls) { struct MHD_Response *response; - RequestMeta *m; + RequestMeta *m = connection_cls; int r; assert(connection); - assert(connection_cls); - - m = request_meta(connection_cls); - if (!m) - return respond_oom(connection); + assert(m); r = open_journal(m); if (r < 0) @@ -651,15 +647,11 @@ static int request_handler_fields( void *connection_cls) { struct MHD_Response *response; - RequestMeta *m; + RequestMeta *m = connection_cls; int r; assert(connection); - assert(connection_cls); - - m = request_meta(connection_cls); - if (!m) - return respond_oom(connection); + assert(m); r = open_journal(m); if (r < 0) @@ -750,10 +742,10 @@ static int request_handler_file( static int request_handler_machine( struct MHD_Connection *connection, - void **connection_cls) { + void *connection_cls) { struct MHD_Response *response; - RequestMeta *m; + RequestMeta *m = connection_cls; int r; _cleanup_free_ char* hostname = NULL, *os_name = NULL; uint64_t cutoff_from, cutoff_to, usage; @@ -762,10 +754,7 @@ static int request_handler_machine( const char *v = "bare"; assert(connection); - - m = request_meta(connection_cls); - if (!m) - return respond_oom(connection); + assert(m); r = open_journal(m); if (r < 0) @@ -840,26 +829,33 @@ static int request_handler( void **connection_cls) { assert(connection); + assert(connection_cls); assert(url); assert(method); if (!streq(method, "GET")) return MHD_NO; + if (!*connection_cls) { + if (!request_meta(connection_cls)) + return respond_oom(connection); + return MHD_YES; + } + if (streq(url, "/")) return request_handler_redirect(connection, "/browse"); if (streq(url, "/entries")) - return request_handler_entries(connection, connection_cls); + return request_handler_entries(connection, *connection_cls); if (startswith(url, "/fields/")) - return request_handler_fields(connection, url + 8, connection_cls); + return request_handler_fields(connection, url + 8, *connection_cls); if (streq(url, "/browse")) return request_handler_file(connection, DOCUMENT_ROOT "/browse.html", "text/html"); if (streq(url, "/machine")) - return request_handler_machine(connection, connection_cls); + return request_handler_machine(connection, *connection_cls); return respond_error(connection, MHD_HTTP_NOT_FOUND, "Not found.\n"); } -- cgit v1.2.1 From a93035cee3df135b72b8ff6c1d8361e2e647ed0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 17 Jan 2013 01:53:01 -0500 Subject: journal-gatewayd: return nice error on unsupported methods Returns "HTTP/1.0 406 Not Acceptable" instead of silently closing the connection. --- src/journal/journal-gatewayd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c index 23939ccbca..4a4905dbfb 100644 --- a/src/journal/journal-gatewayd.c +++ b/src/journal/journal-gatewayd.c @@ -834,7 +834,9 @@ static int request_handler( assert(method); if (!streq(method, "GET")) - return MHD_NO; + return respond_error(connection, MHD_HTTP_METHOD_NOT_ACCEPTABLE, + "Unsupported method.\n"); + if (!*connection_cls) { if (!request_meta(connection_cls)) -- cgit v1.2.1 From c3a7cfb7dee251cab01e98a399e7d2a0f787b6b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 18 Jan 2013 01:41:01 -0500 Subject: journal-gatewayd,man: document new HTTPS options --- src/journal/journal-gatewayd.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c index 4a4905dbfb..dfec8352bb 100644 --- a/src/journal/journal-gatewayd.c +++ b/src/journal/journal-gatewayd.c @@ -862,6 +862,19 @@ static int request_handler( return respond_error(connection, MHD_HTTP_NOT_FOUND, "Not found.\n"); } +static int help(void) { + + printf("%s [OPTIONS...] ...\n\n" + "HTTP server for journal events.\n\n" + " -h --help Show this help\n" + " --version Show package version\n" + " --cert=CERT.PEM Specify server certificate in PEM format\n" + " --key=KEY.PEM Specify server key in PEM format\n", + program_invocation_short_name); + + return 0; +} + static char *key_pem = NULL; static char *cert_pem = NULL; @@ -875,6 +888,7 @@ static int parse_argv(int argc, char *argv[]) { int r, c; static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, { "key", required_argument, NULL, ARG_KEY }, { "cert", required_argument, NULL, ARG_CERT }, @@ -884,13 +898,16 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) + while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) switch(c) { case ARG_VERSION: puts(PACKAGE_STRING); puts(SYSTEMD_FEATURES); return 0; + case 'h': + return help(); + case ARG_KEY: if (key_pem) { log_error("Key file specified twice"); -- cgit v1.2.1 From ef1673d16907726d83bdff2e57b5261997a85020 Mon Sep 17 00:00:00 2001 From: Mirco Tischler Date: Thu, 17 Jan 2013 18:55:05 +0100 Subject: journal: log _SYSTEMD_USER_UNIT for user session units --- src/journal/journald-server.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index ec9be65575..12a46e6bd0 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -601,8 +601,15 @@ static void dispatch_message_real( if (cg_pid_get_unit(ucred->pid, &t) >= 0) { unit = strappend("_SYSTEMD_UNIT=", t); free(t); - } else if (unit_id) - unit = strappend("_SYSTEMD_UNIT=", unit_id); + } else if (cg_pid_get_user_unit(ucred->pid, &t) >= 0) { + unit = strappend("_SYSTEMD_USER_UNIT=", t); + free(t); + } else if (unit_id) { + if (session) + unit = strappend("_SYSTEMD_USER_UNIT=", unit_id); + else + unit = strappend("_SYSTEMD_UNIT=", unit_id); + } if (unit) IOVEC_SET_STRING(iovec[n++], unit); -- cgit v1.2.1 From 67e04a486b92fcb656049cb4d6b66148c7d2e61b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 27 Jan 2013 23:53:52 -0500 Subject: journalctl: allow --lines=0 i.e. only new Makes it easier to watch just for new entries. Once scenario is where the user starts 'journalctl -qfn0' to watch for changes during some operation. --- src/journal/journalctl.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 45543a5013..0ec2f331db 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -60,7 +60,7 @@ static bool arg_follow = false; static bool arg_full = false; static bool arg_all = false; static bool arg_no_pager = false; -static unsigned arg_lines = 0; +static int arg_lines = -1; static bool arg_no_tail = false; static bool arg_quiet = false; static bool arg_merge = false; @@ -239,8 +239,8 @@ static int parse_argv(int argc, char *argv[]) { case 'n': if (optarg) { - r = safe_atou(optarg, &arg_lines); - if (r < 0 || arg_lines <= 0) { + r = safe_atoi(optarg, &arg_lines); + if (r < 0 || arg_lines < 0) { log_error("Failed to parse lines '%s'", optarg); return -EINVAL; } @@ -413,7 +413,7 @@ static int parse_argv(int argc, char *argv[]) { } } - if (arg_follow && !arg_no_tail && arg_lines <= 0) + if (arg_follow && !arg_no_tail && arg_lines < 0) arg_lines = 10; if (arg_since_set && arg_until_set && arg_since_set > arg_until_set) { @@ -849,8 +849,8 @@ int main(int argc, char *argv[]) { sd_journal *j = NULL; bool need_seek = false; sd_id128_t previous_boot_id; - bool previous_boot_id_valid = false; - unsigned n_shown = 0; + bool previous_boot_id_valid = false, first_line = true; + int n_shown = 0; setlocale(LC_ALL, ""); log_parse_environment(); @@ -937,6 +937,11 @@ int main(int argc, char *argv[]) { if (r < 0) goto finish; + /* Opening the fd now means the first sd_journal_wait() will actually wait */ + r = sd_journal_get_fd(j); + if (r < 0) + goto finish; + if (arg_field) { const void *data; size_t size; @@ -950,7 +955,7 @@ int main(int argc, char *argv[]) { SD_JOURNAL_FOREACH_UNIQUE(j, data, size) { const void *eq; - if (arg_lines > 0 && n_shown >= arg_lines) + if (arg_lines >= 0 && n_shown >= arg_lines) break; eq = memchr(data, '=', size); @@ -983,7 +988,7 @@ int main(int argc, char *argv[]) { } r = sd_journal_next(j); - } else if (arg_lines > 0) { + } else if (arg_lines >= 0) { r = sd_journal_seek_tail(j); if (r < 0) { log_error("Failed to seek to tail: %s", strerror(-r)); @@ -1032,7 +1037,7 @@ int main(int argc, char *argv[]) { } for (;;) { - while (arg_lines == 0 || arg_follow || n_shown < arg_lines) { + while (arg_lines < 0 || n_shown < arg_lines || (arg_follow && !first_line)) { int flags; if (need_seek) { @@ -1092,6 +1097,8 @@ int main(int argc, char *argv[]) { log_error("Couldn't wait for journal event: %s", strerror(-r)); goto finish; } + + first_line = false; } finish: -- cgit v1.2.1 From f9045468945cd06fad84f9fbf44019c6813fc50a Mon Sep 17 00:00:00 2001 From: Mirco Tischler Date: Mon, 4 Feb 2013 15:13:23 +0100 Subject: journal: log user units for coredumps and show them in systemctl status --- src/journal/coredump.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/journal') diff --git a/src/journal/coredump.c b/src/journal/coredump.c index c989be9b82..91528d3c81 100644 --- a/src/journal/coredump.c +++ b/src/journal/coredump.c @@ -144,11 +144,14 @@ int main(int argc, char* argv[]) { core_unit = strappend("COREDUMP_UNIT=", t); free(t); - - if (core_unit) - IOVEC_SET_STRING(iovec[j++], core_unit); + } else if (cg_pid_get_user_unit(pid, &t) >= 0) { + core_unit = strappend("COREDUMP_USER_UNIT=", t); + free(t); } + if (core_unit) + IOVEC_SET_STRING(iovec[j++], core_unit); + /* OK, now we know it's not the journal, hence make use of * it */ log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); -- cgit v1.2.1 From b7f7c68570b384fceceb82660528e688f207e145 Mon Sep 17 00:00:00 2001 From: Mirco Tischler Date: Tue, 5 Feb 2013 01:43:10 +0100 Subject: coredump: make use of the cleanup macros --- src/journal/coredump.c | 41 ++++++++++------------------------------- 1 file changed, 10 insertions(+), 31 deletions(-) (limited to 'src/journal') diff --git a/src/journal/coredump.c b/src/journal/coredump.c index 91528d3c81..021b4c6651 100644 --- a/src/journal/coredump.c +++ b/src/journal/coredump.c @@ -32,6 +32,7 @@ #include "log.h" #include "util.h" +#include "macro.h" #include "mkdir.h" #include "special.h" #include "cgroup-util.h" @@ -49,8 +50,7 @@ enum { }; static int divert_coredump(void) { - FILE *f; - int r; + _cleanup_fclose_ FILE *f = NULL; log_info("Detected coredump of the journal daemon itself, diverting coredump to /var/lib/systemd/coredump/."); @@ -70,19 +70,16 @@ static int divert_coredump(void) { if (l <= 0) { if (ferror(f)) { log_error("Failed to read coredump: %m"); - r = -errno; - goto finish; + return -errno; } - r = 0; break; } q = fwrite(buffer, 1, l, f); if (q != l) { log_error("Failed to write coredump: %m"); - r = -errno; - goto finish; + return -errno; } } @@ -90,25 +87,23 @@ static int divert_coredump(void) { if (ferror(f)) { log_error("Failed to write coredump: %m"); - r = -errno; + return -errno; } -finish: - fclose(f); - return r; + return 0; } int main(int argc, char* argv[]) { int r, j = 0; - char *p = NULL; + _cleanup_free_ char *p = NULL; ssize_t n; pid_t pid; uid_t uid; gid_t gid; struct iovec iovec[14]; - char *core_pid = NULL, *core_uid = NULL, *core_gid = NULL, *core_signal = NULL, + _cleanup_free_ char *core_pid = NULL, *core_uid = NULL, *core_gid = NULL, *core_signal = NULL, *core_timestamp = NULL, *core_comm = NULL, *core_exe = NULL, *core_unit = NULL, - *core_session = NULL, *core_message = NULL, *core_cmdline = NULL, *t; + *core_session = NULL, *core_message = NULL, *core_cmdline = NULL, *t = NULL; prctl(PR_SET_DUMPABLE, 0); @@ -143,11 +138,8 @@ int main(int argc, char* argv[]) { } core_unit = strappend("COREDUMP_UNIT=", t); - free(t); - } else if (cg_pid_get_user_unit(pid, &t) >= 0) { + } else if (cg_pid_get_user_unit(pid, &t) >= 0) core_unit = strappend("COREDUMP_USER_UNIT=", t); - free(t); - } if (core_unit) IOVEC_SET_STRING(iovec[j++], core_unit); @@ -264,18 +256,5 @@ int main(int argc, char* argv[]) { log_error("Failed to send coredump: %s", strerror(-r)); finish: - free(p); - free(core_pid); - free(core_uid); - free(core_gid); - free(core_signal); - free(core_timestamp); - free(core_comm); - free(core_exe); - free(core_cmdline); - free(core_unit); - free(core_session); - free(core_message); - return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; } -- cgit v1.2.1 From 7850b3b83791ba0e2377ba40383c5abc258b839d Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 8 Feb 2013 10:22:02 +0100 Subject: shared: conf-files - add root parameter --- src/journal/catalog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/catalog.c b/src/journal/catalog.c index 3735ad9213..32256f6263 100644 --- a/src/journal/catalog.c +++ b/src/journal/catalog.c @@ -296,7 +296,7 @@ int catalog_update(void) { goto finish; } - r = conf_files_list_strv(&files, ".catalog", (const char **) conf_file_dirs); + r = conf_files_list_strv(&files, ".catalog", NULL, (const char **) conf_file_dirs); if (r < 0) { log_error("Failed to get catalog files: %s", strerror(-r)); goto finish; -- cgit v1.2.1 From 96088db02b2802049f1edbd44d5f8c2ea838f3f2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 12 Feb 2013 00:31:13 +0100 Subject: journalctl: allow both "-n 55" and "-n55" on the command line, as equivalent syntaxes https://bugs.freedesktop.org/show_bug.cgi?id=60596 --- src/journal/journalctl.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 0ec2f331db..0afeef932e 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -244,8 +244,25 @@ static int parse_argv(int argc, char *argv[]) { log_error("Failed to parse lines '%s'", optarg); return -EINVAL; } - } else - arg_lines = 10; + } else { + int n; + + /* Hmm, no argument? Maybe the next + * word on the command line is + * supposed to be the argument? Let's + * see if there is one, and is + * parsable as a positive + * integer... */ + + if (optind < argc && + safe_atoi(argv[optind], &n) >= 0 && + n >= 0) { + + arg_lines = n; + optind++; + } else + arg_lines = 10; + } break; -- cgit v1.2.1 From 759c945a43577d56e85a927f15e7d9aaa94a4e4a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 12 Feb 2013 12:24:30 -0500 Subject: journal: Don't use loginuid if it's not valid Code above this attempted to load loginuid, if this failed for whatever reason, we'd still end up using that value (0) in place of realuid. Fix this by setting a bool when we know the loginuid is valid. This fixes journal messages showing up in per-user journals in gnome-ostree (not configured with loginuid, but I'll shortly fix that). --- src/journal/journald-server.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 12a46e6bd0..1375d7a98e 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -515,6 +515,8 @@ static void dispatch_message_real( int r; char *t; uid_t loginuid = 0, realuid = 0; + uid_t journal_uid; + bool loginuid_valid = false; assert(s); assert(iovec); @@ -571,9 +573,11 @@ static void dispatch_message_real( IOVEC_SET_STRING(iovec[n++], audit_session); r = audit_loginuid_from_pid(ucred->pid, &loginuid); - if (r >= 0) + if (r >= 0) { + loginuid_valid = true; if (asprintf(&audit_loginuid, "_AUDIT_LOGINUID=%lu", (unsigned long) loginuid) >= 0) IOVEC_SET_STRING(iovec[n++], audit_loginuid); + } t = shortened_cgroup_path(ucred->pid); if (t) { @@ -666,10 +670,14 @@ static void dispatch_message_real( assert(n <= m); - write_to_journal(s, - s->split_mode == SPLIT_NONE ? 0 : - (s->split_mode == SPLIT_UID ? realuid : - (realuid == 0 ? 0 : loginuid)), iovec, n); + if (s->split_mode == SPLIT_NONE) + journal_uid = 0; + else if (s->split_mode == SPLIT_UID || realuid == 0 || !loginuid_valid) + journal_uid = realuid; + else + journal_uid = loginuid; + + write_to_journal(s, journal_uid, iovec, n); } void server_driver_message(Server *s, sd_id128_t message_id, const char *format, ...) { -- cgit v1.2.1 From 090be8653471e1abe3f1cdd32eaad0fbd65f85cd Mon Sep 17 00:00:00 2001 From: Thomas Hindoe Paaboel Andersen Date: Wed, 13 Feb 2013 18:13:22 +0100 Subject: use streq instead of strcmp --- src/journal/test-journal-syslog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/journal') diff --git a/src/journal/test-journal-syslog.c b/src/journal/test-journal-syslog.c index 3ae8633f22..5cf940733b 100644 --- a/src/journal/test-journal-syslog.c +++ b/src/journal/test-journal-syslog.c @@ -31,8 +31,8 @@ static void test_syslog_parse_identifier(const char* str, ret2 = syslog_parse_identifier(&buf, &ident2, &pid2); assert(ret == ret2); - assert(ident==ident2 || !strcmp(ident, ident2)); - assert(pid==pid2 || !strcmp(pid, pid2)); + assert(ident==ident2 || streq(ident, ident2)); + assert(pid==pid2 || streq(pid, pid2)); } int main(void) { -- cgit v1.2.1 From a5c32cff1f56afe6f0c6c70d91a88a7a8238b2d7 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Thu, 14 Feb 2013 12:26:13 +0100 Subject: honor SELinux labels, when creating and writing config files Also split out some fileio functions to fileio.c and provide a SELinux aware pendant in fileio-label.c see https://bugzilla.redhat.com/show_bug.cgi?id=881577 --- src/journal/journald-server.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/journal') diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 1375d7a98e..818bd0803a 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -34,6 +34,7 @@ #include #endif +#include "fileio.h" #include "mkdir.h" #include "hashmap.h" #include "journal-file.h" -- cgit v1.2.1 From a860325e7ed7ea2bd688b2f002021123a05af084 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Thu, 14 Feb 2013 16:37:31 +0100 Subject: added some missing include for a5c32cff1f56afe6f0c6c70d91a88a7a8238b2d7 --- src/journal/journal-gatewayd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/journal') diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c index dfec8352bb..7e29c905e2 100644 --- a/src/journal/journal-gatewayd.c +++ b/src/journal/journal-gatewayd.c @@ -35,6 +35,7 @@ #include "microhttpd-util.h" #include "virt.h" #include "build.h" +#include "fileio.h" typedef struct RequestMeta { sd_journal *journal; -- cgit v1.2.1 From 6f47ad30250cf467065a19105013321ee4973694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 22 Feb 2013 11:18:46 +0100 Subject: journal: sd_journal_get_cursor should return 0 on success Documentation states that 0 is correct, and all other similar functions return 0 on success. Pointed-out-by: Steven Hiscocks --- src/journal/sd-journal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 095fbb249c..8904560094 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -958,7 +958,7 @@ _public_ int sd_journal_get_cursor(sd_journal *j, char **cursor) { (unsigned long long) le64toh(o->entry.xor_hash)) < 0) return -ENOMEM; - return 1; + return 0; } _public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) { -- cgit v1.2.1 From d489071fb348cd180bc4f70e732b0e76d9804448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 10 Feb 2013 22:47:14 -0500 Subject: journalct: also print Python code in --new-id --- src/journal/journalctl.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 0afeef932e..0de159b89a 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -462,14 +462,17 @@ static int generate_new_id128(void) { "As UUID:\n" "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n\n" "As macro:\n" - "#define MESSAGE_XYZ SD_ID128_MAKE(", + "#define MESSAGE_XYZ SD_ID128_MAKE(", SD_ID128_FORMAT_VAL(id), SD_ID128_FORMAT_VAL(id)); - for (i = 0; i < 16; i++) printf("%02x%s", id.bytes[i], i != 15 ? "," : ""); + fputs(")\n\n", stdout); - fputs(")\n", stdout); + printf("As Python constant:\n" + ">>> import uuid\n" + ">>> MESSAGE_XYZ = uuid.UUID('" SD_ID128_FORMAT_STR "')\n", + SD_ID128_FORMAT_VAL(id)); return 0; } -- cgit v1.2.1 From 3ba09ee8eb9453daf9228f612c9bcd59905fcf05 Mon Sep 17 00:00:00 2001 From: "Paul W. Frields" Date: Sun, 24 Feb 2013 15:27:51 +0100 Subject: journal: fix --until https://bugs.freedesktop.org/show_bug.cgi?id=58946 --- src/journal/journalctl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 0afeef932e..0b3a79bee9 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -433,7 +433,7 @@ static int parse_argv(int argc, char *argv[]) { if (arg_follow && !arg_no_tail && arg_lines < 0) arg_lines = 10; - if (arg_since_set && arg_until_set && arg_since_set > arg_until_set) { + if (arg_since_set && arg_until_set && arg_since > arg_until) { log_error("--since= must be before --until=."); return -EINVAL; } @@ -1076,6 +1076,8 @@ int main(int argc, char *argv[]) { log_error("Failed to determine timestamp: %s", strerror(-r)); goto finish; } + if (usec > arg_until) + goto finish; } if (!arg_merge) { -- cgit v1.2.1 From d95b1fb315f62313be5bee5bee3b2d1467868a7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 25 Feb 2013 05:51:41 +0100 Subject: log-show: look at everything in /run/log/journal Logs written by journald from the initramfs may be written to a directory with the name created from a random machine-id. Afterwards, when the root filesystem has been mounted and machine-id reinitalized, logs will be written to the directory with a name created from the proper machine-id. When logs are flushed to /var/log/journal, everything is copied to one output directory. When journalctl without '-m' is run after the logs have been flushed to /var/log/journal, all messages are shown. However, when run while logs are still in /run/log/journal, those stored under the random machine-id will not be shown. Make journalctl behave the same regardless whether persistent storage has been enabled or not, and slurp all files from /run/log/journal even without '-m'. --- src/journal/sd-journal.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 8904560094..19123544b3 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -1321,10 +1321,12 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname) assert(prefix); assert(dirname); + log_debug("Considering %s/%s.", prefix, dirname); + if ((j->flags & SD_JOURNAL_LOCAL_ONLY) && (sd_id128_from_string(dirname, &id) < 0 || sd_id128_get_machine(&mid) < 0 || - !sd_id128_equal(id, mid))) + !(sd_id128_equal(id, mid) || path_startswith(prefix, "/run")))) return 0; path = strjoin(prefix, "/", dirname, NULL); -- cgit v1.2.1 From d89d6c86d9f141e0fb6939b7fc4f5ea068750690 Mon Sep 17 00:00:00 2001 From: Lukas Nykryn Date: Fri, 1 Mar 2013 10:27:10 +0100 Subject: journalctl: add --reverse option to show the newest lines first --- src/journal/journalctl.c | 58 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 6 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 9084509704..4c9862fa6c 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -77,6 +77,7 @@ static bool arg_since_set = false, arg_until_set = false; static const char *arg_unit = NULL; static const char *arg_field = NULL; static bool arg_catalog = false; +static bool arg_reverse = false; static enum { ACTION_SHOW, @@ -103,6 +104,7 @@ static int help(void) { " -f --follow Follow journal\n" " -n --lines[=INTEGER] Number of journal entries to show\n" " --no-tail Show all lines, even in follow mode\n" + " -r --reverse Show the newest entries first\n" " -o --output=STRING Change journal output mode (short, short-monotonic,\n" " verbose, export, json, json-pretty, json-sse, cat)\n" " -x --catalog Add message explanations where available\n" @@ -184,6 +186,7 @@ static int parse_argv(int argc, char *argv[]) { { "catalog", no_argument, NULL, 'x' }, { "list-catalog", no_argument, NULL, ARG_LIST_CATALOG }, { "update-catalog",no_argument, NULL, ARG_UPDATE_CATALOG }, + { "reverse", no_argument, NULL, 'r' }, { NULL, 0, NULL, 0 } }; @@ -192,7 +195,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "hfo:an::qmbD:p:c:u:F:x", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "hfo:an::qmbD:p:c:u:F:xr", options, NULL)) >= 0) { switch (c) { @@ -424,6 +427,10 @@ static int parse_argv(int argc, char *argv[]) { arg_action = ACTION_UPDATE_CATALOG; break; + case 'r': + arg_reverse = true; + break; + default: log_error("Unknown option code %c", c); return -EINVAL; @@ -443,6 +450,11 @@ static int parse_argv(int argc, char *argv[]) { return -EINVAL; } + if (arg_follow && arg_reverse) { + log_error("Please specify either --reverse= or --follow=, not both."); + return -EINVAL; + } + return 1; } @@ -997,10 +1009,12 @@ int main(int argc, char *argv[]) { log_error("Failed to seek to cursor: %s", strerror(-r)); goto finish; } + if (!arg_reverse) + r = sd_journal_next(j); + else + r = sd_journal_previous(j); - r = sd_journal_next(j); - - } else if (arg_since_set) { + } else if (arg_since_set && !arg_reverse) { r = sd_journal_seek_realtime_usec(j, arg_since); if (r < 0) { log_error("Failed to seek to date: %s", strerror(-r)); @@ -1008,6 +1022,14 @@ int main(int argc, char *argv[]) { } r = sd_journal_next(j); + } else if (arg_until_set && arg_reverse) { + r = sd_journal_seek_realtime_usec(j, arg_until); + if (r < 0) { + log_error("Failed to seek to date: %s", strerror(-r)); + goto finish; + } + r = sd_journal_previous(j); + } else if (arg_lines >= 0) { r = sd_journal_seek_tail(j); if (r < 0) { @@ -1017,6 +1039,15 @@ int main(int argc, char *argv[]) { r = sd_journal_previous_skip(j, arg_lines); + } else if (arg_reverse) { + r = sd_journal_seek_tail(j); + if (r < 0) { + log_error("Failed to seek to tail: %s", strerror(-r)); + goto finish; + } + + r = sd_journal_previous(j); + } else { r = sd_journal_seek_head(j); if (r < 0) { @@ -1061,7 +1092,10 @@ int main(int argc, char *argv[]) { int flags; if (need_seek) { - r = sd_journal_next(j); + if(!arg_reverse) + r = sd_journal_next(j); + else + r = sd_journal_previous(j); if (r < 0) { log_error("Failed to iterate through journal: %s", strerror(-r)); goto finish; @@ -1071,7 +1105,7 @@ int main(int argc, char *argv[]) { if (r == 0) break; - if (arg_until_set) { + if (arg_until_set && !arg_reverse) { usec_t usec; r = sd_journal_get_realtime_usec(j, &usec); @@ -1083,6 +1117,18 @@ int main(int argc, char *argv[]) { goto finish; } + if (arg_since_set && arg_reverse) { + usec_t usec; + + r = sd_journal_get_realtime_usec(j, &usec); + if (r < 0) { + log_error("Failed to determine timestamp: %s", strerror(-r)); + goto finish; + } + if (usec < arg_since) + goto finish; + } + if (!arg_merge) { sd_id128_t boot_id; -- cgit v1.2.1 From ffa7cd15cd2a9e802827ef0f5762de6c22933c07 Mon Sep 17 00:00:00 2001 From: Daniel Wallace Date: Fri, 1 Mar 2013 14:39:04 +0100 Subject: journalctl: add --user-unit= switch Add --user-unit= to make it possible to query for user logs by the name of the service. --- src/journal/journalctl.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 4c9862fa6c..d898ae7179 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -75,6 +75,7 @@ static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC; static usec_t arg_since, arg_until; static bool arg_since_set = false, arg_until_set = false; static const char *arg_unit = NULL; +static const char *arg_unit_type = NULL; static const char *arg_field = NULL; static bool arg_catalog = false; static bool arg_reverse = false; @@ -100,6 +101,7 @@ static int help(void) { " -c --cursor=CURSOR Start showing entries from specified cursor\n" " -b --this-boot Show data only 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" " -f --follow Follow journal\n" " -n --lines[=INTEGER] Number of journal entries to show\n" @@ -152,6 +154,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_DISK_USAGE, ARG_SINCE, ARG_UNTIL, + ARG_USER_UNIT, ARG_LIST_CATALOG, ARG_UPDATE_CATALOG }; @@ -181,6 +184,7 @@ static int parse_argv(int argc, char *argv[]) { { "cursor", required_argument, NULL, 'c' }, { "since", required_argument, NULL, ARG_SINCE }, { "until", required_argument, NULL, ARG_UNTIL }, + { "user-unit", required_argument, NULL, ARG_USER_UNIT }, { "unit", required_argument, NULL, 'u' }, { "field", required_argument, NULL, 'F' }, { "catalog", no_argument, NULL, 'x' }, @@ -404,8 +408,14 @@ static int parse_argv(int argc, char *argv[]) { arg_until_set = true; break; + case ARG_USER_UNIT: + arg_unit = optarg; + arg_unit_type = "_SYSTEMD_USER_UNIT="; + break; + case 'u': arg_unit = optarg; + arg_unit_type = "_SYSTEMD_UNIT="; break; case '?': @@ -583,7 +593,8 @@ static int add_unit(sd_journal *j) { if (!u) return log_oom(); - m = strappend("_SYSTEMD_UNIT=", u); + m = strappend(arg_unit_type, u); + if (!m) return log_oom(); -- cgit v1.2.1 From 41be2ca14d34b67776240bc67facf341b156b974 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 1 Mar 2013 15:19:00 +0100 Subject: coredump: bump coredump truncation size from 24M to 768M In the long run we really should make this runtime configurable. --- src/journal/coredump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/coredump.c b/src/journal/coredump.c index 021b4c6651..bada8487c4 100644 --- a/src/journal/coredump.c +++ b/src/journal/coredump.c @@ -37,7 +37,7 @@ #include "special.h" #include "cgroup-util.h" -#define COREDUMP_MAX (24*1024*1024) +#define COREDUMP_MAX (768*1024*1024) enum { ARG_PID = 1, -- cgit v1.2.1 From d288f79fb4a2fe4a93cf99f74dacd2cebd3f2440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 2 Mar 2013 20:14:21 -0500 Subject: journald: do not barf when setting RateLimitInterval=0 Assertion 'interval > 0 || burst == 0' failed at src/journal/journald-rate-limit.c:78, function journal_rate_limit_new(). Aborting. --- src/journal/journald-server.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 818bd0803a..c8a6285a84 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -1310,6 +1310,12 @@ int server_init(Server *s) { server_parse_config_file(s); server_parse_proc_cmdline(s); + if (!!s->rate_limit_interval ^ !!s->rate_limit_burst) { + log_debug("Setting both rate limit interval and burst from %llu,%u to 0,0", + (long long unsigned) s->rate_limit_interval, + s->rate_limit_burst); + s->rate_limit_interval = s->rate_limit_burst = 0; + } mkdir_p("/run/systemd/journal", 0755); @@ -1396,7 +1402,8 @@ int server_init(Server *s) { if (!s->udev) return -ENOMEM; - s->rate_limit = journal_rate_limit_new(s->rate_limit_interval, s->rate_limit_burst); + s->rate_limit = journal_rate_limit_new(s->rate_limit_interval, + s->rate_limit_burst); if (!s->rate_limit) return -ENOMEM; -- cgit v1.2.1 From da4993920cdf5527b8528f0a483b54ab3cbc1971 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 4 Mar 2013 15:17:45 +0100 Subject: journal: split journal uid only when audit uid data is valid --- src/journal/journald-server.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index c8a6285a84..545760726e 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -671,12 +671,12 @@ static void dispatch_message_real( assert(n <= m); - if (s->split_mode == SPLIT_NONE) - journal_uid = 0; - else if (s->split_mode == SPLIT_UID || realuid == 0 || !loginuid_valid) + if (s->split_mode == SPLIT_UID && realuid > 0) journal_uid = realuid; - else + else if (s->split_mode == SPLIT_LOGIN && loginuid > 0 && loginuid_valid) journal_uid = loginuid; + else + journal_uid = 0; write_to_journal(s, journal_uid, iovec, n); } -- cgit v1.2.1 From 8a0889dfdafa3054c894e54852d8a9e3a7e8390b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 5 Mar 2013 14:23:22 +0100 Subject: journald: check session owner UID rather then audit ID when splitting up journal files We should always go by our own cgroup hierarchy before using foreign schemes such as audit, so let's do that for the split out logic too. --- src/journal/journald-server.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 545760726e..dcfdeaf68e 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -515,9 +515,8 @@ static void dispatch_message_real( sd_id128_t id; int r; char *t; - uid_t loginuid = 0, realuid = 0; - uid_t journal_uid; - bool loginuid_valid = false; + uid_t loginuid = 0, realuid = 0, owner = 0, journal_uid; + bool loginuid_valid = false, owner_valid = false; assert(s); assert(iovec); @@ -526,9 +525,6 @@ static void dispatch_message_real( if (ucred) { uint32_t audit; -#ifdef HAVE_LOGIND - uid_t owner; -#endif realuid = ucred->uid; @@ -598,9 +594,11 @@ static void dispatch_message_real( IOVEC_SET_STRING(iovec[n++], session); } - if (sd_pid_get_owner_uid(ucred->uid, &owner) >= 0) + if (sd_pid_get_owner_uid(ucred->uid, &owner) >= 0) { + owner_valid = true; if (asprintf(&owner_uid, "_SYSTEMD_OWNER_UID=%lu", (unsigned long) owner) >= 0) IOVEC_SET_STRING(iovec[n++], owner_uid); + } #endif if (cg_pid_get_unit(ucred->pid, &t) >= 0) { @@ -673,7 +671,9 @@ static void dispatch_message_real( if (s->split_mode == SPLIT_UID && realuid > 0) journal_uid = realuid; - else if (s->split_mode == SPLIT_LOGIN && loginuid > 0 && loginuid_valid) + else if (s->split_mode == SPLIT_LOGIN && owner_valid && owner > 0) + journal_uid = owner; + else if (s->split_mode == SPLIT_LOGIN && loginuid_valid && loginuid > 0) journal_uid = loginuid; else journal_uid = 0; -- cgit v1.2.1 From 40adcda869bda55f44b57fd3a2bd71d006dfb51b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 5 Mar 2013 14:27:34 +0100 Subject: journald: be a bit more careful when spitting up journals by user id --- src/journal/journald-server.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index dcfdeaf68e..b46a2f63b3 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -670,10 +670,19 @@ static void dispatch_message_real( assert(n <= m); if (s->split_mode == SPLIT_UID && realuid > 0) + /* Split up strictly by any UID */ journal_uid = realuid; - else if (s->split_mode == SPLIT_LOGIN && owner_valid && owner > 0) + else if (s->split_mode == SPLIT_LOGIN && owner_valid && owner > 0 && realuid > 0) + /* Split up by login UIDs, this avoids creation of + * individual journals for system UIDs. We do this + * only if the realuid is not root, in order not to + * accidentally leak privileged information logged by + * a privileged process that is part of an + * unprivileged session to the user. */ journal_uid = owner; - else if (s->split_mode == SPLIT_LOGIN && loginuid_valid && loginuid > 0) + else if (s->split_mode == SPLIT_LOGIN && loginuid_valid && loginuid > 0 && realuid > 0) + /* Hmm, let's try via the audit uids, as fallback, + * just in case */ journal_uid = loginuid; else journal_uid = 0; -- cgit v1.2.1 From 82499507b369fea3033a74c22813bf423301aef4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 5 Mar 2013 14:36:57 +0100 Subject: journald: drop splitting-by-audit entirely Thinking about it we should probably not hide bugs by falling back to audit when we have our own session information anyway. --- src/journal/journald-server.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index b46a2f63b3..c1ec0fad32 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -515,8 +515,8 @@ static void dispatch_message_real( sd_id128_t id; int r; char *t; - uid_t loginuid = 0, realuid = 0, owner = 0, journal_uid; - bool loginuid_valid = false, owner_valid = false; + uid_t realuid = 0, owner = 0, journal_uid; + bool owner_valid = false; assert(s); assert(iovec); @@ -525,6 +525,7 @@ static void dispatch_message_real( if (ucred) { uint32_t audit; + uid_t loginuid; realuid = ucred->uid; @@ -570,11 +571,9 @@ static void dispatch_message_real( IOVEC_SET_STRING(iovec[n++], audit_session); r = audit_loginuid_from_pid(ucred->pid, &loginuid); - if (r >= 0) { - loginuid_valid = true; + if (r >= 0) if (asprintf(&audit_loginuid, "_AUDIT_LOGINUID=%lu", (unsigned long) loginuid) >= 0) IOVEC_SET_STRING(iovec[n++], audit_loginuid); - } t = shortened_cgroup_path(ucred->pid); if (t) { @@ -672,18 +671,14 @@ static void dispatch_message_real( if (s->split_mode == SPLIT_UID && realuid > 0) /* Split up strictly by any UID */ journal_uid = realuid; - else if (s->split_mode == SPLIT_LOGIN && owner_valid && owner > 0 && realuid > 0) + else if (s->split_mode == SPLIT_LOGIN && realuid > 0 && owner_valid && owner > 0) /* Split up by login UIDs, this avoids creation of * individual journals for system UIDs. We do this * only if the realuid is not root, in order not to - * accidentally leak privileged information logged by - * a privileged process that is part of an - * unprivileged session to the user. */ + * accidentally leak privileged information to the + * user that is logged by a privileged process that is + * part of an unprivileged session.*/ journal_uid = owner; - else if (s->split_mode == SPLIT_LOGIN && loginuid_valid && loginuid > 0 && realuid > 0) - /* Hmm, let's try via the audit uids, as fallback, - * just in case */ - journal_uid = loginuid; else journal_uid = 0; -- cgit v1.2.1 From fc7b7e2e74ed0c4ce2bda91d693240c9dcd0d526 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 5 Mar 2013 15:02:38 +0100 Subject: journald: stpcpy() + mempcpy() are awesome --- src/journal/journald-server.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index c1ec0fad32..654f7ace21 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -620,9 +620,7 @@ static void dispatch_message_real( if (label) { selinux_context = malloc(sizeof("_SELINUX_CONTEXT=") + label_len); if (selinux_context) { - memcpy(selinux_context, "_SELINUX_CONTEXT=", sizeof("_SELINUX_CONTEXT=")-1); - memcpy(selinux_context+sizeof("_SELINUX_CONTEXT=")-1, label, label_len); - selinux_context[sizeof("_SELINUX_CONTEXT=")-1+label_len] = 0; + *((char*) mempcpy(stpcpy(selinux_context, "_SELINUX_CONTEXT="), label, label_len)) = 0; IOVEC_SET_STRING(iovec[n++], selinux_context); } } else { @@ -632,7 +630,6 @@ static void dispatch_message_real( selinux_context = strappend("_SELINUX_CONTEXT=", con); if (selinux_context) IOVEC_SET_STRING(iovec[n++], selinux_context); - freecon(con); } } -- cgit v1.2.1 From a24c64f03f9c5c0304451d8542fee853187a5168 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 5 Mar 2013 18:53:21 +0100 Subject: journald: introduce new "systemd-journal" group and make it own the journal files Previously all journal files were owned by "adm". In order to allow specific users to read the journal files without granting it access to the full "adm" powers, introduce a new specific group for this. "systemd-journal" has to be created by the packaging scripts manually at installation time. It's a good idea to assign a static UID/GID to this group, since /var/log/journal might be shared across machines via NFS. This commit also grants read access to the journal files by default to members of the "wheel" and "adm" groups via file system ACLs, since these "almost-root" groups should be able to see what's going on on the system. These ACLs are created by "make install". Packagers probably need to duplicate this logic in their postinst scripts. This also adds documentation how to grant access to the journal to additional users or groups via fs ACLs. --- src/journal/journalctl.c | 12 ++++++------ src/journal/journald-server.c | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index d898ae7179..cb93fea63b 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -870,16 +870,16 @@ static int verify(sd_journal *j) { static int access_check(void) { #ifdef HAVE_ACL - if (access("/var/log/journal", F_OK) < 0 && geteuid() != 0 && in_group("adm") <= 0) { - log_error("Unprivileged users can't see messages unless persistent log storage is enabled. Users in the group 'adm' can always see messages."); + if (access("/var/log/journal", F_OK) < 0 && geteuid() != 0 && in_group("systemd-journal") <= 0) { + log_error("Unprivileged users can't see messages unless persistent log storage is enabled. Users in the group 'systemd-journal' can always see messages."); return -EACCES; } - if (!arg_quiet && geteuid() != 0 && in_group("adm") <= 0) - log_warning("Showing user generated messages only. Users in the group 'adm' can see all messages. Pass -q to turn this notice off."); + if (!arg_quiet && geteuid() != 0 && in_group("systemd-journal") <= 0) + log_warning("Showing user generated messages only. Users in the group 'systemd-journal' can see all messages. Pass -q to turn this notice off."); #else - if (geteuid() != 0 && in_group("adm") <= 0) { - log_error("No access to messages. Only users in the group 'adm' can see messages."); + if (geteuid() != 0 && in_group("systemd-journal") <= 0) { + log_error("No access to messages. Only users in the group 'systemd-journal' can see messages."); return -EACCES; } #endif diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 654f7ace21..ac565c7ece 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -174,7 +174,7 @@ static uint64_t available_space(Server *s) { } static void server_read_file_gid(Server *s) { - const char *adm = "adm"; + const char *g = "systemd-journal"; int r; assert(s); @@ -182,9 +182,9 @@ static void server_read_file_gid(Server *s) { if (s->file_gid_valid) return; - r = get_group_creds(&adm, &s->file_gid); + r = get_group_creds(&g, &s->file_gid); if (r < 0) - log_warning("Failed to resolve 'adm' group: %s", strerror(-r)); + log_warning("Failed to resolve '%s' group: %s", g, strerror(-r)); /* if we couldn't read the gid, then it will be 0, but that's * fine and we shouldn't try to resolve the group again, so -- cgit v1.2.1 From a187bfd98ae7b651f7c464450895ead6bdf1ddd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 5 Mar 2013 21:43:06 -0500 Subject: journal/tests: free allocated memory in test --- src/journal/test-journal-syslog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/test-journal-syslog.c b/src/journal/test-journal-syslog.c index 5cf940733b..895975caa5 100644 --- a/src/journal/test-journal-syslog.c +++ b/src/journal/test-journal-syslog.c @@ -25,7 +25,7 @@ static void test_syslog_parse_identifier(const char* str, const char *ident, const char*pid, int ret) { const char *buf = str; - char *ident2 = NULL, *pid2 = NULL; + char _cleanup_free_ *ident2 = NULL, *pid2 = NULL; int ret2; ret2 = syslog_parse_identifier(&buf, &ident2, &pid2); -- cgit v1.2.1 From 66ee5c3df7dc8ef7cd5b35457471d23d09a3cb56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 6 Mar 2013 12:17:37 -0500 Subject: journal: properly advertise sd_journal_reliable_fd sd_journal_reliable_fd was added in 85210bffd836, but it was exported under the wrong name. Not too many users I guess. --- src/journal/libsystemd-journal.sym | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/libsystemd-journal.sym b/src/journal/libsystemd-journal.sym index 7b602f59cb..67741770c9 100644 --- a/src/journal/libsystemd-journal.sym +++ b/src/journal/libsystemd-journal.sym @@ -83,7 +83,7 @@ global: LIBSYSTEMD_JOURNAL_196 { global: - sd_journal_fd_reliable; + sd_journal_reliable_fd; sd_journal_get_catalog; sd_journal_get_catalog_for_message_id; sd_journal_set_data_threshold; -- cgit v1.2.1 From 9304ef91c563263cfd914fb32b6ca118bf60d60e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 6 Mar 2013 13:19:45 -0500 Subject: libsystemd-journal: export new function, increase library version Since sd_journal_reliable_fd wasn't exported before, it is as if it was added now. Library "current" number must be bumped. michich> Someone links with the fixed version and produces a RPM with his program. The RPM will happily install on a system with an old systemd version (the deps will appear fine), but the program will fail to run. --- src/journal/libsystemd-journal.sym | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/libsystemd-journal.sym b/src/journal/libsystemd-journal.sym index 67741770c9..fbe41501f0 100644 --- a/src/journal/libsystemd-journal.sym +++ b/src/journal/libsystemd-journal.sym @@ -83,9 +83,13 @@ global: LIBSYSTEMD_JOURNAL_196 { global: - sd_journal_reliable_fd; sd_journal_get_catalog; sd_journal_get_catalog_for_message_id; sd_journal_set_data_threshold; sd_journal_get_data_threshold; } LIBSYSTEMD_JOURNAL_195; + +LIBSYSTEMD_JOURNAL_198 { +global: + sd_journal_reliable_fd; +} LIBSYSTEMD_JOURNAL_196; -- cgit v1.2.1 From 99613ec5d7f0c6e30801457f60c2cab7d8e50d8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 7 Mar 2013 00:40:30 -0500 Subject: libsystemd-journal: return 0 on success in get_data() The man page says so. Right now 0 would be returned if the data was encrypted, 1 otherwise. --- src/journal/journalctl.c | 2 +- src/journal/sd-journal.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index cb93fea63b..c90fecd239 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -1103,7 +1103,7 @@ int main(int argc, char *argv[]) { int flags; if (need_seek) { - if(!arg_reverse) + if (!arg_reverse) r = sd_journal_next(j); else r = sd_journal_previous(j); diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 19123544b3..fa04bfdfc8 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -1868,7 +1868,7 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void ** *data = o->data.payload; *size = t; - return 1; + return 0; } r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o); -- cgit v1.2.1 From 1b12a7b5896f94bdf33b3a6661ebabd761ea6adc Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Thu, 7 Mar 2013 20:44:35 +0100 Subject: pager: introduce "jump to end" option $ journalctl -be is what you want :) https://bugzilla.redhat.com/show_bug.cgi?id=867841 --- src/journal/coredumpctl.c | 2 +- src/journal/journalctl.c | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'src/journal') diff --git a/src/journal/coredumpctl.c b/src/journal/coredumpctl.c index b6e558186d..8bfab0075f 100644 --- a/src/journal/coredumpctl.c +++ b/src/journal/coredumpctl.c @@ -560,7 +560,7 @@ int main(int argc, char *argv[]) { case ACTION_LIST: if (!arg_no_pager) - pager_open(); + pager_open(false); r = dump_list(j); break; diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index c90fecd239..5fb2db3ba5 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -56,6 +56,7 @@ #define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE) static OutputMode arg_output = OUTPUT_SHORT; +static bool arg_pager_end = false; static bool arg_follow = false; static bool arg_full = false; static bool arg_all = false; @@ -103,6 +104,7 @@ static int help(void) { " -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" + " -e --pager-end Immediately jump to end of the journal in the pager\n" " -f --follow Follow journal\n" " -n --lines[=INTEGER] Number of journal entries to show\n" " --no-tail Show all lines, even in follow mode\n" @@ -163,6 +165,7 @@ static int parse_argv(int argc, char *argv[]) { { "help", no_argument, NULL, 'h' }, { "version" , no_argument, NULL, ARG_VERSION }, { "no-pager", no_argument, NULL, ARG_NO_PAGER }, + { "pager-end", no_argument, NULL, 'e' }, { "follow", no_argument, NULL, 'f' }, { "output", required_argument, NULL, 'o' }, { "all", no_argument, NULL, 'a' }, @@ -199,7 +202,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "hfo:an::qmbD:p:c:u:F:xr", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "hefo:an::qmbD:p:c:u:F:xr", options, NULL)) >= 0) { switch (c) { @@ -216,6 +219,10 @@ static int parse_argv(int argc, char *argv[]) { arg_no_pager = true; break; + case 'e': + arg_pager_end = true; + break; + case 'f': arg_follow = true; break; @@ -1075,7 +1082,7 @@ int main(int argc, char *argv[]) { } if (!arg_no_pager && !arg_follow) - pager_open(); + pager_open(arg_pager_end); if (!arg_quiet) { usec_t start, end; -- cgit v1.2.1 From fe59e38bef69568c385d10761132458606cdd896 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 7 Mar 2013 21:49:12 +0100 Subject: journalctl: imply -n1000 when -e is used Make sure the pager does not have to buffer an unbounded number of log messages, by default. --- src/journal/journalctl.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 5fb2db3ba5..3682329e46 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -221,6 +221,10 @@ static int parse_argv(int argc, char *argv[]) { case 'e': arg_pager_end = true; + + if (arg_lines < 0) + arg_lines = 1000; + break; case 'f': -- cgit v1.2.1 From e14ddf1cac12f91685cbd5dac6c5127f8cf87863 Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Fri, 8 Mar 2013 12:05:48 +0100 Subject: =?UTF-8?q?journal:=C2=A0allow=20priority=200=20in=20stdout=20stre?= =?UTF-8?q?am?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Priority 0 is acceptable (it's LOG_EMERG). BTW, I'm not sure why we allow priorities up to 999, but I'm leaving this be for now. http://lists.freedesktop.org/archives/systemd-devel/2013-March/009510.html --- src/journal/journald-stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c index 7b88f747db..54a5b3621a 100644 --- a/src/journal/journald-stream.c +++ b/src/journal/journald-stream.c @@ -175,7 +175,7 @@ static int stdout_stream_line(StdoutStream *s, char *p) { case STDOUT_STREAM_PRIORITY: r = safe_atoi(p, &s->priority); - if (r < 0 || s->priority <= 0 || s->priority >= 999) { + if (r < 0 || s->priority < 0 || s->priority >= 999) { log_warning("Failed to parse log priority line."); return -EINVAL; } -- cgit v1.2.1 From 41891700e02daf0cab9e86908c76ac6f411bbd57 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 11 Mar 2013 15:10:29 +0100 Subject: journald: allow priority of 999, too --- src/journal/journald-stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c index 54a5b3621a..bdc2f49ef4 100644 --- a/src/journal/journald-stream.c +++ b/src/journal/journald-stream.c @@ -175,7 +175,7 @@ static int stdout_stream_line(StdoutStream *s, char *p) { case STDOUT_STREAM_PRIORITY: r = safe_atoi(p, &s->priority); - if (r < 0 || s->priority < 0 || s->priority >= 999) { + if (r < 0 || s->priority < 0 || s->priority > 999) { log_warning("Failed to parse log priority line."); return -EINVAL; } -- cgit v1.2.1 From 7199aa96ce19468d9ce4cb21a13e32a3792fde41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 13 Mar 2013 19:30:05 -0400 Subject: journalctl: show systemd messages about unit for -u journalctl -u unit is not very useful, because it doesn't show systemd messages about starting, stopping, coredumps, etc, like systemctl status unit does. Make it show the same information using the same rules. If somebody really want to see just messages from by the unit, it is easy enough to use _SYSTEMD_UNIT=... --- src/journal/journalctl.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 3682329e46..65114b2ff8 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -38,6 +38,7 @@ #include #include "log.h" +#include "logs-show.h" #include "util.h" #include "path-util.h" #include "build.h" @@ -76,7 +77,7 @@ static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC; static usec_t arg_since, arg_until; static bool arg_since_set = false, arg_until_set = false; static const char *arg_unit = NULL; -static const char *arg_unit_type = NULL; +static bool arg_unit_system; static const char *arg_field = NULL; static bool arg_catalog = false; static bool arg_reverse = false; @@ -187,8 +188,8 @@ static int parse_argv(int argc, char *argv[]) { { "cursor", required_argument, NULL, 'c' }, { "since", required_argument, NULL, ARG_SINCE }, { "until", required_argument, NULL, ARG_UNTIL }, - { "user-unit", required_argument, NULL, ARG_USER_UNIT }, { "unit", required_argument, NULL, 'u' }, + { "user-unit", required_argument, NULL, ARG_USER_UNIT }, { "field", required_argument, NULL, 'F' }, { "catalog", no_argument, NULL, 'x' }, { "list-catalog", no_argument, NULL, ARG_LIST_CATALOG }, @@ -419,14 +420,14 @@ static int parse_argv(int argc, char *argv[]) { arg_until_set = true; break; - case ARG_USER_UNIT: + case 'u': arg_unit = optarg; - arg_unit_type = "_SYSTEMD_USER_UNIT="; + arg_unit_system = true; break; - case 'u': + case ARG_USER_UNIT: arg_unit = optarg; - arg_unit_type = "_SYSTEMD_UNIT="; + arg_unit_system = false; break; case '?': @@ -604,16 +605,12 @@ static int add_unit(sd_journal *j) { if (!u) return log_oom(); - m = strappend(arg_unit_type, u); - - if (!m) - return log_oom(); - - r = sd_journal_add_match(j, m, strlen(m)); - if (r < 0) { - log_error("Failed to add match: %s", strerror(-r)); + 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; - } return 0; } -- cgit v1.2.1 From 83d7d83bcc6c462ecbb4c8003e3a8b41f3b88d46 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 16 Mar 2013 16:10:22 +0100 Subject: journal: pass the *pid* to sd_pid_get_owner_uid() --- src/journal/journald-server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index ac565c7ece..364ab0f113 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -593,7 +593,7 @@ static void dispatch_message_real( IOVEC_SET_STRING(iovec[n++], session); } - if (sd_pid_get_owner_uid(ucred->uid, &owner) >= 0) { + if (sd_pid_get_owner_uid(ucred->pid, &owner) >= 0) { owner_valid = true; if (asprintf(&owner_uid, "_SYSTEMD_OWNER_UID=%lu", (unsigned long) owner) >= 0) IOVEC_SET_STRING(iovec[n++], owner_uid); -- cgit v1.2.1 From 6180fc611b415e2a26c64658d2ce700f457f4a67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 17 Mar 2013 21:52:57 -0400 Subject: journal: use sd_journal_close on error in sd_journal_new --- src/journal/sd-journal.c | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) (limited to 'src/journal') diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index fa04bfdfc8..2c5ee3f8f6 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -1568,37 +1568,21 @@ static sd_journal *journal_new(int flags, const char *path) { if (path) { j->path = strdup(path); - if (!j->path) { - free(j); - return NULL; - } + if (!j->path) + goto fail; } j->files = hashmap_new(string_hash_func, string_compare_func); - if (!j->files) { - free(j->path); - free(j); - return NULL; - } - j->directories_by_path = hashmap_new(string_hash_func, string_compare_func); - if (!j->directories_by_path) { - hashmap_free(j->files); - free(j->path); - free(j); - return NULL; - } - j->mmap = mmap_cache_new(); - if (!j->mmap) { - hashmap_free(j->files); - hashmap_free(j->directories_by_path); - free(j->path); - free(j); - return NULL; - } + if (!j->files || !j->directories_by_path || !j->mmap) + goto fail; return j; + +fail: + sd_journal_close(j); + return NULL; } _public_ int sd_journal_open(sd_journal **ret, int flags) { -- cgit v1.2.1 From a50d7d4389217c0d3b527ee260eabf89e4a76caa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 17 Mar 2013 22:00:01 -0400 Subject: journal: use _cleanup_ One log_debug() moved to match order in other functions. --- src/journal/sd-journal.c | 49 ++++++++++++------------------------------------ 1 file changed, 12 insertions(+), 37 deletions(-) (limited to 'src/journal') diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 2c5ee3f8f6..7ffbaf7cbf 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -1215,7 +1215,7 @@ static void check_network(sd_journal *j, int fd) { } static int add_file(sd_journal *j, const char *prefix, const char *filename) { - char *path; + char _cleanup_free_ *path = NULL; int r; JournalFile *f; @@ -1234,20 +1234,15 @@ static int add_file(sd_journal *j, const char *prefix, const char *filename) { if (!path) return -ENOMEM; - if (hashmap_get(j->files, path)) { - free(path); + if (hashmap_get(j->files, path)) return 0; - } if (hashmap_size(j->files) >= JOURNAL_FILES_MAX) { log_debug("Too many open journal files, not adding %s, ignoring.", path); - free(path); return 0; } r = journal_file_open(path, O_RDONLY, 0, false, false, NULL, j->mmap, NULL, &f); - free(path); - if (r < 0) { if (errno == ENOENT) return 0; @@ -1263,12 +1258,12 @@ static int add_file(sd_journal *j, const char *prefix, const char *filename) { return r; } + log_debug("File %s got added.", f->path); + check_network(j, f->fd); j->current_invalidate_counter ++; - log_debug("File %s got added.", f->path); - return 0; } @@ -1311,9 +1306,9 @@ static int remove_file(sd_journal *j, const char *prefix, const char *filename) } static int add_directory(sd_journal *j, const char *prefix, const char *dirname) { - char *path; + char _cleanup_free_ *path = NULL; int r; - DIR *d; + DIR _cleanup_closedir_ *d = NULL; sd_id128_t id, mid; Directory *m; @@ -1336,8 +1331,6 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname) d = opendir(path); if (!d) { log_debug("Failed to open %s: %m", path); - free(path); - if (errno == ENOENT) return 0; return -errno; @@ -1346,32 +1339,24 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname) m = hashmap_get(j->directories_by_path, path); if (!m) { m = new0(Directory, 1); - if (!m) { - closedir(d); - free(path); + if (!m) return -ENOMEM; - } m->is_root = false; m->path = path; if (hashmap_put(j->directories_by_path, m->path, m) < 0) { - closedir(d); - free(m->path); free(m); return -ENOMEM; } + path = NULL; /* avoid freeing in cleanup */ j->current_invalidate_counter ++; log_debug("Directory %s got added.", m->path); - } else if (m->is_root) { - free (path); - closedir(d); + } else if (m->is_root) return 0; - } else - free(path); if (m->wd <= 0 && j->inotify_fd >= 0) { @@ -1402,13 +1387,11 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname) check_network(j, dirfd(d)); - closedir(d); - return 0; } static int add_root_directory(sd_journal *j, const char *p) { - DIR *d; + DIR _cleanup_closedir_ *d = NULL; Directory *m; int r; @@ -1426,21 +1409,17 @@ static int add_root_directory(sd_journal *j, const char *p) { m = hashmap_get(j->directories_by_path, p); if (!m) { m = new0(Directory, 1); - if (!m) { - closedir(d); + if (!m) return -ENOMEM; - } m->is_root = true; m->path = strdup(p); if (!m->path) { - closedir(d); free(m); return -ENOMEM; } if (hashmap_put(j->directories_by_path, m->path, m) < 0) { - closedir(d); free(m->path); free(m); return -ENOMEM; @@ -1450,10 +1429,8 @@ static int add_root_directory(sd_journal *j, const char *p) { log_debug("Root directory %s got added.", m->path); - } else if (!m->is_root) { - closedir(d); + } else if (!m->is_root) return 0; - } if (m->wd <= 0 && j->inotify_fd >= 0) { @@ -1491,8 +1468,6 @@ static int add_root_directory(sd_journal *j, const char *p) { check_network(j, dirfd(d)); - closedir(d); - return 0; } -- cgit v1.2.1 From 763c7aa288485cf5ab627fe1d25ff58e76f9dacb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 17 Mar 2013 23:36:25 -0400 Subject: journal,shared: add _cleanup_journal_close_ --- src/journal/coredumpctl.c | 14 ++++------- src/journal/journalctl.c | 49 ++++++++++++++++++--------------------- src/journal/journald-server.c | 3 +-- src/journal/test-journal-enum.c | 5 ++-- src/journal/test-journal-match.c | 7 ++---- src/journal/test-journal-stream.c | 10 +++----- 6 files changed, 36 insertions(+), 52 deletions(-) (limited to 'src/journal') diff --git a/src/journal/coredumpctl.c b/src/journal/coredumpctl.c index 8bfab0075f..99ca269327 100644 --- a/src/journal/coredumpctl.c +++ b/src/journal/coredumpctl.c @@ -34,6 +34,7 @@ #include "log.h" #include "path-util.h" #include "pager.h" +#include "macro.h" static enum { ACTION_NONE, @@ -42,7 +43,6 @@ static enum { ACTION_GDB, } arg_action = ACTION_LIST; -static Set *matches = NULL; static FILE* output = NULL; static char* field = NULL; @@ -139,7 +139,7 @@ fail: return r; } -static int parse_argv(int argc, char *argv[]) { +static int parse_argv(int argc, char *argv[], Set *matches) { enum { ARG_VERSION = 0x100, ARG_NO_PAGER, @@ -519,10 +519,11 @@ finish: } int main(int argc, char *argv[]) { - sd_journal *j = NULL; + sd_journal _cleanup_journal_close_ *j = NULL; const char* match; Iterator it; int r = 0; + Set _cleanup_set_free_free_ *matches = NULL; setlocale(LC_ALL, ""); log_parse_environment(); @@ -534,7 +535,7 @@ int main(int argc, char *argv[]) { goto end; } - r = parse_argv(argc, argv); + r = parse_argv(argc, argv, matches); if (r < 0) goto end; @@ -578,11 +579,6 @@ int main(int argc, char *argv[]) { } end: - if (j) - sd_journal_close(j); - - set_free_free(matches); - pager_close(); if (output) diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 65114b2ff8..a6ad055dc6 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -897,7 +897,7 @@ static int access_check(void) { int main(int argc, char *argv[]) { int r; - sd_journal *j = NULL; + sd_journal _cleanup_journal_close_ *j = NULL; bool need_seek = false; sd_id128_t previous_boot_id; bool previous_boot_id_valid = false, first_line = true; @@ -937,7 +937,7 @@ int main(int argc, char *argv[]) { r = access_check(); if (r < 0) - goto finish; + return EXIT_FAILURE; if (arg_directory) r = sd_journal_open_directory(&j, arg_directory, 0); @@ -945,7 +945,7 @@ int main(int argc, char *argv[]) { r = sd_journal_open(&j, arg_merge ? 0 : SD_JOURNAL_LOCAL_ONLY); if (r < 0) { log_error("Failed to open journal: %s", strerror(-r)); - goto finish; + return EXIT_FAILURE; } if (arg_action == ACTION_VERIFY) { @@ -955,8 +955,7 @@ int main(int argc, char *argv[]) { if (arg_action == ACTION_PRINT_HEADER) { journal_print_header(j); - r = 0; - goto finish; + return EXIT_SUCCESS; } if (arg_action == ACTION_DISK_USAGE) { @@ -965,33 +964,33 @@ int main(int argc, char *argv[]) { r = sd_journal_get_usage(j, &bytes); if (r < 0) - goto finish; + return EXIT_FAILURE; - printf("Journals take up %s on disk.\n", format_bytes(sbytes, sizeof(sbytes), bytes)); - r = 0; - goto finish; + printf("Journals take up %s on disk.\n", + format_bytes(sbytes, sizeof(sbytes), bytes)); + return EXIT_SUCCESS; } r = add_this_boot(j); if (r < 0) - goto finish; + return EXIT_FAILURE; r = add_unit(j); if (r < 0) - goto finish; + return EXIT_FAILURE; r = add_matches(j, argv + optind); if (r < 0) - goto finish; + return EXIT_FAILURE; r = add_priorities(j); if (r < 0) - goto finish; + 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) - goto finish; + return EXIT_FAILURE; if (arg_field) { const void *data; @@ -1000,7 +999,7 @@ int main(int argc, char *argv[]) { r = sd_journal_query_unique(j, arg_field); if (r < 0) { log_error("Failed to query unique data objects: %s", strerror(-r)); - goto finish; + return EXIT_FAILURE; } SD_JOURNAL_FOREACH_UNIQUE(j, data, size) { @@ -1018,15 +1017,14 @@ int main(int argc, char *argv[]) { n_shown ++; } - r = 0; - goto finish; + return EXIT_SUCCESS; } if (arg_cursor) { r = sd_journal_seek_cursor(j, arg_cursor); if (r < 0) { log_error("Failed to seek to cursor: %s", strerror(-r)); - goto finish; + return EXIT_FAILURE; } if (!arg_reverse) r = sd_journal_next(j); @@ -1037,7 +1035,7 @@ int main(int argc, char *argv[]) { r = sd_journal_seek_realtime_usec(j, arg_since); if (r < 0) { log_error("Failed to seek to date: %s", strerror(-r)); - goto finish; + return EXIT_FAILURE; } r = sd_journal_next(j); @@ -1045,7 +1043,7 @@ int main(int argc, char *argv[]) { r = sd_journal_seek_realtime_usec(j, arg_until); if (r < 0) { log_error("Failed to seek to date: %s", strerror(-r)); - goto finish; + return EXIT_FAILURE; } r = sd_journal_previous(j); @@ -1053,7 +1051,7 @@ int main(int argc, char *argv[]) { r = sd_journal_seek_tail(j); if (r < 0) { log_error("Failed to seek to tail: %s", strerror(-r)); - goto finish; + return EXIT_FAILURE; } r = sd_journal_previous_skip(j, arg_lines); @@ -1062,7 +1060,7 @@ int main(int argc, char *argv[]) { r = sd_journal_seek_tail(j); if (r < 0) { log_error("Failed to seek to tail: %s", strerror(-r)); - goto finish; + return EXIT_FAILURE; } r = sd_journal_previous(j); @@ -1071,7 +1069,7 @@ int main(int argc, char *argv[]) { r = sd_journal_seek_head(j); if (r < 0) { log_error("Failed to seek to head: %s", strerror(-r)); - goto finish; + return EXIT_FAILURE; } r = sd_journal_next(j); @@ -1079,7 +1077,7 @@ int main(int argc, char *argv[]) { if (r < 0) { log_error("Failed to iterate through journal: %s", strerror(-r)); - goto finish; + return EXIT_FAILURE; } if (!arg_no_pager && !arg_follow) @@ -1189,9 +1187,6 @@ int main(int argc, char *argv[]) { } finish: - if (j) - sd_journal_close(j); - pager_close(); return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 364ab0f113..855430a6ba 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -960,8 +960,7 @@ finish: if (r >= 0) rm_rf("/run/log/journal", false, true, false); - if (j) - sd_journal_close(j); + sd_journal_close(j); return r; } diff --git a/src/journal/test-journal-enum.c b/src/journal/test-journal-enum.c index 8a843ecdda..88f583e6c7 100644 --- a/src/journal/test-journal-enum.c +++ b/src/journal/test-journal-enum.c @@ -23,10 +23,12 @@ #include "log.h" #include "sd-journal.h" +#include "macro.h" +#include "util.h" int main(int argc, char *argv[]) { unsigned n = 0; - sd_journal *j; + sd_journal _cleanup_journal_close_ *j = NULL; log_set_max_level(LOG_DEBUG); @@ -48,6 +50,5 @@ int main(int argc, char *argv[]) { break; } - sd_journal_close(j); return 0; } diff --git a/src/journal/test-journal-match.c b/src/journal/test-journal-match.c index fa228144f5..2ca2337c44 100644 --- a/src/journal/test-journal-match.c +++ b/src/journal/test-journal-match.c @@ -28,8 +28,8 @@ #include "log.h" int main(int argc, char *argv[]) { - sd_journal *j; - char *t; + sd_journal _cleanup_journal_close_ *j; + char _cleanup_free_ *t; log_set_max_level(LOG_DEBUG); @@ -59,9 +59,6 @@ int main(int argc, char *argv[]) { assert_se(streq(t, "((TWO=two AND (ONE=two OR ONE=one)) OR (PIFF=paff AND (QUUX=yyyyy OR QUUX=xxxxx OR QUUX=mmmm) AND (HALLO= OR HALLO=WALDO)))")); printf("resulting match expression is: %s\n", t); - free(t); - - sd_journal_close(j); return 0; } diff --git a/src/journal/test-journal-stream.c b/src/journal/test-journal-stream.c index b3e816db70..4b73ac7906 100644 --- a/src/journal/test-journal-stream.c +++ b/src/journal/test-journal-stream.c @@ -75,7 +75,7 @@ int main(int argc, char *argv[]) { JournalFile *one, *two, *three; char t[] = "/tmp/journal-stream-XXXXXX"; unsigned i; - sd_journal *j; + sd_journal _cleanup_journal_close_ *j = NULL; char *z; const void *data; size_t l; @@ -126,25 +126,23 @@ int main(int argc, char *argv[]) { assert_se(sd_journal_add_match(j, "MAGIC=quux", 0) >= 0); SD_JOURNAL_FOREACH_BACKWARDS(j) { - char *c; + char _cleanup_free_ *c; assert_se(sd_journal_get_data(j, "NUMBER", &data, &l) >= 0); printf("\t%.*s\n", (int) l, (const char*) data); assert_se(sd_journal_get_cursor(j, &c) >= 0); assert_se(sd_journal_test_cursor(j, c) > 0); - free(c); } SD_JOURNAL_FOREACH(j) { - char *c; + char _cleanup_free_ *c; assert_se(sd_journal_get_data(j, "NUMBER", &data, &l) >= 0); printf("\t%.*s\n", (int) l, (const char*) data); assert_se(sd_journal_get_cursor(j, &c) >= 0); assert_se(sd_journal_test_cursor(j, c) > 0); - free(c); } sd_journal_flush_matches(j); @@ -177,8 +175,6 @@ int main(int argc, char *argv[]) { SD_JOURNAL_FOREACH_UNIQUE(j, data, l) printf("%.*s\n", (int) l, (const char*) data); - sd_journal_close(j); - assert_se(rm_rf_dangerous(t, false, true, false) >= 0); return 0; -- cgit v1.2.1 From 8cb17a6dc88cecfcee3189765031e9e8a1f4106b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 4 Nov 2012 16:19:04 +0100 Subject: sd-journal: do not require path to be absolute Seems natural to be able to specify relative directory, e.g. with journalctl -D. And even if, this should be checked in front-end code, not in the library. --- src/journal/sd-journal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 7ffbaf7cbf..ef4b9b2242 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -1596,7 +1596,7 @@ _public_ int sd_journal_open_directory(sd_journal **ret, const char *path, int f if (!ret) return -EINVAL; - if (!path || !path_is_absolute(path)) + if (!path) return -EINVAL; if (flags != 0) -- cgit v1.2.1 From 52aeb63cffcdb3701cdc2ca41868208de2347318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 15 Mar 2013 18:00:57 -0400 Subject: journalctl: use _cleanup_ in one function --- src/journal/journalctl.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index a6ad055dc6..8aef923bea 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -513,16 +513,16 @@ static int generate_new_id128(void) { static int add_matches(sd_journal *j, char **args) { char **i; - int r; assert(j); STRV_FOREACH(i, args) { + int r; if (streq(*i, "+")) r = sd_journal_add_disjunction(j); else if (path_is_absolute(*i)) { - char *p, *t = NULL; + char _cleanup_free_ *p, *t = NULL; const char *path; struct stat st; @@ -530,7 +530,6 @@ static int add_matches(sd_journal *j, char **args) { path = p ? p : *i; if (stat(path, &st) < 0) { - free(p); log_error("Couldn't stat file: %m"); return -errno; } @@ -542,18 +541,14 @@ static int add_matches(sd_journal *j, char **args) { else if (S_ISBLK(st.st_mode)) asprintf(&t, "_KERNEL_DEVICE=b%u:%u", major(st.st_rdev), minor(st.st_rdev)); else { - free(p); log_error("File is not a device node, regular file or is not executable: %s", *i); return -EINVAL; } - free(p); - if (!t) return log_oom(); r = sd_journal_add_match(j, t, 0); - free(t); } else r = sd_journal_add_match(j, *i, 0); -- cgit v1.2.1 From 54b7254c1fa629937f92fd6fa34bdf127b696a00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 19 Mar 2013 20:54:04 -0400 Subject: journalct: beef up entry listing The ability to dump catalog entries in full and by id is added. --- src/journal/catalog.c | 58 +++++++++++++++++++++++++++++++++++++++++----- src/journal/catalog.h | 5 +++- src/journal/journalctl.c | 17 ++++++++++++-- src/journal/test-catalog.c | 4 +++- 4 files changed, 74 insertions(+), 10 deletions(-) (limited to 'src/journal') diff --git a/src/journal/catalog.c b/src/journal/catalog.c index 32256f6263..dacf5c50a1 100644 --- a/src/journal/catalog.c +++ b/src/journal/catalog.c @@ -551,7 +551,23 @@ static char *find_header(const char *s, const char *header) { } } -int catalog_list(FILE *f) { +static void dump_catalog_entry(FILE *f, sd_id128_t id, const char *s, bool oneline) { + if (oneline) { + _cleanup_free_ char *subject = NULL, *defined_by = NULL; + + subject = find_header(s, "Subject:"); + defined_by = find_header(s, "Defined-By:"); + + fprintf(f, SD_ID128_FORMAT_STR " %s: %s\n", + SD_ID128_FORMAT_VAL(id), + strna(defined_by), strna(subject)); + } else + fprintf(f, "-- " SD_ID128_FORMAT_STR "\n%s\n", + SD_ID128_FORMAT_VAL(id), s); +} + + +int catalog_list(FILE *f, bool oneline) { _cleanup_close_ int fd = -1; void *p = NULL; struct stat st; @@ -571,17 +587,13 @@ int catalog_list(FILE *f) { for (n = 0; n < le64toh(h->n_items); n++) { const char *s; - _cleanup_free_ char *subject = NULL, *defined_by = NULL; if (last_id_set && sd_id128_equal(last_id, items[n].id)) continue; assert_se(s = find_id(p, items[n].id)); - subject = find_header(s, "Subject:"); - defined_by = find_header(s, "Defined-By:"); - - fprintf(f, SD_ID128_FORMAT_STR " %s: %s\n", SD_ID128_FORMAT_VAL(items[n].id), strna(defined_by), strna(subject)); + dump_catalog_entry(f, items[n].id, s, oneline); last_id_set = true; last_id = items[n].id; @@ -591,3 +603,37 @@ int catalog_list(FILE *f) { return 0; } + +int catalog_list_items(FILE *f, bool oneline, char **items) { + char **item; + int r = 0; + + STRV_FOREACH(item, items) { + sd_id128_t id; + int k; + char _cleanup_free_ *msg = NULL; + + k = sd_id128_from_string(*item, &id); + if (k < 0) { + log_error("Failed to parse id128 '%s': %s", + *item, strerror(-r)); + if (r < 0) + r = k; + continue; + } + + k = catalog_get(id, &msg); + if (k < 0) { + log_full(k == -ENOENT ? LOG_NOTICE : LOG_ERR, + "Failed to retrieve catalog entry for '%s': %s", + *item, strerror(-r)); + if (r < 0) + r = k; + continue; + } + + dump_catalog_entry(f, id, msg, oneline); + } + + return r; +} diff --git a/src/journal/catalog.h b/src/journal/catalog.h index 9add773c95..8ea2c41c2d 100644 --- a/src/journal/catalog.h +++ b/src/journal/catalog.h @@ -21,8 +21,11 @@ along with systemd; If not, see . ***/ +#include + #include "sd-id128.h" int catalog_update(void); int catalog_get(sd_id128_t id, char **data); -int catalog_list(FILE *f); +int catalog_list(FILE *f, bool oneline); +int catalog_list_items(FILE *f, bool oneline, char **items); diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 8aef923bea..975c44fa9b 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -90,6 +90,7 @@ static enum { ACTION_VERIFY, ACTION_DISK_USAGE, ACTION_LIST_CATALOG, + ACTION_DUMP_CATALOG, ACTION_UPDATE_CATALOG } arg_action = ACTION_SHOW; @@ -131,6 +132,7 @@ static int help(void) { " --disk-usage Show total disk usage\n" " -F --field=FIELD List all values a certain field takes\n" " --list-catalog Show message IDs of all entries in the message catalog\n" + " --dump-catalog Show entries in the message catalog\n" " --update-catalog Update the message catalog database\n" #ifdef HAVE_GCRYPT " --setup-keys Generate new FSS key pair\n" @@ -159,6 +161,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_UNTIL, ARG_USER_UNIT, ARG_LIST_CATALOG, + ARG_DUMP_CATALOG, ARG_UPDATE_CATALOG }; @@ -193,6 +196,7 @@ static int parse_argv(int argc, char *argv[]) { { "field", required_argument, NULL, 'F' }, { "catalog", no_argument, NULL, 'x' }, { "list-catalog", no_argument, NULL, ARG_LIST_CATALOG }, + { "dump-catalog", no_argument, NULL, ARG_DUMP_CATALOG }, { "update-catalog",no_argument, NULL, ARG_UPDATE_CATALOG }, { "reverse", no_argument, NULL, 'r' }, { NULL, 0, NULL, 0 } @@ -445,6 +449,10 @@ static int parse_argv(int argc, char *argv[]) { arg_action = ACTION_LIST_CATALOG; break; + case ARG_DUMP_CATALOG: + arg_action = ACTION_DUMP_CATALOG; + break; + case ARG_UPDATE_CATALOG: arg_action = ACTION_UPDATE_CATALOG; break; @@ -918,8 +926,13 @@ int main(int argc, char *argv[]) { goto finish; } - if (arg_action == ACTION_LIST_CATALOG) { - r = catalog_list(stdout); + if (arg_action == ACTION_LIST_CATALOG || + arg_action == ACTION_DUMP_CATALOG) { + bool oneline = arg_action == ACTION_LIST_CATALOG; + if (optind < argc) + r = catalog_list_items(stdout, oneline, argv + optind); + else + r = catalog_list(stdout, oneline); if (r < 0) log_error("Failed to list catalog: %s", strerror(-r)); goto finish; diff --git a/src/journal/test-catalog.c b/src/journal/test-catalog.c index cec8a11c43..c75b1464fe 100644 --- a/src/journal/test-catalog.c +++ b/src/journal/test-catalog.c @@ -36,7 +36,9 @@ int main(int argc, char *argv[]) { assert_se(catalog_update() >= 0); - assert_se(catalog_list(stdout) >= 0); + assert_se(catalog_list(stdout, true) >= 0); + + assert_se(catalog_list(stdout, false) >= 0); assert_se(catalog_get(SD_MESSAGE_COREDUMP, &text) >= 0); -- cgit v1.2.1 From 907809fc6a9867869b8a237663af2eda335d333e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 19 Mar 2013 20:00:29 +0100 Subject: macro: don't redefine CLAMP if it is already defined by glib or some other library --- src/journal/journal-gatewayd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c index 7e29c905e2..8161b7e56b 100644 --- a/src/journal/journal-gatewayd.c +++ b/src/journal/journal-gatewayd.c @@ -110,7 +110,6 @@ static int open_journal(RequestMeta *m) { return sd_journal_open(&m->journal, SD_JOURNAL_LOCAL_ONLY|SD_JOURNAL_SYSTEM_ONLY); } - static int respond_oom_internal(struct MHD_Connection *connection) { struct MHD_Response *response; const char m[] = "Out of memory.\n"; -- cgit v1.2.1 From 4750fade135aed733aa7a5fda7c670e6b4391538 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 20 Mar 2013 18:25:35 -0400 Subject: Remove some unused variables --- src/journal/journalctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 975c44fa9b..ddadc21338 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -596,7 +596,7 @@ static int add_this_boot(sd_journal *j) { } static int add_unit(sd_journal *j) { - _cleanup_free_ char *m = NULL, *u = NULL; + _cleanup_free_ char *u = NULL; int r; assert(j); -- cgit v1.2.1 From 6c142648aaced56ab681fcc97a71b06d588122a9 Mon Sep 17 00:00:00 2001 From: "Jan Alexander Steffens (heftig)" Date: Wed, 20 Mar 2013 21:32:05 +0100 Subject: Fix vacuum logic error The vacuum code used to stop vacuuming after one deletion, even when max_use was still exceeded. Also make usage a uint64_t, as the code already pretends it is one. Signed-off-by: Jan Alexander Steffens (heftig) --- src/journal/journal-vacuum.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c index 731f6c770f..4a3a5a9e63 100644 --- a/src/journal/journal-vacuum.c +++ b/src/journal/journal-vacuum.c @@ -36,7 +36,7 @@ #include "util.h" struct vacuum_info { - off_t usage; + uint64_t usage; char *filename; uint64_t realtime; @@ -293,7 +293,7 @@ int journal_directory_vacuum( if (unlinkat(dirfd(d), list[i].filename, 0) >= 0) { log_debug("Deleted archived journal %s/%s.", directory, list[i].filename); - if ((uint64_t) list[i].usage > sum) + if (list[i].usage < sum) sum -= list[i].usage; else sum = 0; -- cgit v1.2.1 From 4468addca6d01a0d2d154371dd72f54307a9c786 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 22 Mar 2013 17:44:15 +0100 Subject: journalctl: give a nice hint about group membership based on ACLs of /var/log/journal If we notice that we unprivileged and not in any of the groups which have access to /var/log/journal, print a nice message about which groups do. This checks and prints all groups that are in the default ACL for /var/log/journal, which is not necessarily correct for all journal files, but pretty close. --- src/journal/journalctl.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 2 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index ddadc21338..4c288f3334 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -35,6 +35,10 @@ #include #include +#ifdef HAVE_ACL +#include +#endif + #include #include "log.h" @@ -881,13 +885,96 @@ static int verify(sd_journal *j) { static int access_check(void) { #ifdef HAVE_ACL + /* If /var/log/journal doesn't even exist, unprivileged users have no access at all */ if (access("/var/log/journal", F_OK) < 0 && geteuid() != 0 && in_group("systemd-journal") <= 0) { log_error("Unprivileged users can't see messages unless persistent log storage is enabled. Users in the group 'systemd-journal' can always see messages."); return -EACCES; } - if (!arg_quiet && geteuid() != 0 && in_group("systemd-journal") <= 0) - log_warning("Showing user generated messages only. Users in the group 'systemd-journal' can see all messages. Pass -q to turn this notice off."); + /* If /var/log/journal exists, try to pring a nice notice if the user lacks access to it */ + if (!arg_quiet && geteuid() != 0) { + _cleanup_strv_free_ char **g = NULL; + bool have_access; + acl_t acl; + int r; + + have_access = in_group("systemd-journal") > 0; + if (!have_access) { + + /* Let's enumerate all groups from the default + * ACL of the directory, which generally + * should allow access to most journal + * files too */ + + acl = acl_get_file("/var/log/journal/", ACL_TYPE_DEFAULT); + if (acl) { + acl_entry_t entry; + + r = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry); + while (r > 0) { + acl_tag_t tag; + gid_t *gid; + char *name; + + r = acl_get_tag_type(entry, &tag); + if (r < 0) + break; + + if (tag != ACL_GROUP) + goto next; + + gid = acl_get_qualifier(entry); + if (!gid) + break; + + if (in_gid(*gid) > 0) { + have_access = true; + break; + } + + name = gid_to_name(*gid); + if (!name) { + acl_free(acl); + return log_oom(); + } + + r = strv_push(&g, name); + if (r < 0) { + free(name); + acl_free(acl); + return log_oom(); + } + + next: + r = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry); + } + + acl_free(acl); + } + } + + if (!have_access) { + + if (strv_isempty(g)) + log_notice("Hint: You are currently not seeing messages from other users and the system. Users in the group 'systemd-journal' can see all messages. Pass -q to turn this notice off."); + else { + _cleanup_free_ char *s = NULL; + + r = strv_extend(&g, "systemd-journal"); + if (r < 0) + return log_oom(); + + strv_sort(g); + strv_uniq(g); + + s = strv_join(g, "', '"); + if (!s) + return log_oom(); + + log_notice("Hint: You are currently not seeing messages from other users and the system. Users in the groups '%s' can see all messages. Pass -q to turn this notice off.", s); + } + } + } #else if (geteuid() != 0 && in_group("systemd-journal") <= 0) { log_error("No access to messages. Only users in the group 'systemd-journal' can see messages."); -- cgit v1.2.1 From 478c82693c386e7a6e8e4b37cc99fb19b12e7186 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 22 Mar 2013 14:35:26 +0000 Subject: build-sys: move acl searching code into libsystemd-acl This loop over acls is a bit too much to keep inside of another loop. --- src/journal/journalctl.c | 53 +++++------------------------------------------- 1 file changed, 5 insertions(+), 48 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 4c288f3334..8543adfb8a 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -37,6 +37,7 @@ #ifdef HAVE_ACL #include +#include "acl-util.h" #endif #include @@ -895,62 +896,18 @@ static int access_check(void) { if (!arg_quiet && geteuid() != 0) { _cleanup_strv_free_ char **g = NULL; bool have_access; - acl_t acl; int r; have_access = in_group("systemd-journal") > 0; - if (!have_access) { + if (!have_access) { /* Let's enumerate all groups from the default * ACL of the directory, which generally * should allow access to most journal * files too */ - - acl = acl_get_file("/var/log/journal/", ACL_TYPE_DEFAULT); - if (acl) { - acl_entry_t entry; - - r = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry); - while (r > 0) { - acl_tag_t tag; - gid_t *gid; - char *name; - - r = acl_get_tag_type(entry, &tag); - if (r < 0) - break; - - if (tag != ACL_GROUP) - goto next; - - gid = acl_get_qualifier(entry); - if (!gid) - break; - - if (in_gid(*gid) > 0) { - have_access = true; - break; - } - - name = gid_to_name(*gid); - if (!name) { - acl_free(acl); - return log_oom(); - } - - r = strv_push(&g, name); - if (r < 0) { - free(name); - acl_free(acl); - return log_oom(); - } - - next: - r = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry); - } - - acl_free(acl); - } + r = search_acl_groups(&g, "/var/log/journal/", &have_access); + if (r < 0) + return r; } if (!have_access) { -- cgit v1.2.1 From 6fe391c56d3f4231576ccc9d62d2000f37640a92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 11 Mar 2013 18:03:13 -0400 Subject: journalctl: be smarter about journal error checks There are many ways in which we can get those checks wrong, so it is better to warn and then error out on a real access failure. The error messages are wrapped to <80 lines, because their primary use is to be displayed in the terminal, and it is easier to read them this way. Reading them in the journal can be a bit trickier, but this is a bug in logs-show.c. --- src/journal/journal-internal.h | 3 + src/journal/journalctl.c | 136 ++++++++++++++++++++++++++++------------- src/journal/sd-journal.c | 54 ++++++++++++---- 3 files changed, 136 insertions(+), 57 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journal-internal.h b/src/journal/journal-internal.h index 97de0e75ff..bc9e44d42d 100644 --- a/src/journal/journal-internal.h +++ b/src/journal/journal-internal.h @@ -30,6 +30,7 @@ #include "journal-def.h" #include "list.h" #include "hashmap.h" +#include "set.h" #include "journal-file.h" typedef struct Match Match; @@ -123,6 +124,8 @@ struct sd_journal { bool on_network; size_t data_threshold; + + Set *errors; }; char *journal_make_match_string(sd_journal *j); diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 8543adfb8a..91dbde3ba1 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -883,63 +883,111 @@ static int verify(sd_journal *j) { return r; } -static int access_check(void) { - #ifdef HAVE_ACL - /* If /var/log/journal doesn't even exist, unprivileged users have no access at all */ - if (access("/var/log/journal", F_OK) < 0 && geteuid() != 0 && in_group("systemd-journal") <= 0) { - log_error("Unprivileged users can't see messages unless persistent log storage is enabled. Users in the group 'systemd-journal' can always see messages."); - return -EACCES; +static int access_check_var_log_journal(sd_journal *j) { + _cleanup_strv_free_ char **g = NULL; + bool have_access; + int r; + + assert(j); + + have_access = in_group("systemd-journal") > 0; + + if (!have_access) { + /* Let's enumerate all groups from the default ACL of + * the directory, which generally should allow access + * to most journal files too */ + r = search_acl_groups(&g, "/var/log/journal/", &have_access); + if (r < 0) + return r; } - /* If /var/log/journal exists, try to pring a nice notice if the user lacks access to it */ - if (!arg_quiet && geteuid() != 0) { - _cleanup_strv_free_ char **g = NULL; - bool have_access; - int r; + if (!have_access) { - have_access = in_group("systemd-journal") > 0; + if (strv_isempty(g)) + log_notice("Hint: You are currently not seeing messages from other users and\n" + "the system. Users in the group 'systemd-journal' can see all messages.\n" + "Pass -q to turn this notice off."); + else { + _cleanup_free_ char *s = NULL; - if (!have_access) { - /* Let's enumerate all groups from the default - * ACL of the directory, which generally - * should allow access to most journal - * files too */ - r = search_acl_groups(&g, "/var/log/journal/", &have_access); + r = strv_extend(&g, "systemd-journal"); if (r < 0) - return r; + return log_oom(); + + strv_sort(g); + strv_uniq(g); + + s = strv_join(g, "', '"); + if (!s) + return log_oom(); + + log_notice("Hint: You are currently not seeing messages from other users and the system.\n" + "Users in the groups '%s' can see all messages.\n" + "Pass -q to turn this notice off.", s); } + } - if (!have_access) { + return 0; +} +#endif - if (strv_isempty(g)) - log_notice("Hint: You are currently not seeing messages from other users and the system. Users in the group 'systemd-journal' can see all messages. Pass -q to turn this notice off."); - else { - _cleanup_free_ char *s = NULL; +static int access_check(sd_journal *j) { + uint64_t eacces = EACCES, *code; + Iterator it; + int r = 0; - r = strv_extend(&g, "systemd-journal"); - if (r < 0) - return log_oom(); + assert(j); + assert(j->errors); + assert(j->files); - strv_sort(g); - strv_uniq(g); + if (set_isempty(j->errors)) { + if (hashmap_isempty(j->files)) + log_info("No journal files were found."); + return 0; + } - s = strv_join(g, "', '"); - if (!s) - return log_oom(); + if (!set_contains(j->errors, &eacces)) { +#ifdef HAVE_ACL + /* If /var/log/journal doesn't even exist, + unprivileged users have no access at all */ + if (access("/var/log/journal", F_OK) < 0 && + geteuid() != 0 && + in_group("systemd-journal") <= 0) { + log_error("Unprivileged users can't see messages unless persistent log storage\n" + "is enabled. Users in the group 'systemd-journal' can always see messages."); + return -EACCES; + } - log_notice("Hint: You are currently not seeing messages from other users and the system. Users in the groups '%s' can see all messages. Pass -q to turn this notice off.", s); - } + /* If /var/log/journal exists, try to pring a nice + notice if the user lacks access to it */ + if (!arg_quiet && geteuid() != 0) { + r = access_check_var_log_journal(j); + if (r < 0) + return r; } - } #else - if (geteuid() != 0 && in_group("systemd-journal") <= 0) { - log_error("No access to messages. Only users in the group 'systemd-journal' can see messages."); - return -EACCES; - } + if (geteuid() != 0 && in_group("systemd-journal") <= 0) + log_error("No access to messages.\n" + "Users in the group 'systemd-journal' can see messages."); #endif + if (hashmap_isempty(j->files)) { + log_error("No journal files were opened, due to insufficient permissions."); + r = -EACCES; + } + } - return 0; + SET_FOREACH(code, j->errors, it) { + int err = -PTR_TO_INT(code); + assert(err > 0); + if (err != EACCES) + log_warning("Error was encountered while opening journal files: %s", + strerror(err)); + } + + log_notice("Hint: run journalctl in debug mode: SYSTEMD_LOG_LEVEL=debug journalct ..."); + + return r; } int main(int argc, char *argv[]) { @@ -987,10 +1035,6 @@ int main(int argc, char *argv[]) { goto finish; } - r = access_check(); - if (r < 0) - return EXIT_FAILURE; - if (arg_directory) r = sd_journal_open_directory(&j, arg_directory, 0); else @@ -1000,6 +1044,10 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } + r = access_check(j); + if (r < 0) + return EXIT_FAILURE; + if (arg_action == ACTION_VERIFY) { r = verify(j); goto finish; diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index ef4b9b2242..c62ad811dc 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -49,6 +49,15 @@ #define DEFAULT_DATA_THRESHOLD (64*1024) +/* We return an error here only if we didn't manage to + memorize the real error. */ +static int set_put_error(Set* errors, int r) { + if (r >= 0) + return r; + + return set_put(errors, INT_TO_PTR(r)); +} + static void detach_location(sd_journal *j) { Iterator i; JournalFile *f; @@ -1239,7 +1248,7 @@ static int add_file(sd_journal *j, const char *prefix, const char *filename) { if (hashmap_size(j->files) >= JOURNAL_FILES_MAX) { log_debug("Too many open journal files, not adding %s, ignoring.", path); - return 0; + return set_put_error(j->errors, -ETOOMANYREFS); } r = journal_file_open(path, O_RDONLY, 0, false, false, NULL, j->mmap, NULL, &f); @@ -1380,8 +1389,13 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname) if (dirent_is_file_with_suffix(de, ".journal") || dirent_is_file_with_suffix(de, ".journal~")) { r = add_file(j, m->path, de->d_name); - if (r < 0) - log_debug("Failed to add file %s/%s: %s", m->path, de->d_name, strerror(-r)); + if (r < 0) { + log_debug("Failed to add file %s/%s: %s", + m->path, de->d_name, strerror(-r)); + r = set_put_error(j->errors, r); + if (r < 0) + return r; + } } } @@ -1454,9 +1468,13 @@ static int add_root_directory(sd_journal *j, const char *p) { if (dirent_is_file_with_suffix(de, ".journal") || dirent_is_file_with_suffix(de, ".journal~")) { r = add_file(j, m->path, de->d_name); - if (r < 0) - log_debug("Failed to add file %s/%s: %s", m->path, de->d_name, strerror(-r)); - + if (r < 0) { + log_debug("Failed to add file %s/%s: %s", + m->path, de->d_name, strerror(-r)); + r = set_put_error(j->errors, r); + if (r < 0) + return r; + } } else if ((de->d_type == DT_DIR || de->d_type == DT_LNK || de->d_type == DT_UNKNOWN) && sd_id128_from_string(de->d_name, &id) >= 0) { @@ -1495,7 +1513,7 @@ static int remove_directory(sd_journal *j, Directory *d) { } static int add_search_paths(sd_journal *j) { - + int r; const char search_paths[] = "/run/log/journal\0" "/var/log/journal\0"; @@ -1506,8 +1524,11 @@ static int add_search_paths(sd_journal *j) { /* We ignore most errors here, since the idea is to only open * what's actually accessible, and ignore the rest. */ - NULSTR_FOREACH(p, search_paths) - add_root_directory(j, p); + NULSTR_FOREACH(p, search_paths) { + r = add_root_directory(j, p); + if (r < 0) + return set_put_error(j->errors, r); + } return 0; } @@ -1550,7 +1571,8 @@ static sd_journal *journal_new(int flags, const char *path) { j->files = hashmap_new(string_hash_func, string_compare_func); j->directories_by_path = hashmap_new(string_hash_func, string_compare_func); j->mmap = mmap_cache_new(); - if (!j->files || !j->directories_by_path || !j->mmap) + j->errors = set_new(trivial_hash_func, trivial_compare_func); + if (!j->files || !j->directories_by_path || !j->mmap || !j->errors) goto fail; return j; @@ -1607,8 +1629,10 @@ _public_ int sd_journal_open_directory(sd_journal **ret, const char *path, int f return -ENOMEM; r = add_root_directory(j, path); - if (r < 0) + if (r < 0) { + set_put_error(j->errors, r); goto fail; + } *ret = j; return 0; @@ -1650,6 +1674,7 @@ _public_ void sd_journal_close(sd_journal *j) { free(j->path); free(j->unique_field); + set_free(j->errors); free(j); } @@ -1968,8 +1993,11 @@ static void process_inotify_event(sd_journal *j, struct inotify_event *e) { if (e->mask & (IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB)) { r = add_file(j, d->path, e->name); - if (r < 0) - log_debug("Failed to add file %s/%s: %s", d->path, e->name, strerror(-r)); + if (r < 0) { + log_debug("Failed to add file %s/%s: %s", + d->path, e->name, strerror(-r)); + set_put_error(j->errors, r); + } } else if (e->mask & (IN_DELETE|IN_MOVED_FROM|IN_UNMOUNT)) { -- cgit v1.2.1 From 3ac251b81a41295a90c89c164f0d72ce6de651aa Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 23 Mar 2013 01:12:22 +0100 Subject: journalctl: various fixes to the access check logic - Reword messages a bit - Correct check whether EACCES is in the set of errors - Don't complain if no journal files are found - allocate Set object for errors lazily since in the best case we don't need it at all. - don't consider it an error if /run/log/journal doesn't exist (because that's the usual case actually, if storage is enabled) --- src/journal/journalctl.c | 42 ++++++++++++++++++++++-------------------- src/journal/sd-journal.c | 30 +++++++++++++++++++----------- 2 files changed, 41 insertions(+), 31 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 91dbde3ba1..0a82a1cf15 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -905,9 +905,9 @@ static int access_check_var_log_journal(sd_journal *j) { if (!have_access) { if (strv_isempty(g)) - log_notice("Hint: You are currently not seeing messages from other users and\n" - "the system. Users in the group 'systemd-journal' can see all messages.\n" - "Pass -q to turn this notice off."); + log_notice("Hint: You are currently not seeing messages from other users and the system.\n" + " Users in the 'systemd-journal' group can see all messages. Pass -q to\n" + " turn off this notice."); else { _cleanup_free_ char *s = NULL; @@ -923,8 +923,8 @@ static int access_check_var_log_journal(sd_journal *j) { return log_oom(); log_notice("Hint: You are currently not seeing messages from other users and the system.\n" - "Users in the groups '%s' can see all messages.\n" - "Pass -q to turn this notice off.", s); + " Users in the groups '%s' can see all messages.\n" + " Pass -q to turn off this notice.", s); } } @@ -933,29 +933,27 @@ static int access_check_var_log_journal(sd_journal *j) { #endif static int access_check(sd_journal *j) { - uint64_t eacces = EACCES, *code; Iterator it; + void *code; int r = 0; assert(j); - assert(j->errors); - assert(j->files); if (set_isempty(j->errors)) { if (hashmap_isempty(j->files)) - log_info("No journal files were found."); + log_notice("No journal files were found."); return 0; } - if (!set_contains(j->errors, &eacces)) { + if (set_contains(j->errors, INT_TO_PTR(-EACCES))) { #ifdef HAVE_ACL /* If /var/log/journal doesn't even exist, - unprivileged users have no access at all */ + * unprivileged users have no access at all */ if (access("/var/log/journal", F_OK) < 0 && geteuid() != 0 && in_group("systemd-journal") <= 0) { - log_error("Unprivileged users can't see messages unless persistent log storage\n" - "is enabled. Users in the group 'systemd-journal' can always see messages."); + log_error("Unprivileged users cannot access messages, unless persistent log storage is\n" + "enabled. Users in the 'systemd-journal' group may always access messages."); return -EACCES; } @@ -967,26 +965,30 @@ static int access_check(sd_journal *j) { return r; } #else - if (geteuid() != 0 && in_group("systemd-journal") <= 0) - log_error("No access to messages.\n" - "Users in the group 'systemd-journal' can see messages."); + if (geteuid() != 0 && in_group("systemd-journal") <= 0) { + log_error("Unprivileged users cannot access messages. Users in the 'systemd-journal' group\n" + "group may access messages."); + return -EACCES; + } #endif + if (hashmap_isempty(j->files)) { - log_error("No journal files were opened, due to insufficient permissions."); + log_error("No journal files were opened due to insufficient permissions."); r = -EACCES; } } SET_FOREACH(code, j->errors, it) { - int err = -PTR_TO_INT(code); + int err; + + err = -PTR_TO_INT(code); assert(err > 0); + if (err != EACCES) log_warning("Error was encountered while opening journal files: %s", strerror(err)); } - log_notice("Hint: run journalctl in debug mode: SYSTEMD_LOG_LEVEL=debug journalct ..."); - return r; } diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index c62ad811dc..f7f1777fef 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -51,11 +51,17 @@ /* We return an error here only if we didn't manage to memorize the real error. */ -static int set_put_error(Set* errors, int r) { +static int set_put_error(sd_journal *j, int r) { + int k; + if (r >= 0) return r; - return set_put(errors, INT_TO_PTR(r)); + k = set_ensure_allocated(&j->errors, trivial_hash_func, trivial_compare_func); + if (k < 0) + return k; + + return set_put(j->errors, INT_TO_PTR(r)); } static void detach_location(sd_journal *j) { @@ -1248,7 +1254,7 @@ static int add_file(sd_journal *j, const char *prefix, const char *filename) { if (hashmap_size(j->files) >= JOURNAL_FILES_MAX) { log_debug("Too many open journal files, not adding %s, ignoring.", path); - return set_put_error(j->errors, -ETOOMANYREFS); + return set_put_error(j, -ETOOMANYREFS); } r = journal_file_open(path, O_RDONLY, 0, false, false, NULL, j->mmap, NULL, &f); @@ -1392,7 +1398,7 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname) if (r < 0) { log_debug("Failed to add file %s/%s: %s", m->path, de->d_name, strerror(-r)); - r = set_put_error(j->errors, r); + r = set_put_error(j, r); if (r < 0) return r; } @@ -1471,7 +1477,7 @@ static int add_root_directory(sd_journal *j, const char *p) { if (r < 0) { log_debug("Failed to add file %s/%s: %s", m->path, de->d_name, strerror(-r)); - r = set_put_error(j->errors, r); + r = set_put_error(j, r); if (r < 0) return r; } @@ -1526,8 +1532,11 @@ static int add_search_paths(sd_journal *j) { NULSTR_FOREACH(p, search_paths) { r = add_root_directory(j, p); - if (r < 0) - return set_put_error(j->errors, r); + if (r < 0 && r != -ENOENT) { + r = set_put_error(j, r); + if (r < 0) + return r; + } } return 0; @@ -1571,8 +1580,7 @@ static sd_journal *journal_new(int flags, const char *path) { j->files = hashmap_new(string_hash_func, string_compare_func); j->directories_by_path = hashmap_new(string_hash_func, string_compare_func); j->mmap = mmap_cache_new(); - j->errors = set_new(trivial_hash_func, trivial_compare_func); - if (!j->files || !j->directories_by_path || !j->mmap || !j->errors) + if (!j->files || !j->directories_by_path || !j->mmap) goto fail; return j; @@ -1630,7 +1638,7 @@ _public_ int sd_journal_open_directory(sd_journal **ret, const char *path, int f r = add_root_directory(j, path); if (r < 0) { - set_put_error(j->errors, r); + set_put_error(j, r); goto fail; } @@ -1996,7 +2004,7 @@ static void process_inotify_event(sd_journal *j, struct inotify_event *e) { if (r < 0) { log_debug("Failed to add file %s/%s: %s", d->path, e->name, strerror(-r)); - set_put_error(j->errors, r); + set_put_error(j, r); } } else if (e->mask & (IN_DELETE|IN_MOVED_FROM|IN_UNMOUNT)) { -- cgit v1.2.1 From 54b1da83ed8cadde4a53b541a48ce303ade862f7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 23 Mar 2013 04:11:23 +0100 Subject: journal: don't access j->files after use https://bugs.freedesktop.org/show_bug.cgi?id=62605 --- src/journal/sd-journal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/journal') diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index f7f1777fef..82cacf3674 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -1658,6 +1658,8 @@ _public_ void sd_journal_close(sd_journal *j) { if (!j) return; + sd_journal_flush_matches(j); + while ((f = hashmap_steal_first(j->files))) journal_file_close(f); @@ -1675,8 +1677,6 @@ _public_ void sd_journal_close(sd_journal *j) { if (j->inotify_fd >= 0) close_nointr_nofail(j->inotify_fd); - sd_journal_flush_matches(j); - if (j->mmap) mmap_cache_unref(j->mmap); -- cgit v1.2.1 From 7964dfca1b6c4b37d069b3713f9f1b11219c3474 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 23 Mar 2013 21:02:59 +0100 Subject: journald: remove unconditional log_*() use in the main loop Setting MaxRetentionSec= caused the kernel log to overflow and the journal daemon to enter an endless loop. Logging from the journald main loop gets directed to /dev/kmsg, which wakes up journald again. We skip the import of this message by checking for our own PID, but this still causes the main loop to never go to sleep again because we never stopped logging from there. --- src/journal/journald.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/journald.c b/src/journal/journald.c index d6b9be5974..5fb10b1d3f 100644 --- a/src/journal/journald.c +++ b/src/journal/journald.c @@ -88,7 +88,6 @@ int main(int argc, char *argv[]) { /* Calculate when to rotate the next time */ t = (int) ((server.oldest_file_usec + server.max_retention_usec - n + USEC_PER_MSEC - 1) / USEC_PER_MSEC); - log_info("Sleeping for %i ms", t); } #ifdef HAVE_GCRYPT -- cgit v1.2.1 From 26687bf8a907009dedcff79346860ed41511405e Mon Sep 17 00:00:00 2001 From: Oleksii Shevchuk Date: Mon, 25 Mar 2013 18:49:03 +0200 Subject: journal: Add sync timer to journal server Add option to force journal sync with fsync. Default timeout is 5min. Interval configured via SyncIntervalSec option at journal.conf. Synced journal files will be marked as OFFLINE. Manual sync can be performed via sending SIGUSR1. --- src/journal/journal-file.c | 63 +++++++++++++++++----- src/journal/journal-file.h | 2 + src/journal/journald-gperf.gperf | 1 + src/journal/journald-server.c | 112 +++++++++++++++++++++++++++++++++++++-- src/journal/journald-server.h | 6 +++ src/journal/journald.conf | 1 + 6 files changed, 169 insertions(+), 16 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index 13fc8edea9..5b077be0da 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -68,6 +68,50 @@ /* How many entries to keep in the entry array chain cache at max */ #define CHAIN_CACHE_MAX 20 +int journal_file_set_online(JournalFile *f) { + assert(f); + + if (!f->writable) + return -EPERM; + + if (!(f->fd >= 0 && f->header)) + return -EINVAL; + + switch(f->header->state) { + case STATE_ONLINE: + return 0; + + case STATE_OFFLINE: + f->header->state = STATE_ONLINE; + fsync(f->fd); + return 0; + + default: + return -EINVAL; + } +} + +int journal_file_set_offline(JournalFile *f) { + assert(f); + + if (!f->writable) + return -EPERM; + + if (!(f->fd >= 0 && f->header)) + return -EINVAL; + + if (f->header->state != STATE_ONLINE) + return 0; + + fsync(f->fd); + + f->header->state = STATE_OFFLINE; + + fsync(f->fd); + + return 0; +} + void journal_file_close(JournalFile *f) { assert(f); @@ -81,16 +125,10 @@ void journal_file_close(JournalFile *f) { if (f->mmap && f->fd >= 0) mmap_cache_close_fd(f->mmap, f->fd); - if (f->writable && f->fd >= 0) - fdatasync(f->fd); - - if (f->header) { - /* Mark the file offline. Don't override the archived state if it already is set */ - if (f->writable && f->header->state == STATE_ONLINE) - f->header->state = STATE_OFFLINE; + journal_file_set_offline(f); + if (f->header) munmap(f->header, PAGE_ALIGN(sizeof(Header))); - } if (f->fd >= 0) close_nointr_nofail(f->fd); @@ -177,7 +215,7 @@ static int journal_file_refresh_header(JournalFile *f) { f->header->boot_id = boot_id; - f->header->state = STATE_ONLINE; + journal_file_set_online(f); /* Sync the online state to disk */ msync(f->header, PAGE_ALIGN(sizeof(Header)), MS_SYNC); @@ -457,6 +495,10 @@ int journal_file_append_object(JournalFile *f, int type, uint64_t size, Object * assert(offset); assert(ret); + r = journal_file_set_online(f); + if (r < 0) + return r; + p = le64toh(f->header->tail_object_offset); if (p == 0) p = le64toh(f->header->header_size); @@ -1267,9 +1309,6 @@ int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const st assert(f); assert(iovec || n_iovec == 0); - if (!f->writable) - return -EPERM; - if (!ts) { dual_timestamp_get(&_ts); ts = &_ts; diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h index cdbc8e41f6..0eab5017d7 100644 --- a/src/journal/journal-file.h +++ b/src/journal/journal-file.h @@ -106,6 +106,8 @@ int journal_file_open( JournalFile *template, JournalFile **ret); +int journal_file_set_offline(JournalFile *f); +int journal_file_set_online(JournalFile *f); void journal_file_close(JournalFile *j); int journal_file_open_reliably( diff --git a/src/journal/journald-gperf.gperf b/src/journal/journald-gperf.gperf index 1baef1411c..57b45f9232 100644 --- a/src/journal/journald-gperf.gperf +++ b/src/journal/journald-gperf.gperf @@ -18,6 +18,7 @@ struct ConfigPerfItem; Journal.Storage, config_parse_storage, 0, offsetof(Server, storage) Journal.Compress, config_parse_bool, 0, offsetof(Server, compress) Journal.Seal, config_parse_bool, 0, offsetof(Server, seal) +Journal.SyncIntervalSec, config_parse_usec, 0, offsetof(Server, sync_interval_usec) Journal.RateLimitInterval, config_parse_usec, 0, offsetof(Server, rate_limit_interval) Journal.RateLimitBurst, config_parse_unsigned, 0, offsetof(Server, rate_limit_burst) Journal.SystemMaxUse, config_parse_bytes_off, 0, offsetof(Server, system_metrics.max_use) diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 855430a6ba..a9d7aa181d 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -67,6 +68,7 @@ #define USER_JOURNALS_MAX 1024 +#define DEFAULT_SYNC_INTERVAL_USEC (5*USEC_PER_MINUTE) #define DEFAULT_RATE_LIMIT_INTERVAL (10*USEC_PER_SEC) #define DEFAULT_RATE_LIMIT_BURST 200 @@ -344,6 +346,33 @@ void server_rotate(Server *s) { } } +void server_sync(Server *s) { + JournalFile *f; + void *k; + Iterator i; + int r; + + static const struct itimerspec sync_timer_disable = {}; + + if (s->system_journal) { + r = journal_file_set_offline(s->system_journal); + if (r < 0) + log_error("Failed to sync system journal: %s", strerror(-r)); + } + + HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) { + r = journal_file_set_offline(f); + if (r < 0) + log_error("Failed to sync user journal: %s", strerror(-r)); + } + + r = timerfd_settime(s->sync_timer_fd, 0, &sync_timer_disable, NULL); + if (r < 0) + log_error("Failed to disable max timer: %m"); + + s->sync_scheduled = false; +} + void server_vacuum(Server *s) { char *p; char ids[33]; @@ -475,8 +504,10 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned } r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL); - if (r >= 0) + if (r >= 0) { + server_schedule_sync(s); return; + } if (vacuumed || !shall_try_append_again(f, r)) { log_error("Failed to write entry, ignoring: %s", strerror(-r)); @@ -990,11 +1021,10 @@ int process_event(Server *s, struct epoll_event *ev) { return -errno; } - log_info("Received SIG%s", signal_to_string(sfsi.ssi_signo)); - if (sfsi.ssi_signo == SIGUSR1) { touch("/run/systemd/journal/flushed"); server_flush_to_var(s); + server_sync(s); return 1; } @@ -1004,8 +1034,23 @@ int process_event(Server *s, struct epoll_event *ev) { return 1; } + log_info("Received SIG%s", signal_to_string(sfsi.ssi_signo)); + return 0; + } else if (ev->data.fd == s->sync_timer_fd) { + int r; + uint64_t t; + + log_debug("Got sync request from epoll."); + + r = read(ev->data.fd, (void *)&t, sizeof(t)); + if (r < 0) + return 0; + + server_sync(s); + return 1; + } else if (ev->data.fd == s->dev_kmsg_fd) { int r; @@ -1285,16 +1330,68 @@ static int server_parse_config_file(Server *s) { return r; } +static int server_open_sync_timer(Server *s) { + int r; + struct epoll_event ev; + + assert(s); + + s->sync_timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); + if (s->sync_timer_fd < 0) + return -errno; + + zero(ev); + ev.events = EPOLLIN; + ev.data.fd = s->sync_timer_fd; + + r = epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->sync_timer_fd, &ev); + if (r < 0) { + log_error("Failed to add idle timer fd to epoll object: %m"); + return -errno; + } + + return 0; +} + +int server_schedule_sync(Server *s) { + int r; + + struct itimerspec sync_timer_enable; + + assert(s); + + if (s->sync_scheduled) + return 0; + + if (s->sync_interval_usec) { + zero(sync_timer_enable); + sync_timer_enable.it_value.tv_sec = s->sync_interval_usec / USEC_PER_SEC; + sync_timer_enable.it_value.tv_nsec = s->sync_interval_usec % MSEC_PER_SEC; + + r = timerfd_settime(s->sync_timer_fd, 0, &sync_timer_enable, NULL); + if (r < 0) + return -errno; + } + + s->sync_scheduled = true; + + return 0; +} + int server_init(Server *s) { int n, r, fd; assert(s); zero(*s); - s->syslog_fd = s->native_fd = s->stdout_fd = s->signal_fd = s->epoll_fd = s->dev_kmsg_fd = -1; + s->sync_timer_fd = s->syslog_fd = s->native_fd = s->stdout_fd = + s->signal_fd = s->epoll_fd = s->dev_kmsg_fd = -1; s->compress = true; s->seal = true; + s->sync_interval_usec = DEFAULT_SYNC_INTERVAL_USEC; + s->sync_scheduled = false; + s->rate_limit_interval = DEFAULT_RATE_LIMIT_INTERVAL; s->rate_limit_burst = DEFAULT_RATE_LIMIT_BURST; @@ -1394,6 +1491,10 @@ int server_init(Server *s) { if (r < 0) return r; + r = server_open_sync_timer(s); + if (r < 0) + return r; + r = open_signalfd(s); if (r < 0) return r; @@ -1466,6 +1567,9 @@ void server_done(Server *s) { if (s->dev_kmsg_fd >= 0) close_nointr_nofail(s->dev_kmsg_fd); + if (s->sync_timer_fd >= 0) + close_nointr_nofail(s->sync_timer_fd); + if (s->rate_limit) journal_rate_limit_free(s->rate_limit); diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h index 9f50a29e50..21edd6bdaf 100644 --- a/src/journal/journald-server.h +++ b/src/journal/journald-server.h @@ -71,6 +71,7 @@ typedef struct Server { size_t buffer_size; JournalRateLimit *rate_limit; + usec_t sync_interval_usec; usec_t rate_limit_interval; unsigned rate_limit_burst; @@ -119,6 +120,9 @@ typedef struct Server { uint64_t *kernel_seqnum; struct udev *udev; + + int sync_timer_fd; + bool sync_scheduled; } Server; #define N_IOVEC_META_FIELDS 17 @@ -145,8 +149,10 @@ void server_fix_perms(Server *s, JournalFile *f, uid_t uid); bool shall_try_append_again(JournalFile *f, int r); int server_init(Server *s); void server_done(Server *s); +void server_sync(Server *s); void server_vacuum(Server *s); void server_rotate(Server *s); +int server_schedule_sync(Server *s); int server_flush_to_var(Server *s); int process_event(Server *s, struct epoll_event *ev); void server_maybe_append_tags(Server *s); diff --git a/src/journal/journald.conf b/src/journal/journald.conf index 948318bc62..5410477201 100644 --- a/src/journal/journald.conf +++ b/src/journal/journald.conf @@ -12,6 +12,7 @@ #Compress=yes #Seal=yes #SplitMode=login +#SyncIntervalSec=5m #RateLimitInterval=10s #RateLimitBurst=200 #SystemMaxUse= -- cgit v1.2.1 From 2e8fb7026d3c560194cfe9f83935ce0b16263da0 Mon Sep 17 00:00:00 2001 From: Lukas Nykryn Date: Wed, 27 Mar 2013 10:44:21 +0100 Subject: log: fix error codes handling in catalog_list_items It does not make sense to print error code from previous loop. --- src/journal/catalog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/journal') diff --git a/src/journal/catalog.c b/src/journal/catalog.c index dacf5c50a1..6b195f6920 100644 --- a/src/journal/catalog.c +++ b/src/journal/catalog.c @@ -616,7 +616,7 @@ int catalog_list_items(FILE *f, bool oneline, char **items) { k = sd_id128_from_string(*item, &id); if (k < 0) { log_error("Failed to parse id128 '%s': %s", - *item, strerror(-r)); + *item, strerror(-k)); if (r < 0) r = k; continue; @@ -626,7 +626,7 @@ int catalog_list_items(FILE *f, bool oneline, char **items) { if (k < 0) { log_full(k == -ENOENT ? LOG_NOTICE : LOG_ERR, "Failed to retrieve catalog entry for '%s': %s", - *item, strerror(-r)); + *item, strerror(-k)); if (r < 0) r = k; continue; -- cgit v1.2.1 From 464264ac5a35b655065c5d95b8d8ffbbc7ff3bcf Mon Sep 17 00:00:00 2001 From: Lukas Nykryn Date: Wed, 27 Mar 2013 17:35:55 +0100 Subject: catalog: fix error codes handling in catalog_list_items Previously r was set to zero and so if(r<0) was never true. --- src/journal/catalog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/journal') diff --git a/src/journal/catalog.c b/src/journal/catalog.c index 6b195f6920..7ae7b3eecf 100644 --- a/src/journal/catalog.c +++ b/src/journal/catalog.c @@ -617,7 +617,7 @@ int catalog_list_items(FILE *f, bool oneline, char **items) { if (k < 0) { log_error("Failed to parse id128 '%s': %s", *item, strerror(-k)); - if (r < 0) + if (r == 0) r = k; continue; } @@ -627,7 +627,7 @@ int catalog_list_items(FILE *f, bool oneline, char **items) { log_full(k == -ENOENT ? LOG_NOTICE : LOG_ERR, "Failed to retrieve catalog entry for '%s': %s", *item, strerror(-k)); - if (r < 0) + if (r == 0) r = k; continue; } -- cgit v1.2.1 From 5e75606a419059e6fbd8705b0b60c183c8aca246 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 28 Mar 2013 22:09:28 -0400 Subject: coredump: do not free twice --- src/journal/coredump.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/journal') diff --git a/src/journal/coredump.c b/src/journal/coredump.c index bada8487c4..c56d283268 100644 --- a/src/journal/coredump.c +++ b/src/journal/coredump.c @@ -95,15 +95,15 @@ static int divert_coredump(void) { int main(int argc, char* argv[]) { int r, j = 0; - _cleanup_free_ char *p = NULL; + char *t; ssize_t n; pid_t pid; uid_t uid; gid_t gid; struct iovec iovec[14]; - _cleanup_free_ char *core_pid = NULL, *core_uid = NULL, *core_gid = NULL, *core_signal = NULL, + char _cleanup_free_ *core_pid = NULL, *core_uid = NULL, *core_gid = NULL, *core_signal = NULL, *core_timestamp = NULL, *core_comm = NULL, *core_exe = NULL, *core_unit = NULL, - *core_session = NULL, *core_message = NULL, *core_cmdline = NULL, *t = NULL; + *core_session = NULL, *core_message = NULL, *core_cmdline = NULL, *p = NULL; prctl(PR_SET_DUMPABLE, 0); -- cgit v1.2.1 From 18cd5fe99f70a55a2d6f2303d6ee0624942695b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 27 Mar 2013 23:16:32 -0400 Subject: catalog: make sure strings are terminated Coverity complains: systemd-199/src/journal/catalog.c:126: buffer_size_warning: Calling strncpy with a maximum size argument of 32 bytes on destination array "i->language" of size 32 bytes might leave the destination string unterminated. ...and unfortunately it was right. The string was defined as a fixed-size string in some parts of the code, and used a null-terminated string in others (e.g. in log statements). There's no point in conserving one byte, so just define the max language tag length to 31 bytes, and use null terminated strings everywhere. Also, wrap some lines, zero-fill less bytes, use '\0' instead of just 0 to be more explicit that this is one byte. --- src/journal/catalog.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'src/journal') diff --git a/src/journal/catalog.c b/src/journal/catalog.c index 7ae7b3eecf..b2c684ac2d 100644 --- a/src/journal/catalog.c +++ b/src/journal/catalog.c @@ -34,6 +34,7 @@ #include "hashmap.h" #include "strv.h" #include "strbuf.h" +#include "strxcpyx.h" #include "conf-files.h" #include "mkdir.h" #include "catalog.h" @@ -96,7 +97,7 @@ static int catalog_compare_func(const void *a, const void *b) { return 1; } - return strncmp(i->language, j->language, sizeof(i->language)); + return strcmp(i->language, j->language); } static int finish_item( @@ -123,12 +124,13 @@ static int finish_item( return log_oom(); i->id = id; - strncpy(i->language, language, sizeof(i->language)); + strscpy(i->language, sizeof(i->language), language); i->offset = htole64((uint64_t) offset); r = hashmap_put(h, i, i); if (r == EEXIST) { - log_warning("Duplicate entry for " SD_ID128_FORMAT_STR ".%s, ignoring.", SD_ID128_FORMAT_VAL(id), language ? language : "C"); + log_warning("Duplicate entry for " SD_ID128_FORMAT_STR ".%s, ignoring.", + SD_ID128_FORMAT_VAL(id), language ? language : "C"); free(i); return 0; } @@ -185,15 +187,15 @@ static int import_file(Hashmap *h, struct strbuf *sb, const char *path) { line[0] == '-' && line[1] == '-' && line[2] == ' ' && - (line[2+1+32] == ' ' || line[2+1+32] == 0)) { + (line[2+1+32] == ' ' || line[2+1+32] == '\0')) { bool with_language; sd_id128_t jd; /* New entry */ - with_language = line[2+1+32] != 0; - line[2+1+32] = 0; + with_language = line[2+1+32] != '\0'; + line[2+1+32] = '\0'; if (sd_id128_from_string(line + 2 + 1, &jd) >= 0) { @@ -211,21 +213,21 @@ static int import_file(Hashmap *h, struct strbuf *sb, const char *path) { log_error("[%s:%u] Language too short.", path, n); return -EINVAL; } - if (c > sizeof(language)) { + if (c > sizeof(language) - 1) { log_error("[%s:%u] language too long.", path, n); return -EINVAL; } - strncpy(language, t, sizeof(language)); + strscpy(language, sizeof(language), t); } else - zero(language); + language[0] = '\0'; got_id = true; empty_line = false; id = jd; if (payload) - payload[0] = 0; + payload[0] = '\0'; continue; } @@ -324,7 +326,9 @@ int catalog_update(void) { n = 0; HASHMAP_FOREACH(i, h, j) { - log_debug("Found " SD_ID128_FORMAT_STR ", language %s", SD_ID128_FORMAT_VAL(i->id), isempty(i->language) ? "C" : i->language); + log_debug("Found " SD_ID128_FORMAT_STR ", language %s", + SD_ID128_FORMAT_VAL(i->id), + isempty(i->language) ? "C" : i->language); items[n++] = *i; } -- cgit v1.2.1 From 844ec79b3c2f246114ea316ebe1f36044bdb688e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 28 Mar 2013 20:17:24 -0400 Subject: catalog: open up catalog internals In order to write tests for the catalog functions, they are made non-static and start taking a 'database' parameter, which is the name of a file with the preprocessed catalog entries. This makes it possible to make test-catalog part of the normal test suite, since it now only operates on files in /tmp. Some more tests are added. --- src/journal/catalog.c | 188 ++++++++++++++++++++++++--------------------- src/journal/catalog.h | 16 ++-- src/journal/journalctl.c | 32 ++++---- src/journal/sd-journal.c | 4 +- src/journal/test-catalog.c | 99 ++++++++++++++++++++++-- 5 files changed, 224 insertions(+), 115 deletions(-) (limited to 'src/journal') diff --git a/src/journal/catalog.c b/src/journal/catalog.c index b2c684ac2d..ebf0622609 100644 --- a/src/journal/catalog.c +++ b/src/journal/catalog.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "util.h" #include "log.h" @@ -39,7 +40,7 @@ #include "mkdir.h" #include "catalog.h" -static const char * const conf_file_dirs[] = { +const char * const catalog_file_dirs[] = { "/usr/local/lib/systemd/catalog/", "/usr/lib/systemd/catalog/", NULL @@ -62,7 +63,7 @@ typedef struct CatalogItem { le64_t offset; } CatalogItem; -static unsigned catalog_hash_func(const void *p) { +unsigned catalog_hash_func(const void *p) { const CatalogItem *i = p; assert_cc(sizeof(unsigned) == sizeof(uint8_t)*4); @@ -86,7 +87,7 @@ static unsigned catalog_hash_func(const void *p) { string_hash_func(i->language); } -static int catalog_compare_func(const void *a, const void *b) { +int catalog_compare_func(const void *a, const void *b) { const CatalogItem *i = a, *j = b; unsigned k; @@ -138,7 +139,7 @@ static int finish_item( return 0; } -static int import_file(Hashmap *h, struct strbuf *sb, const char *path) { +int catalog_import_file(Hashmap *h, struct strbuf *sb, const char *path) { _cleanup_fclose_ FILE *f = NULL; _cleanup_free_ char *payload = NULL; unsigned n = 0; @@ -271,34 +272,99 @@ static int import_file(Hashmap *h, struct strbuf *sb, const char *path) { return 0; } -#define CATALOG_DATABASE CATALOG_PATH "/database" +static long write_catalog(const char *database, Hashmap *h, struct strbuf *sb, + CatalogItem *items, size_t n) { + CatalogHeader header; + _cleanup_fclose_ FILE *w = NULL; + int r; + char _cleanup_free_ *d, *p = NULL; + size_t k; + + d = dirname_malloc(database); + if (!d) + return log_oom(); + + r = mkdir_p(d, 0775); + if (r < 0) { + log_error("Recursive mkdir %s: %s", d, strerror(-r)); + return r; + } + + r = fopen_temporary(database, &w, &p); + if (r < 0) { + log_error("Failed to open database for writing: %s: %s", + database, strerror(-r)); + return r; + } + + zero(header); + memcpy(header.signature, CATALOG_SIGNATURE, sizeof(header.signature)); + header.header_size = htole64(ALIGN_TO(sizeof(CatalogHeader), 8)); + header.catalog_item_size = htole64(sizeof(CatalogItem)); + header.n_items = htole64(hashmap_size(h)); -int catalog_update(void) { + r = -EIO; + + k = fwrite(&header, 1, sizeof(header), w); + if (k != sizeof(header)) { + log_error("%s: failed to write header.", p); + goto error; + } + + k = fwrite(items, 1, n * sizeof(CatalogItem), w); + if (k != n * sizeof(CatalogItem)) { + log_error("%s: failed to write database.", p); + goto error; + } + + k = fwrite(sb->buf, 1, sb->len, w); + if (k != sb->len) { + log_error("%s: failed to write strings.", p); + goto error; + } + + fflush(w); + + if (ferror(w)) { + log_error("%s: failed to write database.", p); + goto error; + } + + fchmod(fileno(w), 0644); + + if (rename(p, database) < 0) { + log_error("rename (%s -> %s) failed: %m", p, database); + r = -errno; + goto error; + } + + return ftell(w); + +error: + unlink(p); + return r; +} + +int catalog_update(const char* database, const char* root, const char* const* dirs) { _cleanup_strv_free_ char **files = NULL; - _cleanup_fclose_ FILE *w = NULL; - _cleanup_free_ char *p = NULL; char **f; Hashmap *h; struct strbuf *sb = NULL; _cleanup_free_ CatalogItem *items = NULL; CatalogItem *i; - CatalogHeader header; - size_t k; Iterator j; unsigned n; - int r; + long r; h = hashmap_new(catalog_hash_func, catalog_compare_func); - if (!h) - return -ENOMEM; - sb = strbuf_new(); - if (!sb) { + + if (!h || !sb) { r = log_oom(); goto finish; } - r = conf_files_list_strv(&files, ".catalog", NULL, (const char **) conf_file_dirs); + r = conf_files_list_strv(&files, ".catalog", root, dirs); if (r < 0) { log_error("Failed to get catalog files: %s", strerror(-r)); goto finish; @@ -306,7 +372,7 @@ int catalog_update(void) { STRV_FOREACH(f, files) { log_debug("reading file '%s'", *f); - import_file(h, sb, *f); + catalog_import_file(h, sb, *f); } if (hashmap_size(h) <= 0) { @@ -335,79 +401,25 @@ int catalog_update(void) { assert(n == hashmap_size(h)); qsort(items, n, sizeof(CatalogItem), catalog_compare_func); - r = mkdir_p(CATALOG_PATH, 0775); - if (r < 0) { - log_error("Recursive mkdir %s: %s", CATALOG_PATH, strerror(-r)); - goto finish; - } - - r = fopen_temporary(CATALOG_DATABASE, &w, &p); - if (r < 0) { - log_error("Failed to open database for writing: %s: %s", - CATALOG_DATABASE, strerror(-r)); - goto finish; - } - - zero(header); - memcpy(header.signature, CATALOG_SIGNATURE, sizeof(header.signature)); - header.header_size = htole64(ALIGN_TO(sizeof(CatalogHeader), 8)); - header.catalog_item_size = htole64(sizeof(CatalogItem)); - header.n_items = htole64(hashmap_size(h)); - - k = fwrite(&header, 1, sizeof(header), w); - if (k != sizeof(header)) { - log_error("%s: failed to write header.", p); - goto finish; - } - - k = fwrite(items, 1, n * sizeof(CatalogItem), w); - if (k != n * sizeof(CatalogItem)) { - log_error("%s: failed to write database.", p); - goto finish; - } - - k = fwrite(sb->buf, 1, sb->len, w); - if (k != sb->len) { - log_error("%s: failed to write strings.", p); - goto finish; - } - - fflush(w); - - if (ferror(w)) { - log_error("%s: failed to write database.", p); - goto finish; - } - - fchmod(fileno(w), 0644); - - if (rename(p, CATALOG_DATABASE) < 0) { - log_error("rename (%s -> %s) failed: %m", p, CATALOG_DATABASE); - r = -errno; - goto finish; - } - - log_debug("%s: wrote %u items, with %zu bytes of strings, %ld total size.", - CATALOG_DATABASE, n, sb->len, ftell(w)); - - free(p); - p = NULL; + r = write_catalog(database, h, sb, items, n); + if (r < 0) + log_error("Failed to write %s: %s", database, strerror(-r)); + else + log_debug("%s: wrote %u items, with %zu bytes of strings, %ld total size.", + database, n, sb->len, r); r = 0; finish: - hashmap_free_free(h); - + if (h) + hashmap_free_free(h); if (sb) strbuf_cleanup(sb); - if (p) - unlink(p); - - return r; + return r < 0 ? r : 0; } -static int open_mmap(int *_fd, struct stat *_st, void **_p) { +static int open_mmap(const char *database, int *_fd, struct stat *_st, void **_p) { const CatalogHeader *h; int fd; void *p; @@ -417,7 +429,7 @@ static int open_mmap(int *_fd, struct stat *_st, void **_p) { assert(_st); assert(_p); - fd = open(CATALOG_DATABASE, O_RDONLY|O_CLOEXEC); + fd = open(database, O_RDONLY|O_CLOEXEC); if (fd < 0) return -errno; @@ -495,7 +507,7 @@ static const char *find_id(void *p, sd_id128_t id) { le64toh(f->offset); } -int catalog_get(sd_id128_t id, char **_text) { +int catalog_get(const char* database, sd_id128_t id, char **_text) { _cleanup_close_ int fd = -1; void *p = NULL; struct stat st; @@ -505,7 +517,7 @@ int catalog_get(sd_id128_t id, char **_text) { assert(_text); - r = open_mmap(&fd, &st, &p); + r = open_mmap(database, &fd, &st, &p); if (r < 0) return r; @@ -571,7 +583,7 @@ static void dump_catalog_entry(FILE *f, sd_id128_t id, const char *s, bool oneli } -int catalog_list(FILE *f, bool oneline) { +int catalog_list(FILE *f, const char *database, bool oneline) { _cleanup_close_ int fd = -1; void *p = NULL; struct stat st; @@ -582,7 +594,7 @@ int catalog_list(FILE *f, bool oneline) { sd_id128_t last_id; bool last_id_set = false; - r = open_mmap(&fd, &st, &p); + r = open_mmap(database, &fd, &st, &p); if (r < 0) return r; @@ -608,7 +620,7 @@ int catalog_list(FILE *f, bool oneline) { return 0; } -int catalog_list_items(FILE *f, bool oneline, char **items) { +int catalog_list_items(FILE *f, const char *database, bool oneline, char **items) { char **item; int r = 0; @@ -626,7 +638,7 @@ int catalog_list_items(FILE *f, bool oneline, char **items) { continue; } - k = catalog_get(id, &msg); + k = catalog_get(database, id, &msg); if (k < 0) { log_full(k == -ENOENT ? LOG_NOTICE : LOG_ERR, "Failed to retrieve catalog entry for '%s': %s", diff --git a/src/journal/catalog.h b/src/journal/catalog.h index 8ea2c41c2d..89f8f93d03 100644 --- a/src/journal/catalog.h +++ b/src/journal/catalog.h @@ -24,8 +24,14 @@ #include #include "sd-id128.h" - -int catalog_update(void); -int catalog_get(sd_id128_t id, char **data); -int catalog_list(FILE *f, bool oneline); -int catalog_list_items(FILE *f, bool oneline, char **items); +#include "hashmap.h" +#include "strbuf.h" + +int catalog_import_file(Hashmap *h, struct strbuf *sb, const char *path); +unsigned catalog_hash_func(const void *p); +int catalog_compare_func(const void *a, const void *b); +int catalog_update(const char* database, const char* root, const char* const* dirs); +int catalog_get(const char* database, sd_id128_t id, char **data); +int catalog_list(FILE *f, const char* database, bool oneline); +int catalog_list_items(FILE *f, const char* database, bool oneline, char **items); +extern const char * const catalog_file_dirs[]; diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 0a82a1cf15..03daafe9db 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -1020,20 +1020,26 @@ int main(int argc, char *argv[]) { goto finish; } - if (arg_action == ACTION_LIST_CATALOG || - arg_action == ACTION_DUMP_CATALOG) { - bool oneline = arg_action == ACTION_LIST_CATALOG; - if (optind < argc) - r = catalog_list_items(stdout, oneline, argv + optind); - else - r = catalog_list(stdout, oneline); - if (r < 0) - log_error("Failed to list catalog: %s", strerror(-r)); - goto finish; - } + if (arg_action == ACTION_UPDATE_CATALOG || + arg_action == ACTION_LIST_CATALOG || + arg_action == ACTION_DUMP_CATALOG) { + + if (arg_action == ACTION_UPDATE_CATALOG) { + r = catalog_update(CATALOG_DATABASE, NULL, catalog_file_dirs); + if (r < 0) + log_error("Failed to list catalog: %s", strerror(-r)); + } else { + bool oneline = arg_action == ACTION_LIST_CATALOG; + + if (optind < argc) + r = catalog_list_items(stdout, CATALOG_DATABASE, + oneline, argv + optind); + else + r = catalog_list(stdout, CATALOG_DATABASE, oneline); + if (r < 0) + log_error("Failed to list catalog: %s", strerror(-r)); + } - if (arg_action == ACTION_UPDATE_CATALOG) { - r = catalog_update(); goto finish; } diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 82cacf3674..bb99671934 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -2439,7 +2439,7 @@ _public_ int sd_journal_get_catalog(sd_journal *j, char **ret) { if (r < 0) return r; - r = catalog_get(id, &text); + r = catalog_get(CATALOG_DATABASE, id, &text); if (r < 0) return r; @@ -2455,7 +2455,7 @@ _public_ int sd_journal_get_catalog_for_message_id(sd_id128_t id, char **ret) { if (!ret) return -EINVAL; - return catalog_get(id, ret); + return catalog_get(CATALOG_DATABASE, id, ret); } _public_ int sd_journal_set_data_threshold(sd_journal *j, size_t sz) { diff --git a/src/journal/test-catalog.c b/src/journal/test-catalog.c index c75b1464fe..21149f18a5 100644 --- a/src/journal/test-catalog.c +++ b/src/journal/test-catalog.c @@ -4,6 +4,7 @@ This file is part of systemd. Copyright 2012 Lennart Poettering + Copyright 2013 Zbigniew Jędrzejewski-Szmek systemd is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -20,31 +21,115 @@ ***/ #include +#include +#include +#include #include "util.h" #include "log.h" -#include "catalog.h" +#include "macro.h" #include "sd-messages.h" +#include "catalog.h" -int main(int argc, char *argv[]) { +static void test_import(Hashmap *h, struct strbuf *sb, + const char* contents, ssize_t size, int code) { + int r; + char name[] = "/tmp/test-catalog.XXXXXX"; + int _cleanup_close_ fd = mkstemp(name); + assert(fd >= 0); + assert_se(write(fd, contents, size) == size); + + r = catalog_import_file(h, sb, name); + assert(r == code); + + unlink(name); +} + +static void test_catalog_importing(void) { + Hashmap *h; + struct strbuf *sb; + + assert_se(h = hashmap_new(catalog_hash_func, catalog_compare_func)); + assert_se(sb = strbuf_new()); + +#define BUF "xxx" + test_import(h, sb, BUF, sizeof(BUF), -EINVAL); +#undef BUF + assert(hashmap_isempty(h)); + log_debug("----------------------------------------"); + +#define BUF \ +"-- 0027229ca0644181a76c4e92458afaff dededededededededededededededede\n" \ +"Subject: message\n" \ +"\n" \ +"payload\n" + test_import(h, sb, BUF, sizeof(BUF), -EINVAL); +#undef BUF + + log_debug("----------------------------------------"); + +#define BUF \ +"-- 0027229ca0644181a76c4e92458afaff dededededededededededededededed\n" \ +"Subject: message\n" \ +"\n" \ +"payload\n" + test_import(h, sb, BUF, sizeof(BUF), 0); +#undef BUF + + assert(hashmap_size(h) == 1); + log_debug("----------------------------------------"); + + hashmap_free_free(h); + strbuf_cleanup(sb); +} + + +static const char* database = NULL; + +static void test_catalog_update(void) { + int r; + char _cleanup_free_ *path = NULL; + + static char name[] = "/tmp/test-catalog.XXXXXX"; + r = mkstemp(name); + assert(r >= 0); + + database = name; + + /* Test what happens if there are no files. */ + r = catalog_update(database, NULL, NULL); + assert(r >= 0); + + /* Note: this might actually not find anything, if systemd was + * not installed before. That should be fine too. */ + r = catalog_update(database, NULL, catalog_file_dirs); + assert(r >= 0); +} + +int main(int argc, char *argv[]) { _cleanup_free_ char *text = NULL; + int r; setlocale(LC_ALL, "de_DE.UTF-8"); log_set_max_level(LOG_DEBUG); - assert_se(catalog_update() >= 0); + test_catalog_importing(); - assert_se(catalog_list(stdout, true) >= 0); + test_catalog_update(); - assert_se(catalog_list(stdout, false) >= 0); + r = catalog_list(stdout, database, true); + assert_se(r >= 0); - assert_se(catalog_get(SD_MESSAGE_COREDUMP, &text) >= 0); + r = catalog_list(stdout, database, false); + assert_se(r >= 0); + assert_se(catalog_get(database, SD_MESSAGE_COREDUMP, &text) >= 0); printf(">>>%s<<<\n", text); - fflush(stdout); + if (database) + unlink(database); return 0; } -- cgit v1.2.1 From 13cbf3a5f0cf4a1d89413d0ffc4a9067b1d6d1a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 28 Mar 2013 21:44:00 -0400 Subject: journalctl: support --root for message catalogs --- src/journal/journalctl.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 03daafe9db..3ae6482e99 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -86,6 +86,7 @@ static bool arg_unit_system; static const char *arg_field = NULL; static bool arg_catalog = false; static bool arg_reverse = false; +static const char *arg_root = NULL; static enum { ACTION_SHOW, @@ -125,6 +126,7 @@ static int help(void) { " --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" + " --root=ROOT Operate on catalog files underneath the root ROOT\n" #ifdef HAVE_GCRYPT " --interval=TIME Time interval for changing the FSS sealing key\n" " --verify-key=KEY Specify FSS verification key\n" @@ -155,6 +157,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_NO_PAGER, ARG_NO_TAIL, ARG_NEW_ID128, + ARG_ROOT, ARG_HEADER, ARG_FULL, ARG_SETUP_KEYS, @@ -186,6 +189,7 @@ static int parse_argv(int argc, char *argv[]) { { "merge", no_argument, NULL, 'm' }, { "this-boot", no_argument, NULL, 'b' }, { "directory", required_argument, NULL, 'D' }, + { "root", required_argument, NULL, ARG_ROOT }, { "header", no_argument, NULL, ARG_HEADER }, { "priority", required_argument, NULL, 'p' }, { "setup-keys", no_argument, NULL, ARG_SETUP_KEYS }, @@ -318,6 +322,10 @@ static int parse_argv(int argc, char *argv[]) { arg_directory = optarg; break; + case ARG_ROOT: + arg_root = optarg; + break; + case 'c': arg_cursor = optarg; break; @@ -1024,18 +1032,25 @@ int main(int argc, char *argv[]) { arg_action == ACTION_LIST_CATALOG || arg_action == ACTION_DUMP_CATALOG) { + char _cleanup_free_ *database; + database = strjoin(arg_root, "/", CATALOG_DATABASE, NULL); + if (!database) { + r = log_oom(); + goto finish; + } + if (arg_action == ACTION_UPDATE_CATALOG) { - r = catalog_update(CATALOG_DATABASE, NULL, catalog_file_dirs); + r = catalog_update(database, arg_root, catalog_file_dirs); if (r < 0) log_error("Failed to list catalog: %s", strerror(-r)); } else { bool oneline = arg_action == ACTION_LIST_CATALOG; if (optind < argc) - r = catalog_list_items(stdout, CATALOG_DATABASE, + r = catalog_list_items(stdout, database, oneline, argv + optind); else - r = catalog_list(stdout, CATALOG_DATABASE, oneline); + r = catalog_list(stdout, database, oneline); if (r < 0) log_error("Failed to list catalog: %s", strerror(-r)); } -- cgit v1.2.1 From 0db809489fd88a320ae1023ffe36a9965e9a91b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 29 Mar 2013 10:09:21 -0400 Subject: journalctl: fix --update-catalog with not --root arg grawity> `journalctl --update-catalog` from latest git prints: "Recursive mkdir .: Invalid argument" and "Failed to write : Invalid argument" --- src/journal/journalctl.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 3ae6482e99..c96d68dd4c 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -1032,11 +1032,16 @@ int main(int argc, char *argv[]) { arg_action == ACTION_LIST_CATALOG || arg_action == ACTION_DUMP_CATALOG) { - char _cleanup_free_ *database; - database = strjoin(arg_root, "/", CATALOG_DATABASE, NULL); - if (!database) { - r = log_oom(); - goto finish; + const char* database = CATALOG_DATABASE; + char _cleanup_free_ *copy = NULL; + if (arg_root) { + copy = strjoin(arg_root, "/", CATALOG_DATABASE, NULL); + if (!database) { + r = log_oom(); + goto finish; + } + path_kill_slashes(copy); + database = copy; } if (arg_action == ACTION_UPDATE_CATALOG) { -- cgit v1.2.1 From a7edaadd78271e1c35ff9032f068cb08de645437 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 31 Mar 2013 18:15:59 +0200 Subject: journal-gatewayd: query PID 1 for virtalization Since journal-gatewayd is now running unprivileged, and detecting virtalization requires privileges, query PID1 via D-Bus for the used virtualization. This is also the first time we use libsystemd-bus for more than just testing. https://bugs.freedesktop.org/show_bug.cgi?id=62173 --- src/journal/journal-gatewayd.c | 56 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 4 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c index 8161b7e56b..133d0ae478 100644 --- a/src/journal/journal-gatewayd.c +++ b/src/journal/journal-gatewayd.c @@ -31,9 +31,11 @@ #include "util.h" #include "sd-journal.h" #include "sd-daemon.h" +#include "sd-bus.h" +#include "bus-message.h" +#include "bus-internal.h" #include "logs-show.h" #include "microhttpd-util.h" -#include "virt.h" #include "build.h" #include "fileio.h" @@ -740,6 +742,52 @@ static int request_handler_file( return ret; } +static int get_virtualization(char **v) { + _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; + _cleanup_bus_unref_ sd_bus *bus = NULL; + const char *t; + char *b; + int r; + + r = sd_bus_open_system(&bus); + if (r < 0) + return r; + + r = sd_bus_message_new_method_call( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.DBus.Properties", + "Get", + &m); + if (r < 0) + return r; + + r = sd_bus_message_append(m, "ss", "org.freedesktop.systemd1.Manager", "Virtualization"); + if (r < 0) + return r; + + r = sd_bus_send_with_reply_and_block(bus, m, 0, NULL, &reply); + if (r < 0) + return r; + + r = sd_bus_message_read(reply, "v", "s", &t); + if (r < 0) + return r; + + if (isempty(t)) { + *v = NULL; + return 0; + } + + b = strdup(t); + if (!b) + return -ENOMEM; + + *v = b; + return 1; +} + static int request_handler_machine( struct MHD_Connection *connection, void *connection_cls) { @@ -751,7 +799,7 @@ static int request_handler_machine( uint64_t cutoff_from, cutoff_to, usage; char *json; sd_id128_t mid, bid; - const char *v = "bare"; + _cleanup_free_ char *v = NULL; assert(connection); assert(m); @@ -782,7 +830,7 @@ static int request_handler_machine( parse_env_file("/etc/os-release", NEWLINE, "PRETTY_NAME", &os_name, NULL); - detect_virtualization(&v); + get_virtualization(&v); r = asprintf(&json, "{ \"machine_id\" : \"" SD_ID128_FORMAT_STR "\"," @@ -797,7 +845,7 @@ static int request_handler_machine( SD_ID128_FORMAT_VAL(bid), hostname_cleanup(hostname), os_name ? os_name : "Linux", - v, + v ? v : "bare", (unsigned long long) usage, (unsigned long long) cutoff_from, (unsigned long long) cutoff_to); -- cgit v1.2.1 From 4b94f3b8f7693f076e5c85bc2c02cf028192d8de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 30 Mar 2013 17:47:48 -0400 Subject: journald: check return value of strappend --- src/journal/journald-kmsg.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c index b8198760d6..2f536320f8 100644 --- a/src/journal/journald-kmsg.c +++ b/src/journal/journald-kmsg.c @@ -250,10 +250,12 @@ static void dev_kmsg_record(Server *s, char *p, size_t l) { break; g = udev_list_entry_get_name(ll); - b = strappend("_UDEV_DEVLINK=", g); if (g) { - IOVEC_SET_STRING(iovec[n++], b); - z++; + b = strappend("_UDEV_DEVLINK=", g); + if (b) { + IOVEC_SET_STRING(iovec[n++], b); + z++; + } } j++; -- cgit v1.2.1 From fb93cf737549f2d5fce6cb76b1d5e8382c7537b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 24 Mar 2013 20:16:00 -0400 Subject: journalctl: reword error message Sentence seemed to suggest that all three conditions must be true. --- src/journal/journalctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index c96d68dd4c..8661e5e33a 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -562,7 +562,7 @@ static int add_matches(sd_journal *j, char **args) { else if (S_ISBLK(st.st_mode)) asprintf(&t, "_KERNEL_DEVICE=b%u:%u", major(st.st_rdev), minor(st.st_rdev)); else { - log_error("File is not a device node, regular file or is not executable: %s", *i); + log_error("File is neither a device node, nor regular file, nor executable: %s", *i); return -EINVAL; } -- cgit v1.2.1 From 9607d9470eec07df817e58f64d312ccb5ac4cfcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristian=20Rodr=C3=ADguez?= Date: Mon, 1 Apr 2013 03:08:05 -0300 Subject: Always use our own MAX/MIN definitions code in src/shared/macro.h only defined MAX/MIN in case they were not defined previously. however the MAX/MIN macros implemented in glibc are not of the "safe" kind but defined as: define MIN(a,b) (((a)<(b))?(a):(b)) define MAX(a,b) (((a)>(b))?(a):(b)) Avoid nasty side effects by using our own versions instead. Also fix the warnings derived from this change. [zj: - modify MAX3 macro to fix warning about _a shadowing _a, - do bootchart/svg.c too, - remove unused MIN3.] --- src/journal/journal-file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index 5b077be0da..a44e126c0e 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -1325,7 +1325,7 @@ int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const st #endif /* alloca() can't take 0, hence let's allocate at least one */ - items = alloca(sizeof(EntryItem) * MAX(1, n_iovec)); + items = alloca(sizeof(EntryItem) * MAX(1u, n_iovec)); for (i = 0; i < n_iovec; i++) { uint64_t p; -- cgit v1.2.1 From 5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Apr 2013 16:31:55 +0200 Subject: util: add a bit of syntactic sugar for saving/restoring errno --- src/journal/journal-send.c | 94 ++++++++++++++-------------------------------- 1 file changed, 29 insertions(+), 65 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c index d5ec73e371..4b9109a3c8 100644 --- a/src/journal/journal-send.c +++ b/src/journal/journal-send.c @@ -112,12 +112,11 @@ _public_ int sd_journal_printv(int priority, const char *format, va_list ap) { } static int fill_iovec_sprintf(const char *format, va_list ap, int extra, struct iovec **_iov) { + PROTECT_ERRNO; int r, n = 0, i = 0, j; struct iovec *iov = NULL; - int saved_errno; assert(_iov); - saved_errno = errno; if (extra > 0) { n = MAX(extra * 2, extra + 4); @@ -163,7 +162,6 @@ static int fill_iovec_sprintf(const char *format, va_list ap, int extra, struct *_iov = iov; - errno = saved_errno; return i; fail: @@ -172,7 +170,6 @@ fail: free(iov); - errno = saved_errno; return r; } @@ -202,14 +199,14 @@ finish: } _public_ int sd_journal_sendv(const struct iovec *iov, int n) { + PROTECT_ERRNO; int fd, buffer_fd; struct iovec *w; uint64_t *l; - int r, i, j = 0; + int i, j = 0; struct msghdr mh; struct sockaddr_un sa; ssize_t k; - int saved_errno; union { struct cmsghdr cmsghdr; uint8_t buf[CMSG_SPACE(sizeof(int))]; @@ -227,24 +224,18 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) { if (_unlikely_(n <= 0)) return -EINVAL; - saved_errno = errno; - w = alloca(sizeof(struct iovec) * n * 5 + 3); l = alloca(sizeof(uint64_t) * n); for (i = 0; i < n; i++) { char *c, *nl; - if (_unlikely_(!iov[i].iov_base || iov[i].iov_len <= 1)) { - r = -EINVAL; - goto finish; - } + if (_unlikely_(!iov[i].iov_base || iov[i].iov_len <= 1)) + return -EINVAL; c = memchr(iov[i].iov_base, '=', iov[i].iov_len); - if (_unlikely_(!c || c == iov[i].iov_base)) { - r = -EINVAL; - goto finish; - } + if (_unlikely_(!c || c == iov[i].iov_base)) + return -EINVAL; have_syslog_identifier = have_syslog_identifier || (c == (char *) iov[i].iov_base + 17 && @@ -252,10 +243,8 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) { nl = memchr(iov[i].iov_base, '\n', iov[i].iov_len); if (nl) { - if (_unlikely_(nl < c)) { - r = -EINVAL; - goto finish; - } + if (_unlikely_(nl < c)) + return -EINVAL; /* Already includes a newline? Bummer, then * let's write the variable name, then a @@ -300,10 +289,8 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) { } fd = journal_fd(); - if (_unlikely_(fd < 0)) { - r = fd; - goto finish; - } + if (_unlikely_(fd < 0)) + return fd; zero(sa); sa.sun_family = AF_UNIX; @@ -316,37 +303,29 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) { mh.msg_iovlen = j; k = sendmsg(fd, &mh, MSG_NOSIGNAL); - if (k >= 0) { - r = 0; - goto finish; - } + if (k >= 0) + return 0; - if (errno != EMSGSIZE && errno != ENOBUFS) { - r = -errno; - goto finish; - } + if (errno != EMSGSIZE && errno != ENOBUFS) + return -errno; /* Message doesn't fit... Let's dump the data in a temporary * file and just pass a file descriptor of it to the other * side */ buffer_fd = mkostemp(path, O_CLOEXEC|O_RDWR); - if (buffer_fd < 0) { - r = -errno; - goto finish; - } + if (buffer_fd < 0) + return -errno; if (unlink(path) < 0) { close_nointr_nofail(buffer_fd); - r = -errno; - goto finish; + return -errno; } n = writev(buffer_fd, w, j); if (n < 0) { close_nointr_nofail(buffer_fd); - r = -errno; - goto finish; + return -errno; } mh.msg_iov = NULL; @@ -367,24 +346,15 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) { k = sendmsg(fd, &mh, MSG_NOSIGNAL); close_nointr_nofail(buffer_fd); - if (k < 0) { - r = -errno; - goto finish; - } - - r = 0; - -finish: - errno = saved_errno; + if (k < 0) + return -errno; - return r; + return 0; } static int fill_iovec_perror_and_send(const char *message, int skip, struct iovec iov[]) { - size_t n, k, r; - int saved_errno; - - saved_errno = errno; + PROTECT_ERRNO; + size_t n, k; k = isempty(message) ? 0 : strlen(message) + 2; n = 8 + k + 256 + 1; @@ -394,7 +364,7 @@ static int fill_iovec_perror_and_send(const char *message, int skip, struct iove char* j; errno = 0; - j = strerror_r(saved_errno, buffer + 8 + k, n - 8 - k); + j = strerror_r(_saved_errno_, buffer + 8 + k, n - 8 - k); if (errno == 0) { char error[6 + 10 + 1]; /* for a 32bit value */ @@ -408,24 +378,18 @@ static int fill_iovec_perror_and_send(const char *message, int skip, struct iove memcpy(buffer + 8 + k - 2, ": ", 2); } - snprintf(error, sizeof(error), "ERRNO=%u", saved_errno); + snprintf(error, sizeof(error), "ERRNO=%u", _saved_errno_); char_array_0(error); IOVEC_SET_STRING(iov[skip+0], "PRIORITY=3"); IOVEC_SET_STRING(iov[skip+1], buffer); IOVEC_SET_STRING(iov[skip+2], error); - r = sd_journal_sendv(iov, skip + 3); - - errno = saved_errno; - return r; + return sd_journal_sendv(iov, skip + 3); } - if (errno != ERANGE) { - r = -errno; - errno = saved_errno; - return r; - } + if (errno != ERANGE) + return -errno; n *= 2; } -- cgit v1.2.1 From 7f602784de4fd378120e8ebfe6d830862b9cae03 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Apr 2013 20:38:16 +0200 Subject: util: rename parse_usec() to parse_sec() sinds the default unit is seconds Internally we store all time values in usec_t, however parse_usec() actually was used mostly to parse values in seconds (unless explicit units were specified to define a different unit). Hence, be clear about this and name the function about what we pass into it, not what we get out of it. --- src/journal/journalctl.c | 2 +- src/journal/journald-gperf.gperf | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 8661e5e33a..642e20d43f 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -355,7 +355,7 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_INTERVAL: - r = parse_usec(optarg, &arg_interval); + r = parse_sec(optarg, &arg_interval); if (r < 0 || arg_interval <= 0) { log_error("Failed to parse sealing key change interval: %s", optarg); return -EINVAL; diff --git a/src/journal/journald-gperf.gperf b/src/journal/journald-gperf.gperf index 57b45f9232..2ecba3bd0e 100644 --- a/src/journal/journald-gperf.gperf +++ b/src/journal/journald-gperf.gperf @@ -18,8 +18,8 @@ struct ConfigPerfItem; Journal.Storage, config_parse_storage, 0, offsetof(Server, storage) Journal.Compress, config_parse_bool, 0, offsetof(Server, compress) Journal.Seal, config_parse_bool, 0, offsetof(Server, seal) -Journal.SyncIntervalSec, config_parse_usec, 0, offsetof(Server, sync_interval_usec) -Journal.RateLimitInterval, config_parse_usec, 0, offsetof(Server, rate_limit_interval) +Journal.SyncIntervalSec, config_parse_sec, 0, offsetof(Server, sync_interval_usec) +Journal.RateLimitInterval, config_parse_sec, 0, offsetof(Server, rate_limit_interval) Journal.RateLimitBurst, config_parse_unsigned, 0, offsetof(Server, rate_limit_burst) Journal.SystemMaxUse, config_parse_bytes_off, 0, offsetof(Server, system_metrics.max_use) Journal.SystemMaxFileSize, config_parse_bytes_off, 0, offsetof(Server, system_metrics.max_size) @@ -27,8 +27,8 @@ Journal.SystemKeepFree, config_parse_bytes_off, 0, offsetof(Server, system_m Journal.RuntimeMaxUse, config_parse_bytes_off, 0, offsetof(Server, runtime_metrics.max_use) Journal.RuntimeMaxFileSize, config_parse_bytes_off, 0, offsetof(Server, runtime_metrics.max_size) Journal.RuntimeKeepFree, config_parse_bytes_off, 0, offsetof(Server, runtime_metrics.keep_free) -Journal.MaxRetentionSec, config_parse_usec, 0, offsetof(Server, max_retention_usec) -Journal.MaxFileSec, config_parse_usec, 0, offsetof(Server, max_file_usec) +Journal.MaxRetentionSec, config_parse_sec, 0, offsetof(Server, max_retention_usec) +Journal.MaxFileSec, config_parse_sec, 0, offsetof(Server, max_file_usec) Journal.ForwardToSyslog, config_parse_bool, 0, offsetof(Server, forward_to_syslog) Journal.ForwardToKMsg, config_parse_bool, 0, offsetof(Server, forward_to_kmsg) Journal.ForwardToConsole, config_parse_bool, 0, offsetof(Server, forward_to_console) -- cgit v1.2.1 From 2fa4092c2829dd14e50c430ae2f23551d23c6c1d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 4 Apr 2013 02:56:56 +0200 Subject: util: make time formatting a bit smarter Instead of outputting "5h 55s 50ms 3us" we'll now output "5h 55.050003s". Also, while outputting the accuracy is configurable. Basically we now try use "dot notation" for all time values > 1min. For >= 1s we use 's' as unit, otherwise for >= 1ms we use 'ms' as unit, and finally 'us'. This should give reasonably values in most cases. --- src/journal/journalctl.c | 6 +++--- src/journal/test-journal-verify.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 642e20d43f..1f26787cf7 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -804,7 +804,7 @@ static int setup_keys(void) { fprintf(stderr, ANSI_HIGHLIGHT_OFF "\n" "The sealing key is automatically changed every %s.\n", - format_timespan(tsb, sizeof(tsb), arg_interval)); + format_timespan(tsb, sizeof(tsb), arg_interval, 0)); hn = gethostname_malloc(); @@ -878,10 +878,10 @@ static int verify(sd_journal *j) { log_info("=> Validated from %s to %s, final %s entries not sealed.", format_timestamp(a, sizeof(a), first), format_timestamp(b, sizeof(b), validated), - format_timespan(c, sizeof(c), last > validated ? last - validated : 0)); + format_timespan(c, sizeof(c), last > validated ? last - validated : 0, 0)); } else if (last > 0) log_info("=> No sealing yet, %s of entries not sealed.", - format_timespan(c, sizeof(c), last - first)); + format_timespan(c, sizeof(c), last - first, 0)); else log_info("=> No sealing yet, no entries in file."); } diff --git a/src/journal/test-journal-verify.c b/src/journal/test-journal-verify.c index b6677215c0..ad2e2d4c3b 100644 --- a/src/journal/test-journal-verify.c +++ b/src/journal/test-journal-verify.c @@ -117,7 +117,7 @@ int main(int argc, char *argv[]) { log_info("=> Validated from %s to %s, %s missing", format_timestamp(a, sizeof(a), from), format_timestamp(b, sizeof(b), to), - format_timespan(c, sizeof(c), total > to ? total - to : 0)); + format_timespan(c, sizeof(c), total > to ? total - to : 0, 0)); } journal_file_close(f); -- cgit v1.2.1 From ee531d949c2f62374fc109252f8cbe61c2b8ee39 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 4 Apr 2013 17:22:28 +0200 Subject: journal: add public API call sd_journal_get_events() This function should be used when filling in "struct pollfd"'s .events field for watching the journal. It will always return POLLIN for now, but we should keep our options open to change this later on. This mimics libsystemd-bus' sd_bus_get_events() call with the same purpose. --- src/journal/journalctl.c | 1 - src/journal/libsystemd-journal.sym | 5 +++++ src/journal/sd-journal.c | 13 +++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 1f26787cf7..86895b8f5b 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/src/journal/libsystemd-journal.sym b/src/journal/libsystemd-journal.sym index fbe41501f0..e241318cb0 100644 --- a/src/journal/libsystemd-journal.sym +++ b/src/journal/libsystemd-journal.sym @@ -93,3 +93,8 @@ LIBSYSTEMD_JOURNAL_198 { global: sd_journal_reliable_fd; } LIBSYSTEMD_JOURNAL_196; + +LIBSYSTEMD_JOURNAL_201 { +global: + sd_journal_get_events; +} LIBSYSTEMD_JOURNAL_198; diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index bb99671934..3eba4cd0d1 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -1981,6 +1981,19 @@ _public_ int sd_journal_get_fd(sd_journal *j) { return j->inotify_fd; } +_public_ int sd_journal_get_events(sd_journal *j) { + int fd; + + if (!j) + return -EINVAL; + + fd = sd_journal_get_fd(j); + if (fd < 0) + return fd; + + return POLLIN; +} + static void process_inotify_event(sd_journal *j, struct inotify_event *e) { Directory *d; int r; -- cgit v1.2.1 From 39c155ea0d8b24895017fd5cf48508924ce2016d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 4 Apr 2013 20:07:48 +0200 Subject: journal: add sd_journal_get_timeout() call to public API Let's do the wake-up logic on NFS internally, making things simpler for users. --- src/journal/journal-internal.h | 2 ++ src/journal/libsystemd-journal.sym | 1 + src/journal/sd-journal.c | 43 +++++++++++++++++++++++++++++++++----- 3 files changed, 41 insertions(+), 5 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journal-internal.h b/src/journal/journal-internal.h index bc9e44d42d..3accf14c05 100644 --- a/src/journal/journal-internal.h +++ b/src/journal/journal-internal.h @@ -126,6 +126,8 @@ struct sd_journal { size_t data_threshold; Set *errors; + + usec_t last_process_usec; }; char *journal_make_match_string(sd_journal *j); diff --git a/src/journal/libsystemd-journal.sym b/src/journal/libsystemd-journal.sym index e241318cb0..cdebf10ded 100644 --- a/src/journal/libsystemd-journal.sym +++ b/src/journal/libsystemd-journal.sym @@ -97,4 +97,5 @@ global: LIBSYSTEMD_JOURNAL_201 { global: sd_journal_get_events; + sd_journal_get_timeout; } LIBSYSTEMD_JOURNAL_198; diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 3eba4cd0d1..c1f69827e9 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -1994,6 +1994,30 @@ _public_ int sd_journal_get_events(sd_journal *j) { return POLLIN; } +_public_ int sd_journal_get_timeout(sd_journal *j, uint64_t *timeout_usec) { + int fd; + + if (!j) + return -EINVAL; + if (!timeout_usec) + return -EINVAL; + + fd = sd_journal_get_fd(j); + if (fd < 0) + return fd; + + if (!j->on_network) { + *timeout_usec = (uint64_t) -1; + return 0; + } + + /* If we are on the network we need to regularly check for + * changes manually */ + + *timeout_usec = j->last_process_usec + JOURNAL_FILES_RECHECK_USEC; + return 1; +} + static void process_inotify_event(sd_journal *j, struct inotify_event *e) { Directory *d; int r; @@ -2076,6 +2100,8 @@ _public_ int sd_journal_process(sd_journal *j) { if (!j) return -EINVAL; + j->last_process_usec = now(CLOCK_MONOTONIC); + for (;;) { struct inotify_event *e; ssize_t l; @@ -2109,6 +2135,7 @@ _public_ int sd_journal_process(sd_journal *j) { _public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) { int r; + uint64_t t; assert(j); @@ -2127,12 +2154,18 @@ _public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) { return determine_change(j); } - if (j->on_network) { - /* If we are on the network we need to regularly check - * for changes manually */ + r = sd_journal_get_timeout(j, &t); + if (r < 0) + return r; + + if (t != (uint64_t) -1) { + usec_t n; + + n = now(CLOCK_MONOTONIC); + t = t > n ? t - n : 0; - if (timeout_usec == (uint64_t) -1 || timeout_usec > JOURNAL_FILES_RECHECK_USEC) - timeout_usec = JOURNAL_FILES_RECHECK_USEC; + if (timeout_usec == (uint64_t) -1 || timeout_usec > t) + timeout_usec = t; } do { -- cgit v1.2.1 From 917b5dc7075a15bded4948efba8e686dba4509f8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 5 Apr 2013 04:15:39 +0200 Subject: bus: add convenience functions for constructing and sending method calls/signals in one call --- src/journal/journal-gatewayd.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c index 133d0ae478..a633638f80 100644 --- a/src/journal/journal-gatewayd.c +++ b/src/journal/journal-gatewayd.c @@ -743,7 +743,7 @@ static int request_handler_file( } static int get_virtualization(char **v) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; + _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; _cleanup_bus_unref_ sd_bus *bus = NULL; const char *t; char *b; @@ -753,21 +753,17 @@ static int get_virtualization(char **v) { if (r < 0) return r; - r = sd_bus_message_new_method_call( + r = sd_bus_call_method( bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.DBus.Properties", "Get", - &m); - if (r < 0) - return r; - - r = sd_bus_message_append(m, "ss", "org.freedesktop.systemd1.Manager", "Virtualization"); - if (r < 0) - return r; - - r = sd_bus_send_with_reply_and_block(bus, m, 0, NULL, &reply); + NULL, + &reply, + "ss", + "org.freedesktop.systemd1.Manager", + "Virtualization"); if (r < 0) return r; -- cgit v1.2.1 From 144e51eca20b72c8177314c225d8c15c1b0b9d6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristian=20Rodr=C3=ADguez?= Date: Thu, 4 Apr 2013 20:09:50 -0300 Subject: journal: u64log2 can be expressed just as __builtin_clzll(n) ^ 63U --- src/journal/journald-rate-limit.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journald-rate-limit.c b/src/journal/journald-rate-limit.c index 8bd68476a3..da3aed64ea 100644 --- a/src/journal/journald-rate-limit.c +++ b/src/journal/journald-rate-limit.c @@ -170,21 +170,6 @@ fail: return NULL; } -static uint64_t u64log2(uint64_t n) { - unsigned r; - - if (n <= 1) - return 0; - - r = 0; - for (;;) { - n = n >> 1; - if (!n) - return r; - r++; - } -} - static unsigned burst_modulate(unsigned burst, uint64_t available) { unsigned k; -- cgit v1.2.1 From 737563e4bb1606cae1dd0e9484f9e82da466fe76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 5 Apr 2013 00:03:24 -0400 Subject: test-catalog,core/load-dropin: remove unused variables --- src/journal/test-catalog.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/test-catalog.c b/src/journal/test-catalog.c index 21149f18a5..c463035891 100644 --- a/src/journal/test-catalog.c +++ b/src/journal/test-catalog.c @@ -89,7 +89,6 @@ static const char* database = NULL; static void test_catalog_update(void) { int r; - char _cleanup_free_ *path = NULL; static char name[] = "/tmp/test-catalog.XXXXXX"; r = mkstemp(name); -- cgit v1.2.1 From b92bea5d2a9481de69bb627a7b442a9f58fca43d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 24 Mar 2013 19:59:00 -0400 Subject: Use initalization instead of explicit zeroing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before, we would initialize many fields twice: first by filling the structure with zeros, and then a second time with the real values. We can let the compiler do the job for us, avoiding one copy. A downside of this patch is that text gets slightly bigger. This is because all zero() calls are effectively inlined: $ size build/.libs/systemd text data bss dec hex filename before 897737 107300 2560 1007597 f5fed build/.libs/systemd after 897873 107300 2560 1007733 f6075 build/.libs/systemd … actually less than 1‰. A few asserts that the parameter is not null had to be removed. I don't think this changes much, because first, it is quite unlikely for the assert to fail, and second, an immediate SEGV is almost as good as an assert. --- src/journal/journald-server.c | 12 +++++------- src/journal/journald-stream.c | 9 ++++----- src/journal/journald-syslog.c | 33 ++++++++++++++++----------------- 3 files changed, 25 insertions(+), 29 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index a9d7aa181d..9a96689ee7 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -719,7 +719,7 @@ void server_driver_message(Server *s, sd_id128_t message_id, const char *format, struct iovec iovec[N_IOVEC_META_FIELDS + 4]; int n = 0; va_list ap; - struct ucred ucred; + struct ucred ucred = {}; assert(s); assert(format); @@ -740,7 +740,6 @@ void server_driver_message(Server *s, sd_id128_t message_id, const char *format, IOVEC_SET_STRING(iovec[n++], mid); } - zero(ucred); ucred.pid = getpid(); ucred.uid = getuid(); ucred.gid = getgid(); @@ -1356,17 +1355,16 @@ static int server_open_sync_timer(Server *s) { int server_schedule_sync(Server *s) { int r; - struct itimerspec sync_timer_enable; - assert(s); if (s->sync_scheduled) return 0; if (s->sync_interval_usec) { - zero(sync_timer_enable); - sync_timer_enable.it_value.tv_sec = s->sync_interval_usec / USEC_PER_SEC; - sync_timer_enable.it_value.tv_nsec = s->sync_interval_usec % MSEC_PER_SEC; + struct itimerspec sync_timer_enable = { + .it_value.tv_sec = s->sync_interval_usec / USEC_PER_SEC, + .it_value.tv_nsec = s->sync_interval_usec % MSEC_PER_SEC, + }; r = timerfd_settime(s->sync_timer_fd, 0, &sync_timer_enable, NULL); if (r < 0) diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c index bdc2f49ef4..6d51c29083 100644 --- a/src/journal/journald-stream.c +++ b/src/journal/journald-stream.c @@ -412,13 +412,16 @@ fail: } int server_open_stdout_socket(Server *s) { - union sockaddr_union sa; int r; struct epoll_event ev; assert(s); if (s->stdout_fd < 0) { + union sockaddr_union sa = { + .un.sun_family = AF_UNIX, + .un.sun_path = "/run/systemd/journal/stdout", + }; s->stdout_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); if (s->stdout_fd < 0) { @@ -426,10 +429,6 @@ int server_open_stdout_socket(Server *s) { return -errno; } - zero(sa); - sa.un.sun_family = AF_UNIX; - strncpy(sa.un.sun_path, "/run/systemd/journal/stdout", sizeof(sa.un.sun_path)); - unlink(sa.un.sun_path); r = bind(s->stdout_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)); diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c index afddca3630..000f5acc10 100644 --- a/src/journal/journald-syslog.c +++ b/src/journal/journald-syslog.c @@ -34,28 +34,28 @@ #define WARN_FORWARD_SYSLOG_MISSED_USEC (30 * USEC_PER_SEC) static void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned n_iovec, struct ucred *ucred, struct timeval *tv) { - struct msghdr msghdr; + + union sockaddr_union sa = { + .un.sun_family = AF_UNIX, + .un.sun_path = "/run/systemd/journal/syslog", + }; + struct msghdr msghdr = { + .msg_iov = (struct iovec *) iovec, + .msg_iovlen = n_iovec, + .msg_name = &sa, + .msg_namelen = offsetof(union sockaddr_union, un.sun_path) + + sizeof("/run/systemd/journal/syslog") - 1, + }; struct cmsghdr *cmsg; union { struct cmsghdr cmsghdr; uint8_t buf[CMSG_SPACE(sizeof(struct ucred))]; } control; - union sockaddr_union sa; assert(s); assert(iovec); assert(n_iovec > 0); - zero(msghdr); - msghdr.msg_iov = (struct iovec*) iovec; - msghdr.msg_iovlen = n_iovec; - - zero(sa); - sa.un.sun_family = AF_UNIX; - strncpy(sa.un.sun_path, "/run/systemd/journal/syslog", sizeof(sa.un.sun_path)); - msghdr.msg_name = &sa; - msghdr.msg_namelen = offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path); - if (ucred) { zero(control); msghdr.msg_control = &control; @@ -412,13 +412,16 @@ void server_process_syslog_message( } int server_open_syslog_socket(Server *s) { - union sockaddr_union sa; int one, r; struct epoll_event ev; assert(s); if (s->syslog_fd < 0) { + union sockaddr_union sa = { + .un.sun_family = AF_UNIX, + .un.sun_path = "/dev/log", + }; s->syslog_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); if (s->syslog_fd < 0) { @@ -426,10 +429,6 @@ int server_open_syslog_socket(Server *s) { return -errno; } - zero(sa); - sa.un.sun_family = AF_UNIX; - strncpy(sa.un.sun_path, "/dev/log", sizeof(sa.un.sun_path)); - unlink(sa.un.sun_path); r = bind(s->syslog_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)); -- cgit v1.2.1 From 23e97f7d9274b90fb0e1664945dc6259fdae6d39 Mon Sep 17 00:00:00 2001 From: Marius Vollmer Date: Mon, 8 Apr 2013 11:19:44 +0300 Subject: journal: Fix typo This would break backwards skipping. https://bugs.freedesktop.org/show_bug.cgi?id=63250 --- src/journal/sd-journal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index c1f69827e9..7e06a70344 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -602,7 +602,7 @@ static int next_for_match( return r; if ((direction == DIRECTION_DOWN ? cp >= after_offset : cp <= after_offset) && - (np == 0 || (direction == DIRECTION_DOWN ? cp > np : np < cp))) { + (np == 0 || (direction == DIRECTION_DOWN ? cp > np : cp < np))) { np = cp; continue_looking = true; } -- cgit v1.2.1 From 0a20e3c10761378869af7bbef2733e3ae879d0f1 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 6 Apr 2013 10:20:34 +0200 Subject: journald: Do not always record _AUDIT_SESSION and _AUDIT_LOGINUID When systemd was compiled without audit support, do not collect the audit session and loginuid in the journal. This is saving a couple of syscalls and memory allocations per log message. --- src/journal/journald-server.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/journal') diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 9a96689ee7..28ce69dccd 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -555,8 +555,10 @@ static void dispatch_message_real( assert(n + N_IOVEC_META_FIELDS <= m); if (ucred) { +#ifdef HAVE_AUDIT uint32_t audit; uid_t loginuid; +#endif realuid = ucred->uid; @@ -596,6 +598,7 @@ static void dispatch_message_real( IOVEC_SET_STRING(iovec[n++], cmdline); } +#ifdef HAVE_AUDIT r = audit_session_from_pid(ucred->pid, &audit); if (r >= 0) if (asprintf(&audit_session, "_AUDIT_SESSION=%lu", (unsigned long) audit) >= 0) @@ -605,6 +608,7 @@ static void dispatch_message_real( if (r >= 0) if (asprintf(&audit_loginuid, "_AUDIT_LOGINUID=%lu", (unsigned long) loginuid) >= 0) IOVEC_SET_STRING(iovec[n++], audit_loginuid); +#endif t = shortened_cgroup_path(ucred->pid); if (t) { -- cgit v1.2.1 From c2457105d76e3daf159f554a9bafb9751b23d756 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 6 Apr 2013 10:20:35 +0200 Subject: journald: Do not dynamically allocate _UID/_GID/_PID strings Avoid the dynamic allocation for the _UID, _GID, and _PID strings. The maximum size of the string can be determined at compile time. The code has only been compile tested. --- src/journal/journald-server.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 28ce69dccd..2ae5624a04 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -535,8 +535,11 @@ static void dispatch_message_real( const char *label, size_t label_len, const char *unit_id) { - char _cleanup_free_ *pid = NULL, *uid = NULL, *gid = NULL, - *source_time = NULL, *boot_id = NULL, *machine_id = NULL, + char pid[sizeof("_PID=") + DECIMAL_STR_MAX(ucred->pid)], + uid[sizeof("_UID=") + DECIMAL_STR_MAX(ucred->uid)], + gid[sizeof("_GID=") + DECIMAL_STR_MAX(ucred->gid)]; + + char _cleanup_free_ *source_time = NULL, *boot_id = NULL, *machine_id = NULL, *comm = NULL, *cmdline = NULL, *hostname = NULL, *audit_session = NULL, *audit_loginuid = NULL, *exe = NULL, *cgroup = NULL, *session = NULL, @@ -562,14 +565,17 @@ static void dispatch_message_real( realuid = ucred->uid; - if (asprintf(&pid, "_PID=%lu", (unsigned long) ucred->pid) >= 0) - IOVEC_SET_STRING(iovec[n++], pid); + snprintf(pid, sizeof(pid) - 1, "_PID=%lu", (unsigned long) ucred->pid); + char_array_0(pid); + IOVEC_SET_STRING(iovec[n++], pid); - if (asprintf(&uid, "_UID=%lu", (unsigned long) ucred->uid) >= 0) - IOVEC_SET_STRING(iovec[n++], uid); + snprintf(uid, sizeof(uid) - 1, "_UID=%lu", (unsigned long) ucred->uid); + char_array_0(uid); + IOVEC_SET_STRING(iovec[n++], uid); - if (asprintf(&gid, "_GID=%lu", (unsigned long) ucred->gid) >= 0) - IOVEC_SET_STRING(iovec[n++], gid); + snprintf(gid, sizeof(gid) - 1, "_GID=%lu", (unsigned long) ucred->gid); + char_array_0(gid); + IOVEC_SET_STRING(iovec[n++], gid); r = get_process_comm(ucred->pid, &t); if (r >= 0) { -- cgit v1.2.1 From a569398925430de1f8479262e8ab39502054f2e9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 8 Apr 2013 15:38:27 +0200 Subject: journald: get rid of one more memory allocation --- src/journal/journald-server.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 2ae5624a04..74482f184d 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -537,9 +537,10 @@ static void dispatch_message_real( char pid[sizeof("_PID=") + DECIMAL_STR_MAX(ucred->pid)], uid[sizeof("_UID=") + DECIMAL_STR_MAX(ucred->uid)], - gid[sizeof("_GID=") + DECIMAL_STR_MAX(ucred->gid)]; + gid[sizeof("_GID=") + DECIMAL_STR_MAX(ucred->gid)], + source_time[sizeof("_SOURCE_REALTIME_TIMESTAMP=" + DECIMAL_STR_MAX(usec_t))]; - char _cleanup_free_ *source_time = NULL, *boot_id = NULL, *machine_id = NULL, + char _cleanup_free_ *boot_id = NULL, *machine_id = NULL, *comm = NULL, *cmdline = NULL, *hostname = NULL, *audit_session = NULL, *audit_loginuid = NULL, *exe = NULL, *cgroup = NULL, *session = NULL, @@ -678,9 +679,10 @@ static void dispatch_message_real( } if (tv) { - if (asprintf(&source_time, "_SOURCE_REALTIME_TIMESTAMP=%llu", - (unsigned long long) timeval_load(tv)) >= 0) - IOVEC_SET_STRING(iovec[n++], source_time); + snprintf(source_time, sizeof(source_time) - 1, "_SOURCE_REALTIME_TIMESTAMP=%llu", + (unsigned long long) timeval_load(tv)); + char_array_0(source_time); + IOVEC_SET_STRING(iovec[n++], source_time); } /* Note that strictly speaking storing the boot id here is -- cgit v1.2.1 From adb435bb70815461eeddf44dd5d6f1fc2ad9026d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 8 Apr 2013 15:46:32 +0200 Subject: journald: drop two more memory allocations --- src/journal/journald-server.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 74482f184d..6f283df74b 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -538,15 +538,15 @@ static void dispatch_message_real( char pid[sizeof("_PID=") + DECIMAL_STR_MAX(ucred->pid)], uid[sizeof("_UID=") + DECIMAL_STR_MAX(ucred->uid)], gid[sizeof("_GID=") + DECIMAL_STR_MAX(ucred->gid)], - source_time[sizeof("_SOURCE_REALTIME_TIMESTAMP=" + DECIMAL_STR_MAX(usec_t))]; + source_time[sizeof("_SOURCE_REALTIME_TIMESTAMP=" + DECIMAL_STR_MAX(usec_t))], + boot_id[sizeof("_BOOT_ID=") + 32] = "_BOOT_ID=", + machine_id[sizeof("_MACHINE_ID=") + 32] = "_MACHINE_ID="; - char _cleanup_free_ *boot_id = NULL, *machine_id = NULL, - *comm = NULL, *cmdline = NULL, *hostname = NULL, + char _cleanup_free_ *comm = NULL, *cmdline = NULL, *hostname = NULL, *audit_session = NULL, *audit_loginuid = NULL, *exe = NULL, *cgroup = NULL, *session = NULL, *owner_uid = NULL, *unit = NULL, *selinux_context = NULL; - char idbuf[33]; sd_id128_t id; int r; char *t; @@ -689,14 +689,16 @@ static void dispatch_message_real( * redundant since the entry includes this in-line * anyway. However, we need this indexed, too. */ r = sd_id128_get_boot(&id); - if (r >= 0) - if (asprintf(&boot_id, "_BOOT_ID=%s", sd_id128_to_string(id, idbuf)) >= 0) - IOVEC_SET_STRING(iovec[n++], boot_id); + if (r >= 0) { + sd_id128_to_string(id, boot_id + sizeof("_BOOT_ID=") - 1); + IOVEC_SET_STRING(iovec[n++], boot_id); + } r = sd_id128_get_machine(&id); - if (r >= 0) - if (asprintf(&machine_id, "_MACHINE_ID=%s", sd_id128_to_string(id, idbuf)) >= 0) - IOVEC_SET_STRING(iovec[n++], machine_id); + if (r >= 0) { + sd_id128_to_string(id, machine_id + sizeof("_MACHINE_ID") - 1); + IOVEC_SET_STRING(iovec[n++], machine_id); + } t = gethostname_malloc(); if (t) { -- cgit v1.2.1 From 7120511888321c40810a36c8da96c7d09e464f5b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 8 Apr 2013 15:48:12 +0200 Subject: journald: no need to free audit vars --- src/journal/journald-server.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 6f283df74b..53e3830110 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -543,10 +543,13 @@ static void dispatch_message_real( machine_id[sizeof("_MACHINE_ID=") + 32] = "_MACHINE_ID="; char _cleanup_free_ *comm = NULL, *cmdline = NULL, *hostname = NULL, - *audit_session = NULL, *audit_loginuid = NULL, *exe = NULL, *cgroup = NULL, *session = NULL, *owner_uid = NULL, *unit = NULL, *selinux_context = NULL; +#ifdef HAVE_AUDIT + char _cleanup_free_ *audit_session = NULL, *audit_loginuid = NULL; +#endif + sd_id128_t id; int r; char *t; -- cgit v1.2.1 From c4aa09b06f835c91cea9e021df4c3605cff2318d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 8 Apr 2013 20:32:03 +0200 Subject: journald: bring max coredump size in sync with max entry size --- src/journal/coredump.c | 2 ++ src/journal/journald-native.c | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'src/journal') diff --git a/src/journal/coredump.c b/src/journal/coredump.c index c56d283268..2dfb04afdf 100644 --- a/src/journal/coredump.c +++ b/src/journal/coredump.c @@ -37,6 +37,8 @@ #include "special.h" #include "cgroup-util.h" +/* Make sure to not make this larger than the maximum journal entry + * size. See ENTRY_SIZE_MAX in journald-native.c. */ #define COREDUMP_MAX (768*1024*1024) enum { diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c index 069114778b..9d1f39f0c5 100644 --- a/src/journal/journald-native.c +++ b/src/journal/journald-native.c @@ -31,8 +31,10 @@ #include "journald-console.h" #include "journald-syslog.h" -#define ENTRY_SIZE_MAX (1024*1024*64) -#define DATA_SIZE_MAX (1024*1024*64) +/* Make sure not to make this smaller than the maximum coredump + * size. See COREDUMP_MAX in coredump.c */ +#define ENTRY_SIZE_MAX (1024*1024*768) +#define DATA_SIZE_MAX (1024*1024*768) static bool valid_user_field(const char *p, size_t l) { const char *a; -- cgit v1.2.1 From 3a819b1b6289311ebf09e94c6240dfb6be7a0496 Mon Sep 17 00:00:00 2001 From: Lukas Nykryn Date: Wed, 10 Apr 2013 12:53:58 +0200 Subject: journalctl: check return of strjoin --- src/journal/journalctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 86895b8f5b..002ff7cda0 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -1035,7 +1035,7 @@ int main(int argc, char *argv[]) { char _cleanup_free_ *copy = NULL; if (arg_root) { copy = strjoin(arg_root, "/", CATALOG_DATABASE, NULL); - if (!database) { + if (!copy) { r = log_oom(); goto finish; } -- cgit v1.2.1 From d378991747d67fff1d4dc39e7fb2bc8f49f1b561 Mon Sep 17 00:00:00 2001 From: Mirco Tischler Date: Sat, 13 Apr 2013 01:03:49 +0200 Subject: journal: fix broken tags _SOURCE_REALTIME_TIMESTAMP and _MACHINE_ID --- src/journal/journald-server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/journal') diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 53e3830110..be84323a6c 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -538,7 +538,7 @@ static void dispatch_message_real( char pid[sizeof("_PID=") + DECIMAL_STR_MAX(ucred->pid)], uid[sizeof("_UID=") + DECIMAL_STR_MAX(ucred->uid)], gid[sizeof("_GID=") + DECIMAL_STR_MAX(ucred->gid)], - source_time[sizeof("_SOURCE_REALTIME_TIMESTAMP=" + DECIMAL_STR_MAX(usec_t))], + source_time[sizeof("_SOURCE_REALTIME_TIMESTAMP=") + DECIMAL_STR_MAX(usec_t)], boot_id[sizeof("_BOOT_ID=") + 32] = "_BOOT_ID=", machine_id[sizeof("_MACHINE_ID=") + 32] = "_MACHINE_ID="; @@ -699,7 +699,7 @@ static void dispatch_message_real( r = sd_id128_get_machine(&id); if (r >= 0) { - sd_id128_to_string(id, machine_id + sizeof("_MACHINE_ID") - 1); + sd_id128_to_string(id, machine_id + sizeof("_MACHINE_ID=") - 1); IOVEC_SET_STRING(iovec[n++], machine_id); } -- cgit v1.2.1 From d3b6d0c21ea5a0d15ec6dbd8b8d179138b7463bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 13 Apr 2013 20:22:53 -0400 Subject: fileio: in envfiles, do not skip lines following empty lines https://bugs.freedesktop.org/show_bug.cgi?id=63477 --- src/journal/catalog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/catalog.c b/src/journal/catalog.c index ebf0622609..7681af6629 100644 --- a/src/journal/catalog.c +++ b/src/journal/catalog.c @@ -180,7 +180,7 @@ int catalog_import_file(Hashmap *h, struct strbuf *sb, const char *path) { continue; } - if (strchr(COMMENTS, line[0])) + if (strchr(COMMENTS "\n", line[0])) continue; if (empty_line && -- cgit v1.2.1 From abad76cc4c8586bc088fec65560cf4db2e0903c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 13 Apr 2013 21:02:03 -0400 Subject: Include instead of is POSIX. On Linux, simply includes , so there should be on difference. On Android likewise, except that there is some more stuff. QNX has only . https://bugs.freedesktop.org/show_bug.cgi?id=63423 --- src/journal/cat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/journal') diff --git a/src/journal/cat.c b/src/journal/cat.c index a95392ccb0..ea61578353 100644 --- a/src/journal/cat.c +++ b/src/journal/cat.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include -- cgit v1.2.1 From 7027ff61a34a12487712b382a061c654acc3a679 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 16 Apr 2013 04:36:06 +0200 Subject: nspawn: introduce the new /machine/ tree in the cgroup tree and move containers there Containers will now carry a label (normally derived from the root directory name, but configurable by the user), and the container's root cgroup is /machine/