diff mbox series

[18/21] xfs_scrubbed: don't start service if kernel support unavailable

Message ID 173568778738.2710211.17502333103439617688.stgit@frogsfrogsfrogs (mailing list archive)
State New
Headers show
Series [01/21] xfs: create hooks for monitoring health updates | expand

Commit Message

Darrick J. Wong Dec. 31, 2024, 11:52 p.m. UTC
From: Darrick J. Wong <djwong@kernel.org>

Use ExecCondition= in the system service to check if kernel support for
the health monitor is available.  If not, we don't want to run the
service, have it fail, and generate a bunch of silly log messages.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
 scrub/xfs_scrubbed.in          |   39 ++++++++++++++++++++++++++++++++++++++-
 scrub/xfs_scrubbed@.service.in |    1 +
 2 files changed, 39 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/scrub/xfs_scrubbed.in b/scrub/xfs_scrubbed.in
index 9df6f45e53ad80..90602481f64c88 100644
--- a/scrub/xfs_scrubbed.in
+++ b/scrub/xfs_scrubbed.in
@@ -791,6 +791,38 @@  def monitor(mountpoint, event_queue, **kwargs):
 
 	return 0
 
+def check_monitor(mountpoint):
+	'''Check if the kernel can send us health events for the given mountpoint.'''
+	global log
+	global printf_prefix
+	global everything
+	global want_repair
+	global has_parent
+
+	try:
+		fd = os.open(mountpoint, os.O_RDONLY)
+	except OSError as e:
+		# Can't open mountpoint; monitor not available.
+		print(f"{mountpoint}: {e}", file = sys.stderr)
+		return 1
+
+	try:
+		mon_fd = open_health_monitor(fd, verbose = everything)
+	except OSError as e:
+		# Error opening monitor (or it's simply not there); monitor
+		# not available.
+		if e.errno == errno.ENOTTY or e.errno == errno.EOPNOTSUPP:
+			print(f"{mountpoint}: XFS health monitoring not supported.",
+					file = sys.stderr)
+		return 1
+	finally:
+		# Close the mountpoint if opening the health monitor fails;
+		# the handle object will free its own memory.
+		os.close(fd)
+
+	# Monitor available; success!
+	return 0
+
 def __scrub_type(code):
 	'''Convert a "structures" json list to a scrub type code.'''
 	SCRUB_TYPES = {
@@ -923,6 +955,8 @@  def main():
 
 	parser = argparse.ArgumentParser( \
 			description = "XFS filesystem health monitoring demon.")
+	parser.add_argument("--check", help = "Check presense of health monitor.", \
+			action = "store_true")
 	parser.add_argument("--debug", help = "Enabling debugging messages.", \
 			action = "store_true")
 	parser.add_argument("--log", help = "Log health events to stdout.", \
@@ -989,7 +1023,10 @@  def main():
 	printf_prefix = args.mountpoint
 	ret = 0
 	try:
-		ret = monitor(**vars(args))
+		if args.check:
+			ret = check_monitor(args.mountpoint)
+		else:
+			ret = monitor(**vars(args))
 	except KeyboardInterrupt:
 		# Consider SIGINT to be a clean exit.
 		pass
diff --git a/scrub/xfs_scrubbed@.service.in b/scrub/xfs_scrubbed@.service.in
index 9656bdb3cd9a9d..afd5c204327946 100644
--- a/scrub/xfs_scrubbed@.service.in
+++ b/scrub/xfs_scrubbed@.service.in
@@ -18,6 +18,7 @@  RequiresMountsFor=%f
 [Service]
 Type=exec
 Environment=SERVICE_MODE=1
+ExecCondition=@pkg_libexec_dir@/xfs_scrubbed --check %f
 ExecStart=@pkg_libexec_dir@/xfs_scrubbed --log %f
 SyslogIdentifier=%N