systemd/journalctl-pager-improvement.patch
Cristian Rodríguez 36b04c329c - Add use_localtime.patch: use /etc/localtime instead of
/etc/timezone (bnc#773491)
- Add support-suse-clock-sysconfig.patch: read SUSE
  /etc/sysconfig/clock file.
- Add drop-timezone.patch: drop support for /etc/timezone, never
  supported on openSUSE.
- Add journalctl-pager-improvement.patch: better handle output when
  using pager.
- Add fix-enable-disable-boot-initscript.patch: support boot.*
  initscripts for systemctl enable /disable (bnc#746506).

OBS-URL: https://build.opensuse.org/package/show/Base:System/systemd?expand=0&rev=298
2012-08-25 21:03:07 +00:00

449 lines
16 KiB
Diff

From 1682c4bf5b993b956b0367aedc9f0638055540f4 Mon Sep 17 00:00:00 2001
From: Eelco Dolstra <eelco.dolstra@logicblox.com>
Date: Thu, 19 Jul 2012 21:12:16 +0000
Subject: [PATCH 1/3] journalctl: fix assertion failure in ellipsize_mem()
When showing the journal through "journalctl --no-pager", if the
prefix of the log message (i.e. the date and syslog identifier) is
less than 3 characters shorter than the width of the terminal, you
get:
Assertion 'new_length >= 3' failed at src/shared/util.c:3859, function ellipsize_mem(). Aborting.
because there is not enough space for the "...". This patch add the
necessary check.
---
src/logs-show.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/logs-show.c b/src/logs-show.c
index eb9a902..72367f2 100644
--- a/src/logs-show.c
+++ b/src/logs-show.c
@@ -230,7 +230,7 @@ static int output_short(sd_journal *j, unsigned line, unsigned n_columns, bool s
printf(": [%s blob data]\n", format_bytes(bytes, sizeof(bytes), message_len));
} else if (message_len + n < n_columns)
printf(": %.*s\n", (int) message_len, message);
- else if (n < n_columns) {
+ else if (n < n_columns && n_columns - n - 2 >= 3) {
char *e;
e = ellipsize_mem(message, message_len, n_columns - n - 2, 90);
--
1.7.10.4
From ee385756e10862a8bcc0e5c7a3776135af84c750 Mon Sep 17 00:00:00 2001
From: Zbigniew Jedrzejewski-Szmek <zbyszek@in.waw.pl>
Date: Fri, 20 Jul 2012 09:06:26 +0200
Subject: [PATCH 2/3] journalctl: fix ellipsization with PAGER=cat
There are other reasons for not opening the pager then the --no-pager
or --follow options (described below). If the pager is not used,
messages must be ellipsized.
On Fri, Jul 20, 2012 at 05:42:44AM +0000, Shawn Landen wrote:
> "Pager to use when --no-pager is not given; overrides $PAGER.
> Setting this to an empty string or the value cat is equivalent to passing --no-pager."
Conflicts:
src/journal/journalctl.c
---
src/journal/journalctl.c | 5 +----
src/pager.c | 17 ++++++++++-------
src/pager.h | 4 +++-
3 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index f90b2dd..3a3b043 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -259,10 +259,7 @@ int main(int argc, char *argv[]) {
goto finish;
}
- if (!arg_no_pager && !arg_follow) {
- columns();
- pager_open();
- }
+ have_pager = !arg_no_pager && !arg_follow && pager_open();
if (arg_output == OUTPUT_JSON) {
fputc('[', stdout);
diff --git a/src/pager.c b/src/pager.c
index 3fc8182..8065841 100644
--- a/src/pager.c
+++ b/src/pager.c
@@ -44,20 +44,20 @@ _noreturn_ static void pager_fallback(void) {
_exit(EXIT_SUCCESS);
}
-void pager_open(void) {
+bool pager_open(void) {
int fd[2];
const char *pager;
pid_t parent_pid;
if (pager_pid > 0)
- return;
+ return false;
if ((pager = getenv("SYSTEMD_PAGER")) || (pager = getenv("PAGER")))
if (!*pager || streq(pager, "cat"))
- return;
+ return false;
if (isatty(STDOUT_FILENO) <= 0)
- return;
+ return false;
/* Determine and cache number of columns before we spawn the
* pager so that we get the value from the actual tty */
@@ -65,7 +65,7 @@ void pager_open(void) {
if (pipe(fd) < 0) {
log_error("Failed to create pager pipe: %m");
- return;
+ return false;
}
parent_pid = getpid();
@@ -74,7 +74,7 @@ void pager_open(void) {
if (pager_pid < 0) {
log_error("Failed to fork pager: %m");
close_pipe(fd);
- return;
+ return false;
}
/* In the child start the pager */
@@ -115,10 +115,13 @@ void pager_open(void) {
}
/* Return in the parent */
- if (dup2(fd[1], STDOUT_FILENO) < 0)
+ if (dup2(fd[1], STDOUT_FILENO) < 0) {
log_error("Failed to duplicate pager pipe: %m");
+ return false;
+ }
close_pipe(fd);
+ return true;
}
void pager_close(void) {
diff --git a/src/pager.h b/src/pager.h
index b5b4998..bd1a983 100644
--- a/src/pager.h
+++ b/src/pager.h
@@ -22,7 +22,9 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-void pager_open(void);
+#include <stdbool.h>
+
+bool pager_open(void);
void pager_close(void);
#endif
--
1.7.10.4
From ae88e07aec6280e90582703f7950468604182a4b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Tue, 17 Jul 2012 07:35:08 +0200
Subject: [PATCH 3/3] journalctl: do not ellipsize when using pager
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If a pager is used, ellipsization is redundant — the pager does
that better by hiding the part that cannot be shown. Pager's advantage
is that the user can press → to view the hidden part of a message,
and then ← to return.
cherry-picked from 92a1fd9e95954a557d6fe27b56f5ef1b89fc2f5e and 25277cd7fbd77e4c8b20572570aa77c7da9abcc2
---
src/journal/journalctl.c | 7 ++++-
src/logs-show.c | 66 ++++++++++++++++++++++++++++------------------
src/logs-show.h | 14 +++++++---
src/systemctl.c | 8 +++++-
4 files changed, 64 insertions(+), 31 deletions(-)
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 3a3b043..197af71 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -198,6 +198,7 @@ int main(int argc, char *argv[]) {
sd_journal *j = NULL;
unsigned line = 0;
bool need_seek = false;
+ bool have_pager;
log_parse_environment();
log_open();
@@ -268,6 +269,10 @@ int main(int argc, char *argv[]) {
for (;;) {
for (;;) {
+ int flags =
+ arg_show_all * OUTPUT_SHOW_ALL |
+ have_pager * OUTPUT_FULL_WIDTH;
+
if (need_seek) {
r = sd_journal_next(j);
if (r < 0) {
@@ -281,7 +286,7 @@ int main(int argc, char *argv[]) {
line ++;
- r = output_journal(j, arg_output, line, 0, arg_show_all);
+ r = output_journal(j, arg_output, line, 0, flags);
if (r < 0)
goto finish;
diff --git a/src/logs-show.c b/src/logs-show.c
index 72367f2..06ba569 100644
--- a/src/logs-show.c
+++ b/src/logs-show.c
@@ -86,7 +86,8 @@ static bool shall_print(bool show_all, char *p, size_t l) {
return true;
}
-static int output_short(sd_journal *j, unsigned line, unsigned n_columns, bool show_all, bool monotonic_mode) {
+static int output_short(sd_journal *j, unsigned line, unsigned n_columns,
+ OutputFlags flags) {
int r;
const void *data;
size_t length;
@@ -150,7 +151,7 @@ static int output_short(sd_journal *j, unsigned line, unsigned n_columns, bool s
goto finish;
}
- if (monotonic_mode) {
+ if (flags & OUTPUT_MONOTONIC_MODE) {
uint64_t t;
sd_id128_t boot_id;
@@ -202,33 +203,39 @@ static int output_short(sd_journal *j, unsigned line, unsigned n_columns, bool s
n += strlen(buf);
}
- if (hostname && shall_print(show_all, hostname, hostname_len)) {
+ if (hostname && shall_print(flags & OUTPUT_SHOW_ALL,
+ hostname, hostname_len)) {
printf(" %.*s", (int) hostname_len, hostname);
n += hostname_len + 1;
}
- if (identifier && shall_print(show_all, identifier, identifier_len)) {
+ if (identifier && shall_print(flags & OUTPUT_SHOW_ALL,
+ identifier, identifier_len)) {
printf(" %.*s", (int) identifier_len, identifier);
n += identifier_len + 1;
- } else if (comm && shall_print(show_all, comm, comm_len)) {
+ } else if (comm && shall_print(flags & OUTPUT_SHOW_ALL,
+ comm, comm_len)) {
printf(" %.*s", (int) comm_len, comm);
n += comm_len + 1;
- }
+ } else
+ putchar(' ');
- if (pid && shall_print(show_all, pid, pid_len)) {
+ if (pid && shall_print(flags & OUTPUT_SHOW_ALL, pid, pid_len)) {
printf("[%.*s]", (int) pid_len, pid);
n += pid_len + 2;
- } else if (fake_pid && shall_print(show_all, fake_pid, fake_pid_len)) {
+ } else if (fake_pid && shall_print(flags & OUTPUT_SHOW_ALL,
+ fake_pid, fake_pid_len)) {
printf("[%.*s]", (int) fake_pid_len, fake_pid);
n += fake_pid_len + 2;
}
- if (show_all)
+ if (flags & OUTPUT_SHOW_ALL)
printf(": %.*s\n", (int) message_len, message);
else if (contains_unprintable(message, message_len)) {
char bytes[FORMAT_BYTES_MAX];
printf(": [%s blob data]\n", format_bytes(bytes, sizeof(bytes), message_len));
- } else if (message_len + n < n_columns)
+ } else if ((flags & OUTPUT_FULL_WIDTH) ||
+ (message_len + n + 1 < n_columns))
printf(": %.*s\n", (int) message_len, message);
else if (n < n_columns && n_columns - n - 2 >= 3) {
char *e;
@@ -259,15 +266,18 @@ finish:
return r;
}
-static int output_short_realtime(sd_journal *j, unsigned line, unsigned n_columns, bool show_all) {
- return output_short(j, line, n_columns, show_all, false);
+static int output_short_realtime(sd_journal *j, unsigned line,
+ unsigned n_columns, OutputFlags flags) {
+ return output_short(j, line, n_columns, flags & ~OUTPUT_MONOTONIC_MODE);
}
-static int output_short_monotonic(sd_journal *j, unsigned line, unsigned n_columns, bool show_all) {
- return output_short(j, line, n_columns, show_all, true);
+static int output_short_monotonic(sd_journal *j, unsigned line,
+ unsigned n_columns, OutputFlags flags) {
+ return output_short(j, line, n_columns, flags | OUTPUT_MONOTONIC_MODE);
}
-static int output_verbose(sd_journal *j, unsigned line, unsigned n_columns, bool show_all) {
+static int output_verbose(sd_journal *j, unsigned line,
+ unsigned n_columns, OutputFlags flags) {
const void *data;
size_t length;
char *cursor;
@@ -296,7 +306,7 @@ static int output_verbose(sd_journal *j, unsigned line, unsigned n_columns, bool
free(cursor);
SD_JOURNAL_FOREACH_DATA(j, data, length) {
- if (!show_all && (length > PRINT_THRESHOLD ||
+ if (!(flags & OUTPUT_SHOW_ALL) && (length > PRINT_THRESHOLD ||
contains_unprintable(data, length))) {
const char *c;
char bytes[FORMAT_BYTES_MAX];
@@ -318,7 +328,8 @@ static int output_verbose(sd_journal *j, unsigned line, unsigned n_columns, bool
return 0;
}
-static int output_export(sd_journal *j, unsigned line, unsigned n_columns, bool show_all) {
+static int output_export(sd_journal *j, unsigned line,
+ unsigned n_columns, OutputFlags flags) {
sd_id128_t boot_id;
char sid[33];
int r;
@@ -424,7 +435,8 @@ static void json_escape(const char* p, size_t l) {
}
}
-static int output_json(sd_journal *j, unsigned line, unsigned n_columns, bool show_all) {
+static int output_json(sd_journal *j, unsigned line,
+ unsigned n_columns, OutputFlags flags) {
uint64_t realtime, monotonic;
char *cursor;
const void *data;
@@ -491,7 +503,8 @@ static int output_json(sd_journal *j, unsigned line, unsigned n_columns, bool sh
return 0;
}
-static int output_cat(sd_journal *j, unsigned line, unsigned n_columns, bool show_all) {
+static int output_cat(sd_journal *j, unsigned line,
+ unsigned n_columns, OutputFlags flags) {
const void *data;
size_t l;
int r;
@@ -512,7 +525,8 @@ static int output_cat(sd_journal *j, unsigned line, unsigned n_columns, bool sho
return 0;
}
-static int (*output_funcs[_OUTPUT_MODE_MAX])(sd_journal*j, unsigned line, unsigned n_columns, bool show_all) = {
+static int (*output_funcs[_OUTPUT_MODE_MAX])(sd_journal*j, unsigned line,
+ unsigned n_columns, OutputFlags flags) = {
[OUTPUT_SHORT] = output_short_realtime,
[OUTPUT_SHORT_MONOTONIC] = output_short_monotonic,
[OUTPUT_VERBOSE] = output_verbose,
@@ -521,14 +535,15 @@ static int (*output_funcs[_OUTPUT_MODE_MAX])(sd_journal*j, unsigned line, unsign
[OUTPUT_CAT] = output_cat
};
-int output_journal(sd_journal *j, OutputMode mode, unsigned line, unsigned n_columns, bool show_all) {
+int output_journal(sd_journal *j, OutputMode mode, unsigned line,
+ unsigned n_columns, OutputFlags flags) {
assert(mode >= 0);
assert(mode < _OUTPUT_MODE_MAX);
if (n_columns <= 0)
n_columns = columns();
- return output_funcs[mode](j, line, n_columns, show_all);
+ return output_funcs[mode](j, line, n_columns, flags);
}
int show_journal_by_unit(
@@ -537,8 +552,7 @@ int show_journal_by_unit(
unsigned n_columns,
usec_t not_before,
unsigned how_many,
- bool show_all,
- bool follow) {
+ OutputFlags flags) {
char *m = NULL;
sd_journal *j = NULL;
@@ -621,12 +635,12 @@ int show_journal_by_unit(
line ++;
- r = output_journal(j, mode, line, n_columns, show_all);
+ r = output_journal(j, mode, line, n_columns, flags);
if (r < 0)
goto finish;
}
- if (!follow)
+ if (!(flags & OUTPUT_FOLLOW))
break;
r = fd_wait_for_event(fd, POLLIN, (usec_t) -1);
diff --git a/src/logs-show.h b/src/logs-show.h
index db9c7e3..e8c6b03 100644
--- a/src/logs-show.h
+++ b/src/logs-show.h
@@ -39,7 +39,16 @@ typedef enum OutputMode {
_OUTPUT_MODE_INVALID = -1
} OutputMode;
-int output_journal(sd_journal *j, OutputMode mode, unsigned line, unsigned n_columns, bool show_all);
+typedef enum OutputFlags {
+ OUTPUT_SHOW_ALL = 1 << 0,
+ OUTPUT_MONOTONIC_MODE = 1 << 1,
+ OUTPUT_FOLLOW = 1 << 2,
+ OUTPUT_WARN_CUTOFF = 1 << 3,
+ OUTPUT_FULL_WIDTH = 1 << 4,
+} OutputFlags;
+
+int output_journal(sd_journal *j, OutputMode mode, unsigned line,
+ unsigned n_columns, OutputFlags flags);
int show_journal_by_unit(
const char *unit,
@@ -47,8 +56,7 @@ int show_journal_by_unit(
unsigned n_columns,
usec_t not_before,
unsigned how_many,
- bool show_all,
- bool follow);
+ OutputFlags flags);
const char* output_mode_to_string(OutputMode m);
OutputMode output_mode_from_string(const char *s);
diff --git a/src/systemctl.c b/src/systemctl.c
index f51085f..e94e024 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -2374,8 +2374,14 @@ static void print_status_info(UnitStatusInfo *i) {
}
if (i->id && arg_transport != TRANSPORT_SSH) {
+ int flags =
+ arg_lines * OUTPUT_SHOW_ALL |
+ arg_follow * OUTPUT_FOLLOW;
+
printf("\n");
- show_journal_by_unit(i->id, arg_output, 0, i->inactive_exit_timestamp_monotonic, arg_lines, arg_all, arg_follow);
+ show_journal_by_unit(i->id, arg_output, 0,
+ i->inactive_exit_timestamp_monotonic,
+ arg_lines, flags);
}
if (i->need_daemon_reload)
--
1.7.10.4