@@ -21,6 +21,7 @@ SYSTEMD_SERVICES=\
xfs_scrub_media@.service \
xfs_scrub_media_fail@.service \
xfs_scrub_all.service \
+ xfs_scrub_all_fail.service \
xfs_scrub_all.timer \
system-xfs_scrub.slice
OPTIONAL_TARGETS += $(SYSTEMD_SERVICES)
@@ -5,6 +5,7 @@
[Unit]
Description=Online XFS Metadata Check for All Filesystems
+OnFailure=xfs_scrub_all_fail.service
ConditionACPower=true
Documentation=man:xfs_scrub_all(8)
After=paths.target multi-user.target network.target network-online.target systemd-networkd.service NetworkManager.service connman.service
new file mode 100644
@@ -0,0 +1,67 @@
+[Unit]
+Description=Online XFS Metadata Check for All Filesystems Failure Reporting
+Documentation=man:xfs_scrub_all(8)
+
+[Service]
+Type=oneshot
+Environment=EMAIL_ADDR=root
+ExecStart=@pkg_lib_dir@/@pkg_name@/xfs_scrub_fail "${EMAIL_ADDR}" xfs_scrub_all
+User=mail
+Group=mail
+SupplementaryGroups=systemd-journal
+
+# No realtime scheduling
+RestrictRealtime=true
+
+# Make the entire filesystem readonly and /home inaccessible, then bind mount
+# the filesystem we're supposed to be checking into our private /tmp dir.
+ProtectSystem=full
+ProtectHome=yes
+PrivateTmp=true
+RestrictSUIDSGID=true
+
+# Emailing reports requires network access, but not the ability to change the
+# hostname.
+ProtectHostname=true
+
+# Don't let the program mess with the kernel configuration at all
+ProtectKernelLogs=true
+ProtectKernelModules=true
+ProtectKernelTunables=true
+ProtectControlGroups=true
+ProtectProc=invisible
+RestrictNamespaces=true
+
+# Can't hide /proc because journalctl needs it to find various pieces of log
+# information
+#ProcSubset=pid
+
+# Only allow the default personality Linux
+LockPersonality=true
+
+# No writable memory pages
+MemoryDenyWriteExecute=true
+
+# Don't let our mounts leak out to the host
+PrivateMounts=true
+
+# Restrict system calls to the native arch and only enough to get things going
+SystemCallArchitectures=native
+SystemCallFilter=@system-service
+SystemCallFilter=~@privileged
+SystemCallFilter=~@resources
+SystemCallFilter=~@mount
+
+# xfs_scrub needs these privileges to run, and no others
+CapabilityBoundingSet=
+NoNewPrivileges=true
+
+# Failure reporting shouldn't create world-readable files
+UMask=0077
+
+# Clean up any IPC objects when this unit stops
+RemoveIPC=true
+
+# No access to hardware device files
+PrivateDevices=true
+ProtectClock=true
@@ -5,14 +5,13 @@
# Copyright (C) 2018 Oracle. All Rights Reserved.
# Author: Darrick J. Wong <djwong@kernel.org>
-# Email logs of failed xfs_scrub unit runs
+# Email logs of failed xfs_scrub and xfs_scrub_all unit runs
recipient="$1"
test -z "${recipient}" && exit 0
service="$2"
test -z "${service}" && exit 0
mntpoint="$3"
-test -z "${mntpoint}" && exit 0
hostname="$(hostname -f 2>/dev/null)"
test -z "${hostname}" && hostname="${HOSTNAME}"
@@ -47,10 +46,12 @@ escape_path() {
echo "-$(systemd-escape --path "${mntpoint}")"
}
-mntpoint_esc="$(escape_path "${mntpoint}")"
+fail_mail_mntpoint() {
+ local mntpoint_esc
-(cat << ENDL
-To: $1
+ mntpoint_esc="$(escape_path "${mntpoint}")"
+ cat << ENDL
+To: ${recipient}
From: <${service}@${hostname}>
Subject: ${service} failure on ${mntpoint}
@@ -58,5 +59,25 @@ So sorry, the automatic ${service} of ${mntpoint} on ${hostname} failed.
A log of what happened follows:
ENDL
-systemctl status --full --lines 4294967295 "${service}@${mntpoint_esc}") | "${mailer}" -t -i
+ systemctl status --full --lines 4294967295 "${service}@${mntpoint_esc}"
+}
+
+fail_mail() {
+ cat << ENDL
+To: ${recipient}
+From: <${service}@${hostname}>
+Subject: ${service} failure
+
+So sorry, the automatic ${service} on ${hostname} failed.
+
+A log of what happened follows:
+ENDL
+ systemctl status --full --lines 4294967295 "${service}"
+}
+
+if [ -n "${mntpoint}" ]; then
+ fail_mail_mntpoint | "${mailer}" -t -i
+else
+ fail_mail | "${mailer}" -t -i
+fi
exit "${PIPESTATUS[1]}"