aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarlos Maiolino <cem@kernel.org>2024-01-23 11:30:03 +0100
committerCarlos Maiolino <cem@kernel.org>2024-01-23 11:30:03 +0100
commit9b641bcd17122dba0a6e919531b2a7531d94e420 (patch)
tree96ca7524a1b4b1e29b50a9603004ce85f62a5c36
parent0f7e58a387f57ebda2566916b545077f51dc2da1 (diff)
parent3d37d8bf535fd6a8ab241a86433b449152746e6a (diff)
downloadxfsprogs-dev-9b641bcd17122dba0a6e919531b2a7531d94e420.tar.gz
Merge tag 'scrub-service-fixes-6.6_2024-01-11' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfsprogs-dev into for-next
xfs_scrub: fixes for systemd services [v28.3 4/6] This series fixes deficiencies in the systemd services that were created to manage background scans. First, improve the debian packaging so that services get installed at package install time. Next, fix copyright and spdx header omissions. Finally, fix bugs in the mailer scripts so that scrub failures are reported effectively. Finally, fix xfs_scrub_all to deal with systemd restarts causing it to think that a scrub has finished before the service actually finishes. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
-rwxr-xr-xdebian/rules1
-rw-r--r--include/builddefs.in2
-rw-r--r--scrub/Makefile26
-rw-r--r--scrub/xfs_scrub@.service.in6
-rw-r--r--scrub/xfs_scrub_all.in53
-rwxr-xr-xscrub/xfs_scrub_fail.in (renamed from scrub/xfs_scrub_fail)12
-rw-r--r--scrub/xfs_scrub_fail@.service.in4
7 files changed, 57 insertions, 47 deletions
diff --git a/debian/rules b/debian/rules
index 95df4835b2..57baad625c 100755
--- a/debian/rules
+++ b/debian/rules
@@ -108,6 +108,7 @@ binary-arch: checkroot built
dh_compress
dh_fixperms
dh_makeshlibs
+ dh_installsystemd -p xfsprogs --no-enable --no-start --no-restart-after-upgrade --no-stop-on-upgrade
dh_installdeb
dh_shlibdeps
dh_gencontrol
diff --git a/include/builddefs.in b/include/builddefs.in
index 43025ba4fc..a3745efbe2 100644
--- a/include/builddefs.in
+++ b/include/builddefs.in
@@ -51,7 +51,7 @@ PKG_SBIN_DIR = @sbindir@
PKG_ROOT_SBIN_DIR = @root_sbindir@
PKG_ROOT_LIB_DIR= @root_libdir@@libdirsuffix@
PKG_LIB_DIR = @libdir@@libdirsuffix@
-PKG_LIB_SCRIPT_DIR = @libdir@
+PKG_LIBEXEC_DIR = @libexecdir@/@pkg_name@
PKG_INC_DIR = @includedir@/xfs
DK_INC_DIR = @includedir@/disk
PKG_MAN_DIR = @mandir@
diff --git a/scrub/Makefile b/scrub/Makefile
index 24af971612..4368897f2c 100644
--- a/scrub/Makefile
+++ b/scrub/Makefile
@@ -8,14 +8,17 @@ include $(builddefs)
SCRUB_PREREQS=$(HAVE_OPENAT)$(HAVE_FSTATAT)$(HAVE_GETFSMAP)
+scrub_svcname=xfs_scrub@.service
+
ifeq ($(SCRUB_PREREQS),yesyesyes)
LTCOMMAND = xfs_scrub
INSTALL_SCRUB = install-scrub
XFS_SCRUB_ALL_PROG = xfs_scrub_all
+XFS_SCRUB_FAIL_PROG = xfs_scrub_fail
XFS_SCRUB_ARGS = -b -n
ifeq ($(HAVE_SYSTEMD),yes)
INSTALL_SCRUB += install-systemd
-SYSTEMD_SERVICES = xfs_scrub@.service xfs_scrub_all.service xfs_scrub_all.timer xfs_scrub_fail@.service
+SYSTEMD_SERVICES = $(scrub_svcname) xfs_scrub_all.service xfs_scrub_all.timer xfs_scrub_fail@.service
OPTIONAL_TARGETS += $(SYSTEMD_SERVICES)
endif
ifeq ($(HAVE_CROND),yes)
@@ -23,7 +26,7 @@ INSTALL_SCRUB += install-crond
CRONTABS = xfs_scrub_all.cron
OPTIONAL_TARGETS += $(CRONTABS)
# Don't enable the crontab by default for now
-CROND_DIR = $(PKG_LIB_SCRIPT_DIR)/$(PKG_NAME)
+CROND_DIR = $(PKG_DATA_DIR)
endif
endif # scrub_prereqs
@@ -107,17 +110,25 @@ ifeq ($(HAVE_HDIO_GETGEO),yes)
LCFLAGS += -DHAVE_HDIO_GETGEO
endif
-LDIRT = $(XFS_SCRUB_ALL_PROG) *.service *.cron
+LDIRT = $(XFS_SCRUB_ALL_PROG) $(XFS_SCRUB_FAIL_PROG) *.service *.cron
-default: depend $(LTCOMMAND) $(XFS_SCRUB_ALL_PROG) $(OPTIONAL_TARGETS)
+default: depend $(LTCOMMAND) $(XFS_SCRUB_ALL_PROG) $(XFS_SCRUB_FAIL_PROG) $(OPTIONAL_TARGETS)
xfs_scrub_all: xfs_scrub_all.in $(builddefs)
@echo " [SED] $@"
$(Q)$(SED) -e "s|@sbindir@|$(PKG_SBIN_DIR)|g" \
+ -e "s|@scrub_svcname@|$(scrub_svcname)|g" \
-e "s|@pkg_version@|$(PKG_VERSION)|g" \
-e "s|@scrub_args@|$(XFS_SCRUB_ARGS)|g" < $< > $@
$(Q)chmod a+x $@
+xfs_scrub_fail: xfs_scrub_fail.in $(builddefs)
+ @echo " [SED] $@"
+ $(Q)$(SED) -e "s|@sbindir@|$(PKG_SBIN_DIR)|g" \
+ -e "s|@scrub_svcname@|$(scrub_svcname)|g" \
+ -e "s|@pkg_version@|$(PKG_VERSION)|g" < $< > $@
+ $(Q)chmod a+x $@
+
phase5.o unicrash.o xfs.o: $(builddefs)
include $(BUILDRULES)
@@ -128,8 +139,7 @@ install: $(INSTALL_SCRUB)
@echo " [SED] $@"
$(Q)$(SED) -e "s|@sbindir@|$(PKG_SBIN_DIR)|g" \
-e "s|@scrub_args@|$(XFS_SCRUB_ARGS)|g" \
- -e "s|@pkg_lib_dir@|$(PKG_LIB_SCRIPT_DIR)|g" \
- -e "s|@pkg_name@|$(PKG_NAME)|g" \
+ -e "s|@pkg_libexec_dir@|$(PKG_LIBEXEC_DIR)|g" \
< $< > $@
%.cron: %.cron.in $(builddefs)
@@ -139,8 +149,8 @@ install: $(INSTALL_SCRUB)
install-systemd: default $(SYSTEMD_SERVICES)
$(INSTALL) -m 755 -d $(SYSTEMD_SYSTEM_UNIT_DIR)
$(INSTALL) -m 644 $(SYSTEMD_SERVICES) $(SYSTEMD_SYSTEM_UNIT_DIR)
- $(INSTALL) -m 755 -d $(PKG_LIB_SCRIPT_DIR)/$(PKG_NAME)
- $(INSTALL) -m 755 xfs_scrub_fail $(PKG_LIB_SCRIPT_DIR)/$(PKG_NAME)
+ $(INSTALL) -m 755 -d $(PKG_LIBEXEC_DIR)
+ $(INSTALL) -m 755 $(XFS_SCRUB_FAIL_PROG) $(PKG_LIBEXEC_DIR)
install-crond: default $(CRONTABS)
$(INSTALL) -m 755 -d $(CROND_DIR)
diff --git a/scrub/xfs_scrub@.service.in b/scrub/xfs_scrub@.service.in
index b90107bdcb..05e5293ee1 100644
--- a/scrub/xfs_scrub@.service.in
+++ b/scrub/xfs_scrub@.service.in
@@ -4,7 +4,7 @@
# Author: Darrick J. Wong <djwong@kernel.org>
[Unit]
-Description=Online XFS Metadata Check for %I
+Description=Online XFS Metadata Check for %f
OnFailure=xfs_scrub_fail@%i.service
Documentation=man:xfs_scrub(8)
@@ -13,7 +13,7 @@ Type=oneshot
PrivateNetwork=true
ProtectSystem=full
ProtectHome=read-only
-# Disable private /tmp just in case %i is a path under /tmp.
+# Disable private /tmp just in case %f is a path under /tmp.
PrivateTmp=no
AmbientCapabilities=CAP_SYS_ADMIN CAP_FOWNER CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_SYS_RAWIO
NoNewPrivileges=yes
@@ -21,5 +21,5 @@ User=nobody
IOSchedulingClass=idle
CPUSchedulingPolicy=idle
Environment=SERVICE_MODE=1
-ExecStart=@sbindir@/xfs_scrub @scrub_args@ %I
+ExecStart=@sbindir@/xfs_scrub @scrub_args@ %f
SyslogIdentifier=%N
diff --git a/scrub/xfs_scrub_all.in b/scrub/xfs_scrub_all.in
index 5042321a73..d7d36e1bdb 100644
--- a/scrub/xfs_scrub_all.in
+++ b/scrub/xfs_scrub_all.in
@@ -81,31 +81,20 @@ def run_killable(cmd, stdout, killfuncs, kill_fn):
return -1
# systemd doesn't like unit instance names with slashes in them, so it
-# replaces them with dashes when it invokes the service. However, it's not
-# smart enough to convert the dashes to something else, so when it unescapes
-# the instance name to feed to xfs_scrub, it turns all dashes into slashes.
-# "/moo-cow" becomes "-moo-cow" becomes "/moo/cow", which is wrong. systemd
-# actually /can/ escape the dashes correctly if it is told that this is a path
-# (and not a unit name), but it didn't do this prior to January 2017, so fix
-# this for them.
-#
-# 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.
-def systemd_escape(path):
- '''Escape a path to avoid mangled systemd mangling.'''
-
- if path == '/':
- return '-'
- cmd = ['systemd-escape', '--path', path]
+# replaces them with dashes when it invokes the service. Filesystem paths
+# need a special --path argument so that dashes do not get mangled.
+def path_to_serviceunit(path):
+ '''Convert a pathname into a systemd service unit name.'''
+
+ cmd = ['systemd-escape', '--template', '@scrub_svcname@',
+ '--path', path]
try:
proc = subprocess.Popen(cmd, stdout = subprocess.PIPE)
proc.wait()
for line in proc.stdout:
- return '-' + line.decode(sys.stdout.encoding).strip()
+ return line.decode(sys.stdout.encoding).strip()
except:
- return path
+ return None
def run_scrub(mnt, cond, running_devs, mntdevs, killfuncs):
'''Run a scrub process.'''
@@ -119,17 +108,19 @@ def run_scrub(mnt, cond, running_devs, mntdevs, killfuncs):
return
# Try it the systemd way
- cmd=['systemctl', 'start', 'xfs_scrub@%s' % systemd_escape(mnt)]
- ret = run_killable(cmd, DEVNULL(), killfuncs, \
- lambda proc: kill_systemd('xfs_scrub@%s' % mnt, proc))
- if ret == 0 or ret == 1:
- print("Scrubbing %s done, (err=%d)" % (mnt, ret))
- sys.stdout.flush()
- retcode |= ret
- return
-
- if terminate:
- return
+ unitname = path_to_serviceunit(path)
+ if unitname is not None:
+ cmd=['systemctl', 'start', unitname]
+ ret = run_killable(cmd, DEVNULL(), killfuncs, \
+ lambda proc: kill_systemd(unitname, proc))
+ if ret == 0 or ret == 1:
+ print("Scrubbing %s done, (err=%d)" % (mnt, ret))
+ sys.stdout.flush()
+ retcode |= ret
+ return
+
+ if terminate:
+ return
# Invoke xfs_scrub manually
cmd=['@sbindir@/xfs_scrub', '@scrub_args@', mnt]
diff --git a/scrub/xfs_scrub_fail b/scrub/xfs_scrub_fail.in
index 4f3f11d43f..9437b0327e 100755
--- a/scrub/xfs_scrub_fail
+++ b/scrub/xfs_scrub_fail.in
@@ -7,25 +7,33 @@
# Email logs of failed xfs_scrub unit runs
-mailer=/usr/sbin/sendmail
recipient="$1"
test -z "${recipient}" && exit 0
mntpoint="$2"
test -z "${mntpoint}" && exit 0
hostname="$(hostname -f 2>/dev/null)"
test -z "${hostname}" && hostname="${HOSTNAME}"
+
+mailer="$(command -v sendmail)"
if [ ! -x "${mailer}" ]; then
echo "${mailer}: Mailer program not found."
exit 1
fi
+# Turn the mountpoint into a properly escaped systemd instance name
+scrub_svc="$(systemd-escape --template "@scrub_svcname@" --path "${mntpoint}")"
+
(cat << ENDL
To: $1
From: <xfs_scrub@${hostname}>
Subject: xfs_scrub failure on ${mntpoint}
+Content-Transfer-Encoding: 8bit
+Content-Type: text/plain; charset=UTF-8
So sorry, the automatic xfs_scrub of ${mntpoint} on ${hostname} failed.
+Please do not reply to this mesage.
A log of what happened follows:
ENDL
-systemctl status --full --lines 4294967295 "xfs_scrub@${mntpoint}") | "${mailer}" -t -i
+systemctl status --full --lines 4294967295 "${scrub_svc}") | "${mailer}" -t -i
+exit "${PIPESTATUS[1]}"
diff --git a/scrub/xfs_scrub_fail@.service.in b/scrub/xfs_scrub_fail@.service.in
index 489a946732..96a2ed5da3 100644
--- a/scrub/xfs_scrub_fail@.service.in
+++ b/scrub/xfs_scrub_fail@.service.in
@@ -4,13 +4,13 @@
# Author: Darrick J. Wong <djwong@kernel.org>
[Unit]
-Description=Online XFS Metadata Check Failure Reporting for %I
+Description=Online XFS Metadata Check Failure Reporting for %f
Documentation=man:xfs_scrub(8)
[Service]
Type=oneshot
Environment=EMAIL_ADDR=root
-ExecStart=@pkg_lib_dir@/@pkg_name@/xfs_scrub_fail "${EMAIL_ADDR}" %I
+ExecStart=@pkg_libexec_dir@/xfs_scrub_fail "${EMAIL_ADDR}" %f
User=mail
Group=mail
SupplementaryGroups=systemd-journal