diff mbox series

xfs_scrub_all: fail fast on masked units

Message ID 20240724045241.GW612460@frogsfrogsfrogs (mailing list archive)
State Superseded, archived
Headers show
Series xfs_scrub_all: fail fast on masked units | expand

Commit Message

Darrick J. Wong July 24, 2024, 4:52 a.m. UTC
From: Darrick J. Wong <djwong@kernel.org>

If xfs_scrub_all tries to start a masked xfs_scrub@ unit, that's a sign
that the system administrator really didn't want us to scrub that
filesystem.  Instead of retrying pointlessly, just make a note of the
failure and move on.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 scrub/xfs_scrub_all.in |   21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

Comments

Christoph Hellwig July 24, 2024, 1:16 p.m. UTC | #1
Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>

On Tue, Jul 23, 2024 at 09:52:41PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> If xfs_scrub_all tries to start a masked xfs_scrub@ unit, that's a sign
> that the system administrator really didn't want us to scrub that
> filesystem.  Instead of retrying pointlessly, just make a note of the
> failure and move on.
> 
> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> ---
>  scrub/xfs_scrub_all.in |   21 +++++++++++++++++++++
>  1 file changed, 21 insertions(+)
> 
> diff --git a/scrub/xfs_scrub_all.in b/scrub/xfs_scrub_all.in
> index 5440e51c0791..5e2e0446a99f 100644
> --- a/scrub/xfs_scrub_all.in
> +++ b/scrub/xfs_scrub_all.in
> @@ -181,6 +181,10 @@ def fibonacci(max_ret):
>  		y = z
>  		z = x + y
>  
> +def was_unit_masked(ex):
> +	'''Decide if this dbus exception occurred because we tried to start a masked unit.'''
> +	return ex.get_dbus_name() == "org.freedesktop.systemd1.UnitMasked"
> +
>  class scrub_service(scrub_control):
>  	'''Control object for xfs_scrub systemd service.'''
>  	def __init__(self, mnt, scrub_media):
> @@ -219,6 +223,12 @@ class scrub_service(scrub_control):
>  				if debug:
>  					print(e)
>  				fatal_ex = e
> +
> +				# If the unit is masked, there's no point in
> +				# retrying any operations on it.
> +				if was_unit_masked(e):
> +					break
> +
>  				time.sleep(i)
>  				self.bind()
>  		raise fatal_ex
> @@ -270,6 +280,13 @@ class scrub_service(scrub_control):
>  		try:
>  			self.__dbusrun(lambda: self.unit.Start('replace'))
>  			return self.wait()
> +		except dbus.exceptions.DBusException as e:
> +			# If the unit was masked, the sysadmin doesn't want us
> +			# running it.  Pretend that we finished it.
> +			if was_unit_masked(e):
> +				return 32
> +			print(e, file = sys.stderr)
> +			return -1
>  		except Exception as e:
>  			print(e, file = sys.stderr)
>  			return -1
> @@ -317,6 +334,10 @@ def run_scrub(mnt, cond, running_devs, mntdevs, killfuncs):
>  		# are running as a systemd service.
>  		if 'SERVICE_MODE' in os.environ:
>  			ret = run_service(mnt, scrub_media, killfuncs)
> +			if ret == 32:
> +				print("Scrubbing %s disabled by administrator, (err=%d)" % (mnt, ret))
> +				sys.stdout.flush()
> +				return
>  			if ret == 0 or ret == 1:
>  				print("Scrubbing %s done, (err=%d)" % (mnt, ret))
>  				sys.stdout.flush()
---end quoted text---
diff mbox series

Patch

diff --git a/scrub/xfs_scrub_all.in b/scrub/xfs_scrub_all.in
index 5440e51c0791..5e2e0446a99f 100644
--- a/scrub/xfs_scrub_all.in
+++ b/scrub/xfs_scrub_all.in
@@ -181,6 +181,10 @@  def fibonacci(max_ret):
 		y = z
 		z = x + y
 
+def was_unit_masked(ex):
+	'''Decide if this dbus exception occurred because we tried to start a masked unit.'''
+	return ex.get_dbus_name() == "org.freedesktop.systemd1.UnitMasked"
+
 class scrub_service(scrub_control):
 	'''Control object for xfs_scrub systemd service.'''
 	def __init__(self, mnt, scrub_media):
@@ -219,6 +223,12 @@  class scrub_service(scrub_control):
 				if debug:
 					print(e)
 				fatal_ex = e
+
+				# If the unit is masked, there's no point in
+				# retrying any operations on it.
+				if was_unit_masked(e):
+					break
+
 				time.sleep(i)
 				self.bind()
 		raise fatal_ex
@@ -270,6 +280,13 @@  class scrub_service(scrub_control):
 		try:
 			self.__dbusrun(lambda: self.unit.Start('replace'))
 			return self.wait()
+		except dbus.exceptions.DBusException as e:
+			# If the unit was masked, the sysadmin doesn't want us
+			# running it.  Pretend that we finished it.
+			if was_unit_masked(e):
+				return 32
+			print(e, file = sys.stderr)
+			return -1
 		except Exception as e:
 			print(e, file = sys.stderr)
 			return -1
@@ -317,6 +334,10 @@  def run_scrub(mnt, cond, running_devs, mntdevs, killfuncs):
 		# are running as a systemd service.
 		if 'SERVICE_MODE' in os.environ:
 			ret = run_service(mnt, scrub_media, killfuncs)
+			if ret == 32:
+				print("Scrubbing %s disabled by administrator, (err=%d)" % (mnt, ret))
+				sys.stdout.flush()
+				return
 			if ret == 0 or ret == 1:
 				print("Scrubbing %s done, (err=%d)" % (mnt, ret))
 				sys.stdout.flush()