init: Use journald as the systems logging daemon

Use systemd's journald as the systems logging daemon.
See go/improve-cros-logging for details.

BUG=b:120686750
TEST=journalctl shows log output
TEST=/var/log/messages is still populated
CQ-DEPEND=CL:1372288

Change-Id: Ia06c895bb003864451438e334abf92f957e8bcb8
Reviewed-on: https://chromium-review.googlesource.com/1368791
Commit-Ready: Christopher Morin <cmtm@google.com>
Tested-by: Christopher Morin <cmtm@google.com>
Reviewed-by: Yusuke Sato <yusukes@chromium.org>
diff --git a/init/rsyslog.chromeos b/init/rsyslog.chromeos
index 2f75df7..4ee3abd 100644
--- a/init/rsyslog.chromeos
+++ b/init/rsyslog.chromeos
@@ -4,20 +4,22 @@
 #
 
 $ModLoad immark.so # provides --MARK-- message capability
-$ModLoad imuxsock.so # provides support for local system logging (e.g. via logger command)
-$ModLoad imklog.so # kernel logging (formerly provided by rklogd)
+module(load="imuxsock"
+       SysSock.Use="on"
+       SysSock.Name="/run/systemd/journal/syslog"
+       SysSock.UsePIDFromSystem="on")
+# Allow messages from upstart, which logs through /dev/klog.
+module(load="imklog"
+       PermitNonKernelFacility="on")
 
 $PrivDropToUser syslog
 $PrivDropToGroup syslog
 
-# Include PID in log messages
-$SystemLogUsePIDFromSystem on
-
 # Don't include hostname in log messages.
-$template LogWithoutHostname,"%TIMESTAMP:::date-rfc3339% %syslogseverity-text:::uppercase% %syslogtag%%msg:::sp-if-no-1st-sp%%msg::drop-last-lf%\n"
-$ActionFileDefaultTemplate LogWithoutHostname
+template(name="LogWithoutHostname" type="string"
+         string="%TIMESTAMP:::date-rfc3339% %syslogseverity-text:::uppercase% %syslogtag%%msg:::sp-if-no-1st-sp%%msg::drop-last-lf%\n")
+module(load="builtin:omfile" Template="LogWithoutHostname")
 
-$SystemLogRateLimitInterval 0
 $RepeatedMsgReduction on
 
 # Merge and include all *.conf files.
@@ -25,9 +27,6 @@
 # *.conf files that are to be included.
 $IncludeConfig /etc/rsyslog.d/*.conf
 
-# Allow messages from upstart, which logs through /dev/klog.
-$KLogPermitNonKernelFacility on
-
 # Keep network stuff in /var/log/net.log
 if (($programname == 'shill') or \
     ($programname == 'dhcpcd') or \
diff --git a/init/upstart/journald.conf b/init/upstart/journald.conf
new file mode 100644
index 0000000..b7bed0b
--- /dev/null
+++ b/init/upstart/journald.conf
@@ -0,0 +1,51 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+description      "systemd-journald"
+author           "chromium-os-dev@chromium.org"
+
+start on starting boot-services
+stop on stopping boot-services
+
+expect fork
+respawn
+
+pre-start script
+  mkdir -p /run/systemd/journal
+  chown syslog /run/systemd/journal
+
+  mkdir -p /run/log
+  chown syslog /run/log
+
+  ln -sf /run/systemd/journal/dev-log /dev/log
+end script
+
+# Upstart has limitation on how it can track daemon readiness.  See this report
+# for more details: https://crbug.com/702794#27. net_poll_tool allows us to
+# emit the started event only after the socket is ready.
+# /run/systemd/journal/socket is the last socket created by journald.
+
+# CAP_SYS_PTRACE is required to read /proc/<PID>/exe.
+# We aren't going to give that capability to journald due to security concerns.
+exec minijail0 -u syslog -g syslog -c 'cap_syslog+e' -i -e -n \
+               -f /run/systemd-journald.pid \
+               -P /var/empty -b / -b /proc -b /dev,,1 -b /run,,1 \
+               -k tmpfs,/var,tmpfs,0xe -b /var/log,,1 \
+                /lib/systemd/systemd-journald
+
+post-start script
+  # The timeout is high, but it should never be hit unless there's a serious
+  # problem, in which case we want to fall over anyways.  We can't set it too
+  # low because we also run in slow environments like VMs.
+  net_poll_tool --timeout=60 --unix_socket=/run/systemd/journal/socket
+
+  # This is needed to flush the journal to persistent storage
+  pkill -SIGUSR1 --pidfile /run/systemd-journald.pid
+end script
+
+post-stop script
+  rm /dev/log || true
+  rm /run/systemd-journald.pid || true
+end script
+
diff --git a/init/upstart/syslog.conf b/init/upstart/syslog.conf
index 87315a5..36f4af0 100644
--- a/init/upstart/syslog.conf
+++ b/init/upstart/syslog.conf
@@ -5,8 +5,8 @@
 description   "Syslog daemon"
 author        "chromium-os-dev@chromium.org"
 
-start on starting boot-services
-stop on stopping boot-services
+start on started journald
+stop on stopping journald
 expect fork
 respawn
 
@@ -25,29 +25,18 @@
   mkdir -p /var/lib/timezone
 end script
 
-# The way upstart tracks daemon readiness is not the way we need it to.  In the
-# normal forking/daemon mode (no -n), rsyslog will fork and then wait for the
-# child to prepare /dev/log before exiting.  However, upstart will see the first
-# fork and mark the service started immediately and not wait for rsyslog itself
-# to exit.  That creates a small window where other services may start and try
-# to use syslog which would fail.  That's why we don't bother using daemon mode
-# (we pass -n), and why we need the poll command below.
-# See this report for more details: https://crbug.com/702794#27
-#
 # We don't use --mount-dev because of the way the /dev/log unix socket works.
 # See https://crbug.com/764455#c6 for details.
 #
+# rsyslogd creates it's unix domain socket at /run/systemd/journal/syslog.
+# Journald forwards messages to that address.
+#
 # We don't use a pid namespace because that breaks syslog's ability to log the
 # remote pid.  Otherwise the logs would look like (where [0] is the pid):
 # INFO sshd[0]: ...
 exec /sbin/minijail0 -l --uts -i -v -e -t -P /var/empty -T static \
-    -b / -b /dev,,1 -b /proc -k tmpfs,/var,tmpfs,0xe -b /var/log,,1 \
-    -b /var/lib/timezone \
+    -b / -b /dev,,1 -b /proc \
+    -k tmpfs,/run,tmpfs,0xe -b /run/systemd/journal,,1 \
+    -k tmpfs,/var,tmpfs,0xe -b /var/log,,1 -b /var/lib/timezone \
     /usr/sbin/rsyslogd -n -f /etc/rsyslog.chromeos -i /tmp/rsyslogd.pid
 
-# See above comment for why we need to poll ourselves.
-#
-# The timeout is high, but it should never be hit unless there's a serious
-# problem, in which case we want to fall over anyways.  We can't set it too
-# low because we also run in slow environments like VMs.
-post-start exec net_poll_tool --timeout=60 --unix_socket=/dev/log
diff --git a/init/upstart/udev-trigger-early.conf b/init/upstart/udev-trigger-early.conf
index 4878949..969dad1 100644
--- a/init/upstart/udev-trigger-early.conf
+++ b/init/upstart/udev-trigger-early.conf
@@ -20,6 +20,7 @@
 # graphics & drm - required to set permissions for accelerated graphics
 # nvhost & tegra_dc_ext - on nVidia systems, X needs this
 # tty - opened by powerd (running as user in "tty" group) at startup
+# mem - kmsg opened by journald
 
 # N.B.  The 'boot-services' start on condition assumes this
 # dependency on 'udev'.  Don't change this line without accounting
@@ -31,7 +32,7 @@
     --subsystem-match="input" --subsystem-match="misc" \
     --subsystem-match="graphics" --subsystem-match="drm" \
     --subsystem-match="nvhost" --subsystem-match="tegra_dc_ext" \
-    --subsystem-match="tty"
+    --subsystem-match="tty" --subsystem-match="mem"
   # Trigger graphics pci devices that may load as modules
   udevadm trigger --settle --subsystem-match=pci --attr-match=class=0x030000
 end script
diff --git a/init/upstart/udev-trigger.conf b/init/upstart/udev-trigger.conf
index 891fd05..e6d99da 100644
--- a/init/upstart/udev-trigger.conf
+++ b/init/upstart/udev-trigger.conf
@@ -22,6 +22,6 @@
     --subsystem-nomatch="input" --subsystem-nomatch="misc" \
     --subsystem-nomatch="graphics" --subsystem-nomatch="drm" \
     --subsystem-nomatch="nvhost" --subsystem-nomatch="tegra_dc_ext" \
-    --attr-nomatch="name=cros-ec-accel*"
+    --subsystem-nomatch="mem" --attr-nomatch="name=cros-ec-accel*"
   exec udevadm settle
 end script