]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
e2scrub: fix pathname escaping across all service definitions
authorDarrick J. Wong <djwong@kernel.org>
Fri, 17 Mar 2023 18:19:11 +0000 (11:19 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Fri, 15 Dec 2023 20:24:25 +0000 (12:24 -0800)
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>
scrub/e2scrub@.service.in
scrub/e2scrub_all.in
scrub/e2scrub_fail.in
scrub/e2scrub_fail@.service.in

index 496f894834a6e92941a46c7f5b35f8a68c07abed..6425263c2bc6189dca2ccbe3f8204a1336fac3b0 100644 (file)
@@ -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
index 4288b969849066f51136b9839cfdb4470b7a95ac..437f6cc2fa6f9766facef2871af2a9dc20245299 100644 (file)
@@ -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;
index 2c0754a9965c09c145b070ec881b548e5136c1c1..6899c47c6a56126746ae61451b325bdd8315da6e 100644 (file)
@@ -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
index 4bad311bb12dd05c2b8b1026f530a680838c73fa..ae65a1da3a94cf6535d5f99d72445df7ef06e780 100644 (file)
@@ -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