[systemd-commits] 2 commits - man/journalctl.xml src/core TODO
Zbigniew JÄdrzejewski-Szmek
zbyszek at kemper.freedesktop.org
Mon Jul 15 18:35:24 PDT 2013
TODO | 2 -
man/journalctl.xml | 14 ++++++++
src/core/execute.c | 42 ++++++++++++++++++++------
src/core/manager.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++--
src/core/manager.h | 7 +++-
src/core/transaction.c | 5 ++-
src/core/unit.c | 12 +++++--
7 files changed, 140 insertions(+), 20 deletions(-)
New commits:
commit 31a7eb86f18b0466681d6fbe80c148f96c551c80
Author: Zbigniew JÄdrzejewski-Szmek <zbyszek at in.waw.pl>
Date: Mon Jul 15 21:34:57 2013 -0400
systemd: do not output status messages once gettys are running
Make Type=idle communication bidirectional: when bootup is finished,
the manager, as before, signals idling Type=idle jobs to continue.
However, if the boot takes too long, idling jobs signal the manager
that they have had enough, wait a tiny bit more, and continue, taking
ownership of the console. The manager, when signalled that Type=idle
jobs are done, makes a note and will not write to the console anymore.
This is a cosmetic issue, but quite noticable, so let's just fix it.
Based on Harald Hoyer's patch.
https://bugs.freedesktop.org/show_bug.cgi?id=54247
http://unix.stackexchange.com/questions/51805/systemd-messages-after-starting-login/
diff --git a/src/core/execute.c b/src/core/execute.c
index 50d2d49..43b571e 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -69,6 +69,7 @@
#include "unit.h"
#define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC)
+#define IDLE_TIMEOUT2_USEC (1*USEC_PER_SEC)
/* This assumes there is a 'tty' group */
#define TTY_MODE 0620
@@ -977,6 +978,35 @@ static int apply_seccomp(uint32_t *syscall_filter) {
return 0;
}
+static void do_idle_pipe_dance(int idle_pipe[4]) {
+ assert(idle_pipe);
+
+ if (idle_pipe[1] >= 0)
+ close_nointr_nofail(idle_pipe[1]);
+ if (idle_pipe[2] >= 0)
+ close_nointr_nofail(idle_pipe[2]);
+
+ if (idle_pipe[0] >= 0) {
+ int r;
+
+ r = fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT_USEC);
+
+ if (idle_pipe[3] >= 0 && r == 0 /* timeout */) {
+ /* Signal systemd that we are bored and want to continue. */
+ write(idle_pipe[3], "x", 1);
+
+ /* Wait for systemd to react to the signal above. */
+ fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT2_USEC);
+ }
+
+ close_nointr_nofail(idle_pipe[0]);
+
+ }
+
+ if (idle_pipe[3] >= 0)
+ close_nointr_nofail(idle_pipe[3]);
+}
+
int exec_spawn(ExecCommand *command,
char **argv,
ExecContext *context,
@@ -989,7 +1019,7 @@ int exec_spawn(ExecCommand *command,
CGroupControllerMask cgroup_mask,
const char *cgroup_path,
const char *unit_id,
- int idle_pipe[2],
+ int idle_pipe[4],
pid_t *ret) {
_cleanup_strv_free_ char **files_env = NULL;
@@ -1083,14 +1113,8 @@ int exec_spawn(ExecCommand *command,
goto fail_child;
}
- if (idle_pipe) {
- if (idle_pipe[1] >= 0)
- close_nointr_nofail(idle_pipe[1]);
- if (idle_pipe[0] >= 0) {
- fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT_USEC);
- close_nointr_nofail(idle_pipe[0]);
- }
- }
+ if (idle_pipe)
+ do_idle_pipe_dance(idle_pipe);
/* Close sockets very early to make sure we don't
* block init reexecution because it cannot bind its
diff --git a/src/core/manager.c b/src/core/manager.c
index 2e98181..ad1a8d6 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -273,6 +273,58 @@ static void manager_print_jobs_in_progress(Manager *m) {
m->jobs_in_progress_iteration++;
}
+static int manager_watch_idle_pipe(Manager *m) {
+ struct epoll_event ev = {
+ .events = EPOLLIN,
+ .data.ptr = &m->idle_pipe_watch,
+ };
+ int r;
+
+ if (m->idle_pipe_watch.type != WATCH_INVALID)
+ return 0;
+
+ if (m->idle_pipe[2] < 0)
+ return 0;
+
+ m->idle_pipe_watch.type = WATCH_IDLE_PIPE;
+ m->idle_pipe_watch.fd = m->idle_pipe[2];
+ if (m->idle_pipe_watch.fd < 0) {
+ log_error("Failed to create timerfd: %m");
+ r = -errno;
+ goto err;
+ }
+
+ if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->idle_pipe_watch.fd, &ev) < 0) {
+ log_error("Failed to add idle_pipe fd to epoll: %m");
+ r = -errno;
+ goto err;
+ }
+
+ log_debug("Set up idle_pipe watch.");
+ log_debug("m->epoll_fd=%d m->idle_pipe_watch.fd=%d",
+ m->epoll_fd, m->idle_pipe_watch.fd);
+
+ return 0;
+
+err:
+ if (m->idle_pipe_watch.fd >= 0)
+ close_nointr_nofail(m->idle_pipe_watch.fd);
+ watch_init(&m->idle_pipe_watch);
+ return r;
+}
+
+static void manager_unwatch_idle_pipe(Manager *m) {
+ if (m->idle_pipe_watch.type != WATCH_IDLE_PIPE)
+ return;
+
+ log_debug("m->epoll_fd=%d m->idle_pipe_watch.fd=%d",
+ m->epoll_fd, m->idle_pipe_watch.fd);
+ assert_se(epoll_ctl(m->epoll_fd, EPOLL_CTL_DEL, m->idle_pipe_watch.fd, NULL) >= 0);
+ watch_init(&m->idle_pipe_watch);
+
+ log_debug("Closed idle_pipe watch.");
+}
+
static int manager_setup_time_change(Manager *m) {
struct epoll_event ev = {
.events = EPOLLIN,
@@ -445,7 +497,7 @@ int manager_new(SystemdRunningAs running_as, bool reexecuting, Manager **_m) {
m->name_data_slot = m->conn_data_slot = m->subscribed_data_slot = -1;
m->exit_code = _MANAGER_EXIT_CODE_INVALID;
m->pin_cgroupfs_fd = -1;
- m->idle_pipe[0] = m->idle_pipe[1] = -1;
+ m->idle_pipe[0] = m->idle_pipe[1] = m->idle_pipe[2] = m->idle_pipe[3] = -1;
watch_init(&m->signal_watch);
watch_init(&m->mount_watch);
@@ -657,6 +709,11 @@ static void manager_clear_jobs_and_units(Manager *m) {
m->n_running_jobs = 0;
}
+static void close_idle_pipe(Manager *m) {
+ close_pipe(m->idle_pipe);
+ close_pipe(m->idle_pipe + 2);
+}
+
void manager_free(Manager *m) {
UnitType c;
int i;
@@ -701,7 +758,7 @@ void manager_free(Manager *m) {
hashmap_free(m->cgroup_unit);
set_free_free(m->unit_path_cache);
- close_pipe(m->idle_pipe);
+ close_idle_pipe(m);
free(m->switch_root);
free(m->switch_root_init);
@@ -1138,6 +1195,9 @@ unsigned manager_dispatch_run_queue(Manager *m) {
if (m->n_running_jobs > 0)
manager_watch_jobs_in_progress(m);
+ if (m->n_on_console > 0)
+ manager_watch_idle_pipe(m);
+
return n;
}
@@ -1691,6 +1751,14 @@ static int process_event(Manager *m, struct epoll_event *ev) {
break;
}
+ case WATCH_IDLE_PIPE: {
+ m->no_console_output = true;
+
+ manager_unwatch_idle_pipe(m);
+ close_idle_pipe(m);
+ break;
+ }
+
default:
log_error("event type=%i", w->type);
assert_not_reached("Unknown epoll event type.");
@@ -2384,7 +2452,8 @@ void manager_check_finished(Manager *m) {
}
/* Notify Type=idle units that we are done now */
- close_pipe(m->idle_pipe);
+ manager_unwatch_idle_pipe(m);
+ close_idle_pipe(m);
/* Turn off confirm spawn now */
m->confirm_spawn = false;
@@ -2660,6 +2729,9 @@ static bool manager_get_show_status(Manager *m) {
if (m->running_as != SYSTEMD_SYSTEM)
return false;
+ if (m->no_console_output)
+ return false;
+
if (m->show_status)
return true;
diff --git a/src/core/manager.h b/src/core/manager.h
index 6d52414..bd068ac 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -63,7 +63,8 @@ enum WatchType {
WATCH_DBUS_WATCH,
WATCH_DBUS_TIMEOUT,
WATCH_TIME_CHANGE,
- WATCH_JOBS_IN_PROGRESS
+ WATCH_JOBS_IN_PROGRESS,
+ WATCH_IDLE_PIPE,
};
struct Watch {
@@ -135,6 +136,7 @@ struct Manager {
Watch signal_watch;
Watch time_change_watch;
Watch jobs_in_progress_watch;
+ Watch idle_pipe_watch;
int epoll_fd;
@@ -227,6 +229,7 @@ struct Manager {
bool show_status;
bool confirm_spawn;
+ bool no_console_output;
ExecOutput default_std_output, default_std_error;
@@ -244,7 +247,7 @@ struct Manager {
unsigned jobs_in_progress_iteration;
/* Type=idle pipes */
- int idle_pipe[2];
+ int idle_pipe[4];
char *switch_root;
char *switch_root_init;
diff --git a/src/core/transaction.c b/src/core/transaction.c
index 5259a5b..27efef7 100644
--- a/src/core/transaction.c
+++ b/src/core/transaction.c
@@ -733,8 +733,11 @@ int transaction_activate(Transaction *tr, Manager *m, JobMode mode, DBusError *e
* feature for cosmetics, not actually useful for
* anything beyond that. */
- if (m->idle_pipe[0] < 0 && m->idle_pipe[1] < 0)
+ if (m->idle_pipe[0] < 0 && m->idle_pipe[1] < 0 &&
+ m->idle_pipe[2] < 0 && m->idle_pipe[3] < 0) {
pipe2(m->idle_pipe, O_NONBLOCK|O_CLOEXEC);
+ pipe2(m->idle_pipe + 2, O_NONBLOCK|O_CLOEXEC);
+ }
}
return 0;
diff --git a/src/core/unit.c b/src/core/unit.c
index b245356..f4f92f0 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -1425,10 +1425,14 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
if (UNIT_IS_INACTIVE_OR_FAILED(os) != UNIT_IS_INACTIVE_OR_FAILED(ns)) {
ExecContext *ec = unit_get_exec_context(u);
if (ec && exec_context_may_touch_console(ec)) {
- if (UNIT_IS_INACTIVE_OR_FAILED(ns))
- m->n_on_console--;
- else
- m->n_on_console++;
+ if (UNIT_IS_INACTIVE_OR_FAILED(ns)) {
+ m->n_on_console --;
+
+ if (m->n_on_console == 0)
+ /* unset no_console_output flag, since the console is free */
+ m->no_console_output = 0;
+ } else
+ m->n_on_console ++;
}
}
commit 77a9e8de6572db6ba5ca49023937b67fc835f356
Author: Zbigniew JÄdrzejewski-Szmek <zbyszek at in.waw.pl>
Date: Mon Jul 15 21:03:17 2013 -0400
man: add note about paging and colors to journalctl(1)
diff --git a/TODO b/TODO
index 88d9ae6..3fa384c 100644
--- a/TODO
+++ b/TODO
@@ -357,7 +357,7 @@ Features:
- refuse taking lower-case variable names in sd_journal_send() and friends.
- journald: we currently rotate only after MaxUse+MaxFilesize has been reached.
- journal: deal nicely with byte-by-byte copied files, especially regards header
- - journalctl: show multiline log messages sanely, expand tabs, and show all valid utf8 messages
+ - journalctl: expand tabs
- journal: store euid in journal if it differs from uid
- journal: sanely deal with entries which are larger than the individual file size, but where the components would fit
- Replace utmp, wtmp, btmp, and lastlog completely with journal
diff --git a/man/journalctl.xml b/man/journalctl.xml
index 71b1bab..b8b29b4 100644
--- a/man/journalctl.xml
+++ b/man/journalctl.xml
@@ -107,6 +107,20 @@
users who are members of the <literal>adm</literal>
group get access to the system journal and the
journals of other users.</para>
+
+ <para>The output is paged through
+ <command>less</command> by default, and long lines are
+ "truncated" to screen width. The hidden part can be
+ viewed by using the left-arrow and right-arrow
+ keys. Paging can be disabled, see
+ <option>--no-pager</option> and section Environment
+ below.</para>
+
+ <para>When outputing to a tty, lines are colored
+ according to priority: lines of level ERROR and higher
+ are colored red, lines of level NOTICE and higher are
+ highlighted, and other lines are displayed normally.
+ </para>
</refsect1>
<refsect1>
More information about the systemd-commits
mailing list