aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2023-03-17 11:19:11 -0700
committerDarrick J. Wong <djwong@kernel.org>2023-12-15 12:24:25 -0800
commitc45ca2925b031df1a85b8b35c8429fd4bf67c14d (patch)
tree3ba63eab5abde4a995aa2ba5027d4b31fc4461c7
parent260dfea450e387cbd2c8de79a7c2eeacc26f74e9 (diff)
downloade2fsprogs-c45ca2925b031df1a85b8b35c8429fd4bf67c14d.tar.gz
e2scrub: fix pathname escaping across all service definitions
systemd services provide an "instance name" that can be associated with a particular invocation of a service. This allows service users to invoke multiple copies of a service, each with a unique string. For e2scrub, we pass the mountpoint of the filesystem as the instance name. However, systemd services aren't supposed to have slashes in them, so we're supposed to escape them. The canonical escaping scheme for pathnames is defined by the systemd-escape --path command. Unfortunately, we've been adding our own opinionated sauce for years, to work around the fact that --path didn't quite work right in systemd before January 2017. The special sauce is incorrect, and we no longer care about systemd of 7 years past. Clean up this mess by following the systemd escaping scheme throughout the service units. Now we can use the '%f' specifier in them, which makes things a lot less complicated. Signed-off-by: Darrick J. Wong <djwong@kernel.org>
-rw-r--r--scrub/e2scrub@.service.in4
-rw-r--r--scrub/e2scrub_all.in20
-rw-r--r--scrub/e2scrub_fail.in10
-rw-r--r--scrub/e2scrub_fail@.service.in4
4 files changed, 13 insertions, 25 deletions
diff --git a/scrub/e2scrub@.service.in b/scrub/e2scrub@.service.in
index 496f89483..6425263c2 100644
--- a/scrub/e2scrub@.service.in
+++ b/scrub/e2scrub@.service.in
@@ -1,5 +1,5 @@
[Unit]
-Description=Online ext4 Metadata Check for %I
+Description=Online ext4 Metadata Check for %f
OnFailure=e2scrub_fail@%i.service
Documentation=man:e2scrub(8)
@@ -16,5 +16,5 @@ User=root
IOSchedulingClass=idle
CPUSchedulingPolicy=idle
Environment=SERVICE_MODE=1
-ExecStart=@root_sbindir@/e2scrub -t %I
+ExecStart=@root_sbindir@/e2scrub -t %f
SyslogIdentifier=%N
diff --git a/scrub/e2scrub_all.in b/scrub/e2scrub_all.in
index 4288b9698..437f6cc2f 100644
--- a/scrub/e2scrub_all.in
+++ b/scrub/e2scrub_all.in
@@ -146,22 +146,10 @@ ls_targets() {
fi
}
-# systemd doesn't know to do path escaping on the instance variable we pass
-# to the e2scrub service, which breaks things if there is a dash in the path
-# name. Therefore, do the path escaping ourselves if needed.
-#
-# systemd path escaping also drops the initial slash so we add that back in so
-# that log messages from the service units preserve the full path and users can
-# look up log messages using full paths. However, for "/" the escaping rules
-# do /not/ drop the initial slash, so we have to special-case that here.
+# Turn our mount path into a service name that systemd will recognize
escape_path_for_systemd() {
local path="$1"
-
- if [ "${path}" != "/" ]; then
- echo "-$(systemd-escape --path "${path}")"
- else
- echo "-"
- fi
+ systemd-escape --template 'e2scrub@.service' --path "${path}"
}
# Scrub any mounted fs on lvm by creating a snapshot and fscking that.
@@ -170,8 +158,8 @@ for tgt in "${targets[@]}"; do
# If we're not reaping and systemd is present, try invoking the
# systemd service.
if [ "${reap}" -ne 1 ] && type systemctl > /dev/null 2>&1; then
- tgt_esc="$(escape_path_for_systemd "${tgt}")"
- ${DBG} systemctl start "e2scrub@${tgt_esc}" 2> /dev/null
+ svcname="$(escape_path_for_systemd "${tgt}")"
+ ${DBG} systemctl start "${svcname}" 2> /dev/null
res=$?
if [ "${res}" -eq 0 ] || [ "${res}" -eq 1 ]; then
continue;
diff --git a/scrub/e2scrub_fail.in b/scrub/e2scrub_fail.in
index 2c0754a99..6899c47c6 100644
--- a/scrub/e2scrub_fail.in
+++ b/scrub/e2scrub_fail.in
@@ -2,8 +2,8 @@
# Email logs of failed e2scrub unit runs when the systemd service fails.
-device="$1"
-test -z "${device}" && exit 0
+mntpoint="$1"
+test -z "${mntpoint}" && exit 0
if ! type sendmail > /dev/null 2>&1; then
echo "$0: sendmail program not found."
@@ -16,7 +16,7 @@ fi
hostname="$(hostname -f 2>/dev/null)"
test -z "${hostname}" && hostname="${HOSTNAME}"
-service_name="e2scrub@$(systemd-escape ${device})"
+service_name="$(systemd-escape --template "e2scrub@.service" --path "${mntpoint}")"
if test -z "${recipient}" ; then
recipient="root"
@@ -29,9 +29,9 @@ fi
(cat << ENDL
To: ${recipient}
From: ${sender}
-Subject: e2scrub failure on ${device}
+Subject: e2scrub failure on ${mntpoint}
-So sorry, the automatic e2scrub of ${device} on ${hostname} failed.
+So sorry, the automatic e2scrub of ${mntpoint} on ${hostname} failed.
A log of what happened follows:
ENDL
diff --git a/scrub/e2scrub_fail@.service.in b/scrub/e2scrub_fail@.service.in
index 4bad311bb..ae65a1da3 100644
--- a/scrub/e2scrub_fail@.service.in
+++ b/scrub/e2scrub_fail@.service.in
@@ -1,10 +1,10 @@
[Unit]
-Description=Online ext4 Metadata Check Failure Reporting for %I
+Description=Online ext4 Metadata Check Failure Reporting for %f
Documentation=man:e2scrub(8)
[Service]
Type=oneshot
-ExecStart=@pkglibdir@/e2scrub_fail "%I"
+ExecStart=@pkglibdir@/e2scrub_fail "%f"
User=mail
Group=mail
SupplementaryGroups=systemd-journal