From patchwork Tue Jul 2 01:06:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13718803 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E471A8479 for ; Tue, 2 Jul 2024 01:06:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719882392; cv=none; b=dexWZ4Zjz9c3pDBNnyyia9MXgdJrYDUqGhN/Fdvv/2p7++xPvJweDwIyayzfRIg+/HVC5FJhmE5GhKaSEwIr7Q7mg08Ie+AS7cWyQoaWRVOOYczAez+hjqMmeoVFEuEccn1J2J6gNjCnqF4sLPopIffj+nzZdoR+SlrrOM7iO3o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719882392; c=relaxed/simple; bh=c4Dpv6Xmpw2savvClgcUf2oFyT7M0yRBvu/RApaefGs=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=FNmOuwPenEgj1W9xb+1gQJ1m7K00HucMmFyq7nBtBym5Ayaup16iU8mQoQdsV97hnMMe6PTlEgy1s6gtj+LApSpV2aLgeztsPCI5K53CYttiT8adDl17yhK47sbVxdobgcn6uJ28heCoB/U9oxnMmPVuxXA+XQ00UE0NewtGpaI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=g68LvcHo; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="g68LvcHo" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B8381C116B1; Tue, 2 Jul 2024 01:06:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1719882391; bh=c4Dpv6Xmpw2savvClgcUf2oFyT7M0yRBvu/RApaefGs=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=g68LvcHoqBwM+q3dxnEDcge64wfOaiqmOkdQ91FHuw2B2YRNgpEZ4pzSNYk3Udnyt 3XsNWeo+TEmDyxeSyCAWMB2mvMI5eTDvm+6c/e8k8PWjFgLzVwrXOqkDp20hmhr5fn UZdzWEkq7V739CQJNZKChhFecFPLwKbaIpO8cDzX4AQk0Ma1W1808Of5mlzMTYuRHE vreChtShsJutR8OFP4Z++00Mer79KA4QO+aQhNfB4rEl1Q3VMJ9r76zp0LLOe4oHd2 kknLnEfi0MbMSzFSXYw7W4Pmr7RGPqq/2gwa8b3X89ezZWnQlHoBYCsrEhyd5j5kuF DvVzrVWJ7gZGA== Date: Mon, 01 Jul 2024 18:06:31 -0700 Subject: [PATCH 1/6] xfs_scrub_all: only use the xfs_scrub@ systemd services in service mode From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org, hch@lst.de Message-ID: <171988119423.2008463.11698354867151927273.stgit@frogsfrogsfrogs> In-Reply-To: <171988119402.2008463.10432604765226555660.stgit@frogsfrogsfrogs> References: <171988119402.2008463.10432604765226555660.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Since the per-mount xfs_scrub@.service definition includes a bunch of resource usage constraints, we no longer want to use those services if xfs_scrub_all is being run directly by the sysadmin (aka not in service mode) on the presumption that sysadmins want answers as quickly as possible. Therefore, only try to call the systemd service from xfs_scrub_all if SERVICE_MODE is set in the environment. If reaching out to systemd fails and we're in service mode, we still want to run xfs_scrub directly. Split the makefile variables as necessary so that we only pass -b to xfs_scrub in service mode. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- scrub/Makefile | 5 ++++- scrub/xfs_scrub@.service.in | 2 +- scrub/xfs_scrub_all.in | 11 ++++++++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/scrub/Makefile b/scrub/Makefile index 2a257e0805cd..2050fe28fc75 100644 --- a/scrub/Makefile +++ b/scrub/Makefile @@ -15,7 +15,8 @@ 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 +XFS_SCRUB_ARGS = -n +XFS_SCRUB_SERVICE_ARGS = -b ifeq ($(HAVE_SYSTEMD),yes) INSTALL_SCRUB += install-systemd SYSTEMD_SERVICES=\ @@ -113,6 +114,7 @@ xfs_scrub_all: xfs_scrub_all.in $(builddefs) $(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_service_args@|$(XFS_SCRUB_SERVICE_ARGS)|g" \ -e "s|@scrub_args@|$(XFS_SCRUB_ARGS)|g" < $< > $@ $(Q)chmod a+x $@ @@ -132,6 +134,7 @@ install: $(INSTALL_SCRUB) %.service: %.service.in $(builddefs) @echo " [SED] $@" $(Q)$(SED) -e "s|@sbindir@|$(PKG_SBIN_DIR)|g" \ + -e "s|@scrub_service_args@|$(XFS_SCRUB_SERVICE_ARGS)|g" \ -e "s|@scrub_args@|$(XFS_SCRUB_ARGS)|g" \ -e "s|@pkg_libexec_dir@|$(PKG_LIBEXEC_DIR)|g" \ < $< > $@ diff --git a/scrub/xfs_scrub@.service.in b/scrub/xfs_scrub@.service.in index a8dd9052f0e0..5fa5f328200e 100644 --- a/scrub/xfs_scrub@.service.in +++ b/scrub/xfs_scrub@.service.in @@ -22,7 +22,7 @@ RequiresMountsFor=%f [Service] Type=oneshot Environment=SERVICE_MODE=1 -ExecStart=@sbindir@/xfs_scrub @scrub_args@ -M /tmp/scrub/ %f +ExecStart=@sbindir@/xfs_scrub @scrub_service_args@ @scrub_args@ -M /tmp/scrub/ %f SyslogIdentifier=%N # Run scrub with minimal CPU and IO priority so that nothing else will starve. diff --git a/scrub/xfs_scrub_all.in b/scrub/xfs_scrub_all.in index d0ab27fd3060..f27251fa5439 100644 --- a/scrub/xfs_scrub_all.in +++ b/scrub/xfs_scrub_all.in @@ -162,9 +162,10 @@ def run_scrub(mnt, cond, running_devs, mntdevs, killfuncs): if terminate: return - # Try it the systemd way + # Run per-mount systemd xfs_scrub service only if we ourselves + # are running as a systemd service. unitname = path_to_serviceunit(path) - if unitname is not None: + if unitname is not None and 'SERVICE_MODE' in os.environ: ret = systemctl_start(unitname, killfuncs) if ret == 0 or ret == 1: print("Scrubbing %s done, (err=%d)" % (mnt, ret)) @@ -175,8 +176,12 @@ def run_scrub(mnt, cond, running_devs, mntdevs, killfuncs): if terminate: return - # Invoke xfs_scrub manually + # Invoke xfs_scrub manually if we're running in the foreground. + # We also permit this if we're running as a cronjob where + # systemd services are unavailable. cmd = ['@sbindir@/xfs_scrub'] + if 'SERVICE_MODE' in os.environ: + cmd += '@scrub_service_args@'.split() cmd += '@scrub_args@'.split() cmd += [mnt] ret = run_killable(cmd, None, killfuncs) From patchwork Tue Jul 2 01:06:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13718804 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DDA348BE2 for ; Tue, 2 Jul 2024 01:06:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719882407; cv=none; b=BjbcqFbzEZrZvDyh9y76C1quuMlUB4R8MxPxu0G/0tF2kydYAib+PC14s4qOHxdsNO4jjYjoKQ+QOdgMeQ5lWUa2EYOnX6YlLhKSgAeJchk7M5YCdPQSjmwVVEyI6PzHExeER+FdpFF+zWOqhm61/FQ8TtbzUTN5cD2wtz9tl1A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719882407; c=relaxed/simple; bh=t0UlHfzSDydRduZ5/ttHdy21TLtLG984/0bJiDQH/rE=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=LqRqp2epopqa8yoOuUz/i9lWwWV1AEddxfiwFlpeAO+u9ZmRc+wKXAawUw+cQvVj8rMNL8s8RUfgLeIv3CMw7e6oXDpCEgbl91ZCezPPzvrtvoBtIU1xywsanN60CCIMX+xM2GAOhx5OvRGzNsGU8uINXDQmlDmjGfZaBphFM6k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=okcKbf48; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="okcKbf48" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5C67AC116B1; Tue, 2 Jul 2024 01:06:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1719882407; bh=t0UlHfzSDydRduZ5/ttHdy21TLtLG984/0bJiDQH/rE=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=okcKbf48sUJIUrmh1+r5MEhNA3XLqp2PrkO7nz0ksEznJkmvZGGOU0LrXOByNX/W4 QrQkHSkg0GLiYxisCR2sm9sNCCUqGYjfDTJBSJBRZbEehCJ+2uLsB9SnFf0aZdERq9 VnjfTwizn0edpBl1Zv1mrMToJPVna3C9O53lo0mhCty/X4ft3fHCwxiMJBua/Oyryc nWELPiaPjDTp/QcSc8s0Hxhd61SO/LWQd0D8eh8aKxzRcyA9FsLQ/zE2PIDqHTmHpr 6Ti7G2zfs4i1xN7bC2qXmvml0ciXfB4/soKOgDtpmys8W3o71XnP8kd2S5184dIa2h mVo7fGr0TtTZQ== Date: Mon, 01 Jul 2024 18:06:46 -0700 Subject: [PATCH 2/6] xfs_scrub_all: remove journalctl background process From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org, hch@lst.de Message-ID: <171988119439.2008463.11717166273939123673.stgit@frogsfrogsfrogs> In-Reply-To: <171988119402.2008463.10432604765226555660.stgit@frogsfrogsfrogs> References: <171988119402.2008463.10432604765226555660.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Now that we only start systemd services if we're running in service mode, there's no need for the background journalctl process that only ran if we had started systemd services in non-service mode. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- scrub/xfs_scrub_all.in | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/scrub/xfs_scrub_all.in b/scrub/xfs_scrub_all.in index f27251fa5439..fc7a2e637efa 100644 --- a/scrub/xfs_scrub_all.in +++ b/scrub/xfs_scrub_all.in @@ -261,17 +261,6 @@ def main(): fs = find_mounts() - # Tail the journal if we ourselves aren't a service... - journalthread = None - if 'SERVICE_MODE' not in os.environ: - try: - cmd=['journalctl', '--no-pager', '-q', '-S', 'now', \ - '-f', '-u', 'xfs_scrub@*', '-o', \ - 'cat'] - journalthread = subprocess.Popen(cmd) - except: - pass - # Schedule scrub jobs... running_devs = set() killfuncs = set() @@ -308,9 +297,6 @@ def main(): while len(killfuncs) > 0: wait_for_termination(cond, killfuncs) - if journalthread is not None: - journalthread.terminate() - # See the service mode comments in xfs_scrub.c for why we do this. if 'SERVICE_MODE' in os.environ: time.sleep(2) From patchwork Tue Jul 2 01:07:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13718810 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 27D728F44 for ; Tue, 2 Jul 2024 01:07:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719882423; cv=none; b=QvF9F9nXNsJtvoWSxKi6/S7knbVZRe7mN2B62M55QfbPAWKQfwFdNo7hAmjNAutpuKCODC1JoII4ed185JJ1zyJ93iNiTX8uO9FbC+MjL+SmO+y6tdabR4NAZpmC5PZCW1Bc+Q7fYREU6eQ2XBQcGey9P1B3YHhw/UeJvhUnLLY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719882423; c=relaxed/simple; bh=6f0+yJ9NVI0vgGQmS7bCiNmjnYKo1O5swES9sMshVLI=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=DLZzetdruyUIV+65Wpi499QfT0IFUaiPWlyECHY/AhXFO0k+OQoDEQWxV7k8l3FtVBS0dLvhYJtzho+RNkPQt2bdHRVoc2iu/VzcvB18wF3CuGAHlPmb6m4jrtJUWo3oL5AxW2YlNVFc/qehLsUJ1ebUrnrx9Bst10wffymuYMQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PdmuZy2q; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="PdmuZy2q" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EEAA6C116B1; Tue, 2 Jul 2024 01:07:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1719882423; bh=6f0+yJ9NVI0vgGQmS7bCiNmjnYKo1O5swES9sMshVLI=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=PdmuZy2qQ9/TMc6aa0gpGWjRfGmtN+nexkJCgw10H/ew3LofW6JodF8xTyQfVlURu hQ5bW3KHyIOb/xNsO7eFyz/iS/ChoxjEFY/EEMAjXR3LFpi4nkwYVfY0gwhTmFYAGc AQ0yKbTvA5vVRbDlevrCO28EMuMcGlAS3L+TJ7/QT0o0G5DpZi5pzQ3vDLv3YtHah3 W3p9Fu0NQkZ3AlppjDRAG5bRCBjDtPYKszMeDrlWjydWzVD0IRre3A5KWpfdMm8Dxr 700vVzG07IO4x//W9i7TUGRsJy0AGpKzmAKblDwuu/2OV8GcFy7FbQLVT4vbrbwY7s R/FSpuxtJT/Bg== Date: Mon, 01 Jul 2024 18:07:02 -0700 Subject: [PATCH 3/6] xfs_scrub_all: support metadata+media scans of all filesystems From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org, hch@lst.de Message-ID: <171988119454.2008463.33463397057054094.stgit@frogsfrogsfrogs> In-Reply-To: <171988119402.2008463.10432604765226555660.stgit@frogsfrogsfrogs> References: <171988119402.2008463.10432604765226555660.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Add the necessary systemd services and control bits so that xfs_scrub_all can kick off a metadata+media scan of a filesystem. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- man/man8/xfs_scrub_all.8 | 5 +- scrub/Makefile | 4 + scrub/xfs_scrub_all.in | 23 +++++-- scrub/xfs_scrub_fail.in | 13 +++- scrub/xfs_scrub_fail@.service.in | 2 - scrub/xfs_scrub_media@.service.in | 100 ++++++++++++++++++++++++++++++++ scrub/xfs_scrub_media_fail@.service.in | 76 ++++++++++++++++++++++++ 7 files changed, 210 insertions(+), 13 deletions(-) create mode 100644 scrub/xfs_scrub_media@.service.in create mode 100644 scrub/xfs_scrub_media_fail@.service.in diff --git a/man/man8/xfs_scrub_all.8 b/man/man8/xfs_scrub_all.8 index 74548802eda0..86a9b3eced28 100644 --- a/man/man8/xfs_scrub_all.8 +++ b/man/man8/xfs_scrub_all.8 @@ -4,7 +4,7 @@ xfs_scrub_all \- scrub all mounted XFS filesystems .SH SYNOPSIS .B xfs_scrub_all [ -.B \-hV +.B \-hxV ] .SH DESCRIPTION .B xfs_scrub_all @@ -21,6 +21,9 @@ the same device simultaneously. .B \-h Display help. .TP +.B \-x +Read all file data extents to look for disk errors. +.TP .B \-V Prints the version number and exits. .SH EXIT CODE diff --git a/scrub/Makefile b/scrub/Makefile index 2050fe28fc75..5567ec061e82 100644 --- a/scrub/Makefile +++ b/scrub/Makefile @@ -9,6 +9,7 @@ include $(builddefs) SCRUB_PREREQS=$(HAVE_GETFSMAP) scrub_svcname=xfs_scrub@.service +scrub_media_svcname=xfs_scrub_media@.service ifeq ($(SCRUB_PREREQS),yes) LTCOMMAND = xfs_scrub @@ -22,6 +23,8 @@ INSTALL_SCRUB += install-systemd SYSTEMD_SERVICES=\ $(scrub_svcname) \ xfs_scrub_fail@.service \ + $(scrub_media_svcname) \ + xfs_scrub_media_fail@.service \ xfs_scrub_all.service \ xfs_scrub_all.timer \ system-xfs_scrub.slice @@ -113,6 +116,7 @@ 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|@scrub_media_svcname@|$(scrub_media_svcname)|g" \ -e "s|@pkg_version@|$(PKG_VERSION)|g" \ -e "s|@scrub_service_args@|$(XFS_SCRUB_SERVICE_ARGS)|g" \ -e "s|@scrub_args@|$(XFS_SCRUB_ARGS)|g" < $< > $@ diff --git a/scrub/xfs_scrub_all.in b/scrub/xfs_scrub_all.in index fc7a2e637efa..afba0dbe8912 100644 --- a/scrub/xfs_scrub_all.in +++ b/scrub/xfs_scrub_all.in @@ -19,6 +19,7 @@ from io import TextIOWrapper retcode = 0 terminate = False +scrub_media = False def DEVNULL(): '''Return /dev/null in subprocess writable format.''' @@ -88,11 +89,15 @@ def run_killable(cmd, stdout, killfuncs): # systemd doesn't like unit instance names with slashes in them, so it # 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): +def path_to_serviceunit(path, scrub_media): '''Convert a pathname into a systemd service unit name.''' - cmd = ['systemd-escape', '--template', '@scrub_svcname@', - '--path', path] + if scrub_media: + svcname = '@scrub_media_svcname@' + else: + svcname = '@scrub_svcname@' + cmd = ['systemd-escape', '--template', svcname, '--path', path] + try: proc = subprocess.Popen(cmd, stdout = subprocess.PIPE) proc.wait() @@ -153,7 +158,7 @@ def systemctl_start(unitname, killfuncs): def run_scrub(mnt, cond, running_devs, mntdevs, killfuncs): '''Run a scrub process.''' - global retcode, terminate + global retcode, terminate, scrub_media print("Scrubbing %s..." % mnt) sys.stdout.flush() @@ -164,7 +169,7 @@ def run_scrub(mnt, cond, running_devs, mntdevs, killfuncs): # Run per-mount systemd xfs_scrub service only if we ourselves # are running as a systemd service. - unitname = path_to_serviceunit(path) + unitname = path_to_serviceunit(path, scrub_media) if unitname is not None and 'SERVICE_MODE' in os.environ: ret = systemctl_start(unitname, killfuncs) if ret == 0 or ret == 1: @@ -183,6 +188,8 @@ def run_scrub(mnt, cond, running_devs, mntdevs, killfuncs): if 'SERVICE_MODE' in os.environ: cmd += '@scrub_service_args@'.split() cmd += '@scrub_args@'.split() + if scrub_media: + cmd += '-x' cmd += [mnt] ret = run_killable(cmd, None, killfuncs) if ret >= 0: @@ -247,18 +254,22 @@ def main(): a = (mnt, cond, running_devs, devs, killfuncs) thr = threading.Thread(target = run_scrub, args = a) thr.start() - global retcode, terminate + global retcode, terminate, scrub_media parser = argparse.ArgumentParser( \ description = "Scrub all mounted XFS filesystems.") parser.add_argument("-V", help = "Report version and exit.", \ action = "store_true") + parser.add_argument("-x", help = "Scrub file data after filesystem metadata.", \ + action = "store_true") args = parser.parse_args() if args.V: print("xfs_scrub_all version @pkg_version@") sys.exit(0) + scrub_media = args.x + fs = find_mounts() # Schedule scrub jobs... diff --git a/scrub/xfs_scrub_fail.in b/scrub/xfs_scrub_fail.in index 9437b0327e7c..e420917f699f 100755 --- a/scrub/xfs_scrub_fail.in +++ b/scrub/xfs_scrub_fail.in @@ -9,8 +9,11 @@ recipient="$1" test -z "${recipient}" && exit 0 -mntpoint="$2" +service="$2" +test -z "${service}" && exit 0 +mntpoint="$3" test -z "${mntpoint}" && exit 0 + hostname="$(hostname -f 2>/dev/null)" test -z "${hostname}" && hostname="${HOSTNAME}" @@ -21,16 +24,16 @@ if [ ! -x "${mailer}" ]; then fi # Turn the mountpoint into a properly escaped systemd instance name -scrub_svc="$(systemd-escape --template "@scrub_svcname@" --path "${mntpoint}")" +scrub_svc="$(systemd-escape --template "${service}@.service" --path "${mntpoint}")" (cat << ENDL To: $1 -From: -Subject: xfs_scrub failure on ${mntpoint} +From: <${service}@${hostname}> +Subject: ${service} 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. +So sorry, the automatic ${service} of ${mntpoint} on ${hostname} failed. Please do not reply to this mesage. A log of what happened follows: diff --git a/scrub/xfs_scrub_fail@.service.in b/scrub/xfs_scrub_fail@.service.in index 2c879afd6d8e..16077888df33 100644 --- a/scrub/xfs_scrub_fail@.service.in +++ b/scrub/xfs_scrub_fail@.service.in @@ -10,7 +10,7 @@ Documentation=man:xfs_scrub(8) [Service] Type=oneshot Environment=EMAIL_ADDR=root -ExecStart=@pkg_libexec_dir@/xfs_scrub_fail "${EMAIL_ADDR}" %f +ExecStart=@pkg_libexec_dir@/xfs_scrub_fail "${EMAIL_ADDR}" xfs_scrub %f User=mail Group=mail SupplementaryGroups=systemd-journal diff --git a/scrub/xfs_scrub_media@.service.in b/scrub/xfs_scrub_media@.service.in new file mode 100644 index 000000000000..e670748ced51 --- /dev/null +++ b/scrub/xfs_scrub_media@.service.in @@ -0,0 +1,100 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2018-2024 Oracle. All Rights Reserved. +# Author: Darrick J. Wong + +[Unit] +Description=Online XFS Metadata and Media Check for %f +OnFailure=xfs_scrub_media_fail@%i.service +Documentation=man:xfs_scrub(8) + +# Explicitly require the capabilities that this program needs +ConditionCapability=CAP_SYS_ADMIN +ConditionCapability=CAP_FOWNER +ConditionCapability=CAP_DAC_OVERRIDE +ConditionCapability=CAP_DAC_READ_SEARCH +ConditionCapability=CAP_SYS_RAWIO + +# Must be a mountpoint +ConditionPathIsMountPoint=%f +RequiresMountsFor=%f + +[Service] +Type=oneshot +Environment=SERVICE_MODE=1 +ExecStart=@sbindir@/xfs_scrub @scrub_service_args@ @scrub_args@ -M /tmp/scrub/ -x %f +SyslogIdentifier=%N + +# Run scrub with minimal CPU and IO priority so that nothing else will starve. +IOSchedulingClass=idle +CPUSchedulingPolicy=idle +CPUAccounting=true +Nice=19 + +# Create the service underneath the scrub background service slice so that we +# can control resource usage. +Slice=system-xfs_scrub.slice + +# No realtime CPU scheduling +RestrictRealtime=true + +# Dynamically create a user that isn't root +DynamicUser=true + +# Make the entire filesystem readonly and /home inaccessible, then bind mount +# the filesystem we're supposed to be checking into our private /tmp dir. +# 'norbind' means that we don't bind anything under that original mount. +ProtectSystem=strict +ProtectHome=yes +PrivateTmp=true +BindPaths=%f:/tmp/scrub:norbind + +# Don't let scrub complain about paths in /etc/projects that have been hidden +# by our sandboxing. scrub doesn't care about project ids anyway. +InaccessiblePaths=-/etc/projects + +# No network access +PrivateNetwork=true +ProtectHostname=true +RestrictAddressFamilies=none +IPAddressDeny=any + +# Don't let the program mess with the kernel configuration at all +ProtectKernelLogs=true +ProtectKernelModules=true +ProtectKernelTunables=true +ProtectControlGroups=true +ProtectProc=invisible +RestrictNamespaces=true + +# Hide everything in /proc, even /proc/mounts +ProcSubset=pid + +# Only allow the default personality Linux +LockPersonality=true + +# No writable memory pages +MemoryDenyWriteExecute=true + +# Don't let our mounts leak out to the host +PrivateMounts=true + +# Restrict system calls to the native arch and only enough to get things going +SystemCallArchitectures=native +SystemCallFilter=@system-service +SystemCallFilter=~@privileged +SystemCallFilter=~@resources +SystemCallFilter=~@mount + +# xfs_scrub needs these privileges to run, and no others +CapabilityBoundingSet=CAP_SYS_ADMIN CAP_FOWNER CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_SYS_RAWIO +AmbientCapabilities=CAP_SYS_ADMIN CAP_FOWNER CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_SYS_RAWIO +NoNewPrivileges=true + +# xfs_scrub doesn't create files +UMask=7777 + +# No access to hardware /dev files except for block devices +ProtectClock=true +DevicePolicy=closed +DeviceAllow=block-* diff --git a/scrub/xfs_scrub_media_fail@.service.in b/scrub/xfs_scrub_media_fail@.service.in new file mode 100644 index 000000000000..97c0e090721d --- /dev/null +++ b/scrub/xfs_scrub_media_fail@.service.in @@ -0,0 +1,76 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2018-2024 Oracle. All Rights Reserved. +# Author: Darrick J. Wong + +[Unit] +Description=Online XFS Metadata and Media Check Failure Reporting for %f +Documentation=man:xfs_scrub(8) + +[Service] +Type=oneshot +Environment=EMAIL_ADDR=root +ExecStart=@pkg_libexec_dir@/xfs_scrub_fail "${EMAIL_ADDR}" xfs_scrub_media %f +User=mail +Group=mail +SupplementaryGroups=systemd-journal + +# Create the service underneath the scrub background service slice so that we +# can control resource usage. +Slice=system-xfs_scrub.slice + +# No realtime scheduling +RestrictRealtime=true + +# Make the entire filesystem readonly and /home inaccessible, then bind mount +# the filesystem we're supposed to be checking into our private /tmp dir. +ProtectSystem=full +ProtectHome=yes +PrivateTmp=true +RestrictSUIDSGID=true + +# Emailing reports requires network access, but not the ability to change the +# hostname. +ProtectHostname=true + +# Don't let the program mess with the kernel configuration at all +ProtectKernelLogs=true +ProtectKernelModules=true +ProtectKernelTunables=true +ProtectControlGroups=true +ProtectProc=invisible +RestrictNamespaces=true + +# Can't hide /proc because journalctl needs it to find various pieces of log +# information +#ProcSubset=pid + +# Only allow the default personality Linux +LockPersonality=true + +# No writable memory pages +MemoryDenyWriteExecute=true + +# Don't let our mounts leak out to the host +PrivateMounts=true + +# Restrict system calls to the native arch and only enough to get things going +SystemCallArchitectures=native +SystemCallFilter=@system-service +SystemCallFilter=~@privileged +SystemCallFilter=~@resources +SystemCallFilter=~@mount + +# xfs_scrub needs these privileges to run, and no others +CapabilityBoundingSet= +NoNewPrivileges=true + +# Failure reporting shouldn't create world-readable files +UMask=0077 + +# Clean up any IPC objects when this unit stops +RemoveIPC=true + +# No access to hardware device files +PrivateDevices=true +ProtectClock=true From patchwork Tue Jul 2 01:07:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13718811 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0FA4A9449 for ; Tue, 2 Jul 2024 01:07:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719882439; cv=none; b=oIqyMPrMVyXzeyIpaBlE8bOphxqGmjM/+Y6M54QET8qe4rzcEU3j4XzotnT4nVCxgCtBDxyZ9H52ifqjkumet8n70JfsqrQLMFiaLN6B93BoR6I723OErpZBlBfL6Z/7SBIfPhJg3B4VEtQ0Ar5ynBomoi3ibdY969KCAIQwsgA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719882439; c=relaxed/simple; bh=Ak/et9pSioe89DtoOx7fnpo0qp3kUDzjNTvEGtJkHoM=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=CX0Ypij5BkAKZDP0cfU8i4I9GNekf6pUpBRL8VEd9gcjc/xHZEQIT1VwBOzDU5nb7VvDttrWkTn8jDeFB9A1iuIYYLs8cKzBi6bElGVGSSVuWI7oBbUUfItO5iuTHMO/lx+zqfLG0bxysmODBDc2y1dylexNS1l4CZ7JFARSlxY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FYDwsyNO; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="FYDwsyNO" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 893A7C116B1; Tue, 2 Jul 2024 01:07:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1719882438; bh=Ak/et9pSioe89DtoOx7fnpo0qp3kUDzjNTvEGtJkHoM=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=FYDwsyNOY47JXwga8pWWtbIX7/ksC0c7VioTYrdrRtxWtKaMCJ+qskKT/k7poYZPa 5WXw1M6EogXiLlHn0YfuUXQ2491JxN4QY+JX/UrhT3kTgJJv/l5Hq8hfwpNB5LpFz6 OQdH27qYy7EJixjAQ3iNA+y1KoNs8+GkIn4ItK1jmcjNk6Nozc9akwHHFp8L9gWqP/ SHJlzonamNp0ujh94nCPAT5vg3cotKIo0Na4fBCRmabSQcgpK6L9nrbQFmrDFvb2+W MwWsLlWGD+0M9iOSkQM4Lg0jtJdWi1eBJqOiW/yJIQS+B1Xc+k/bAP6jKY/OrN+mYc I8AS/hY/02tmQ== Date: Mon, 01 Jul 2024 18:07:18 -0700 Subject: [PATCH 4/6] xfs_scrub_all: enable periodic file data scrubs automatically From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org, hch@lst.de Message-ID: <171988119470.2008463.14610381676308637018.stgit@frogsfrogsfrogs> In-Reply-To: <171988119402.2008463.10432604765226555660.stgit@frogsfrogsfrogs> References: <171988119402.2008463.10432604765226555660.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Enhance xfs_scrub_all with the ability to initiate a file data scrub periodically. The user must specify the period, and they may optionally specify the path to a file that will record the last time the file data was scrubbed. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- debian/rules | 3 +- include/builddefs.in | 3 ++ man/man8/Makefile | 7 +++- man/man8/xfs_scrub_all.8.in | 15 ++++++++ scrub/Makefile | 3 ++ scrub/xfs_scrub_all.in | 76 +++++++++++++++++++++++++++++++++++++++- scrub/xfs_scrub_all.service.in | 6 ++- 7 files changed, 108 insertions(+), 5 deletions(-) rename man/man8/{xfs_scrub_all.8 => xfs_scrub_all.8.in} (63%) diff --git a/debian/rules b/debian/rules index 0db0ed8e7543..69a79fc67405 100755 --- a/debian/rules +++ b/debian/rules @@ -38,7 +38,8 @@ configure_options = \ --disable-ubsan \ --disable-addrsan \ --disable-threadsan \ - --enable-lto + --enable-lto \ + --localstatedir=/var options = export DEBUG=-DNDEBUG DISTRIBUTION=debian \ INSTALL_USER=root INSTALL_GROUP=root \ diff --git a/include/builddefs.in b/include/builddefs.in index 6ac36c149238..734bd95ecb0b 100644 --- a/include/builddefs.in +++ b/include/builddefs.in @@ -57,6 +57,9 @@ PKG_DOC_DIR = @datadir@/doc/@pkg_name@ PKG_LOCALE_DIR = @datadir@/locale PKG_DATA_DIR = @datadir@/@pkg_name@ MKFS_CFG_DIR = @datadir@/@pkg_name@/mkfs +PKG_STATE_DIR = @localstatedir@/lib/@pkg_name@ + +XFS_SCRUB_ALL_AUTO_MEDIA_SCAN_STAMP=$(PKG_STATE_DIR)/xfs_scrub_all_media.stamp CC = @cc@ BUILD_CC = @BUILD_CC@ diff --git a/man/man8/Makefile b/man/man8/Makefile index 272e45aebc20..5be76ab727a1 100644 --- a/man/man8/Makefile +++ b/man/man8/Makefile @@ -11,11 +11,12 @@ ifneq ("$(ENABLE_SCRUB)","yes") MAN_PAGES = $(filter-out xfs_scrub%,$(shell echo *.$(MAN_SECTION))) else MAN_PAGES = $(shell echo *.$(MAN_SECTION)) + MAN_PAGES += xfs_scrub_all.8 endif MAN_PAGES += mkfs.xfs.8 MAN_DEST = $(PKG_MAN_DIR)/man$(MAN_SECTION) LSRCFILES = $(MAN_PAGES) -DIRT = mkfs.xfs.8 +DIRT = mkfs.xfs.8 xfs_scrub_all.8 default : $(MAN_PAGES) @@ -29,4 +30,8 @@ mkfs.xfs.8: mkfs.xfs.8.in @echo " [SED] $@" $(Q)$(SED) -e 's|@mkfs_cfg_dir@|$(MKFS_CFG_DIR)|g' < $^ > $@ +xfs_scrub_all.8: xfs_scrub_all.8.in + @echo " [SED] $@" + $(Q)$(SED) -e 's|@stampfile@|$(XFS_SCRUB_ALL_AUTO_MEDIA_SCAN_STAMP)|g' < $^ > $@ + install-dev : diff --git a/man/man8/xfs_scrub_all.8 b/man/man8/xfs_scrub_all.8.in similarity index 63% rename from man/man8/xfs_scrub_all.8 rename to man/man8/xfs_scrub_all.8.in index 86a9b3eced28..0aa87e237165 100644 --- a/man/man8/xfs_scrub_all.8 +++ b/man/man8/xfs_scrub_all.8.in @@ -18,6 +18,21 @@ operations can be run in parallel so long as no two scrubbers access the same device simultaneously. .SH OPTIONS .TP +.B \--auto-media-scan-interval +Automatically enable the file data scan (i.e. the +.B -x +flag) if it has not been run in the specified interval. +The interval must be a floating point number with an optional unit suffix. +Supported unit suffixes are +.IR y ", " q ", " mo ", " w ", " d ", " h ", " m ", and " s +for years, 90-day quarters, 30-day months, weeks, days, hours, minutes, and +seconds, respectively. +If no units are specified, the default is seconds. +.TP +.B \--auto-media-scan-stamp +Path to a file that will record the last time the media scan was run. +Defaults to @stampfile@. +.TP .B \-h Display help. .TP diff --git a/scrub/Makefile b/scrub/Makefile index 5567ec061e82..091a5c94baa1 100644 --- a/scrub/Makefile +++ b/scrub/Makefile @@ -118,6 +118,7 @@ xfs_scrub_all: xfs_scrub_all.in $(builddefs) -e "s|@scrub_svcname@|$(scrub_svcname)|g" \ -e "s|@scrub_media_svcname@|$(scrub_media_svcname)|g" \ -e "s|@pkg_version@|$(PKG_VERSION)|g" \ + -e "s|@stampfile@|$(XFS_SCRUB_ALL_AUTO_MEDIA_SCAN_STAMP)|g" \ -e "s|@scrub_service_args@|$(XFS_SCRUB_SERVICE_ARGS)|g" \ -e "s|@scrub_args@|$(XFS_SCRUB_ARGS)|g" < $< > $@ $(Q)chmod a+x $@ @@ -141,6 +142,7 @@ install: $(INSTALL_SCRUB) -e "s|@scrub_service_args@|$(XFS_SCRUB_SERVICE_ARGS)|g" \ -e "s|@scrub_args@|$(XFS_SCRUB_ARGS)|g" \ -e "s|@pkg_libexec_dir@|$(PKG_LIBEXEC_DIR)|g" \ + -e "s|@pkg_state_dir@|$(PKG_STATE_DIR)|g" \ < $< > $@ %.cron: %.cron.in $(builddefs) @@ -161,6 +163,7 @@ install-scrub: default $(INSTALL) -m 755 -d $(PKG_SBIN_DIR) $(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR) $(INSTALL) -m 755 $(XFS_SCRUB_ALL_PROG) $(PKG_SBIN_DIR) + $(INSTALL) -m 755 -d $(PKG_STATE_DIR) install-udev: $(UDEV_RULES) $(INSTALL) -m 755 -d $(UDEV_RULE_DIR) diff --git a/scrub/xfs_scrub_all.in b/scrub/xfs_scrub_all.in index afba0dbe8912..9d5cbd2a6487 100644 --- a/scrub/xfs_scrub_all.in +++ b/scrub/xfs_scrub_all.in @@ -16,6 +16,10 @@ import os import argparse import signal from io import TextIOWrapper +from pathlib import Path +from datetime import timedelta +from datetime import datetime +from datetime import timezone retcode = 0 terminate = False @@ -248,6 +252,65 @@ def wait_for_termination(cond, killfuncs): fn() return True +def scan_interval(string): + '''Convert a textual scan interval argument into a time delta.''' + + if string.endswith('y'): + year = timedelta(seconds = 31556952) + return year * float(string[:-1]) + if string.endswith('q'): + return timedelta(days = 90 * float(string[:-1])) + if string.endswith('mo'): + return timedelta(days = 30 * float(string[:-2])) + if string.endswith('w'): + return timedelta(weeks = float(string[:-1])) + if string.endswith('d'): + return timedelta(days = float(string[:-1])) + if string.endswith('h'): + return timedelta(hours = float(string[:-1])) + if string.endswith('m'): + return timedelta(minutes = float(string[:-1])) + if string.endswith('s'): + return timedelta(seconds = float(string[:-1])) + return timedelta(seconds = int(string)) + +def utcnow(): + '''Create a representation of the time right now, in UTC.''' + + dt = datetime.utcnow() + return dt.replace(tzinfo = timezone.utc) + +def enable_automatic_media_scan(args): + '''Decide if we enable media scanning automatically.''' + already_enabled = args.x + + try: + interval = scan_interval(args.auto_media_scan_interval) + except Exception as e: + raise Exception('%s: Invalid media scan interval.' % \ + args.auto_media_scan_interval) + + p = Path(args.auto_media_scan_stamp) + if already_enabled: + res = True + else: + try: + last_run = p.stat().st_mtime + now = utcnow().timestamp() + res = last_run + interval.total_seconds() < now + except FileNotFoundError: + res = True + + if res: + # Truncate the stamp file to update its mtime + with p.open('w') as f: + pass + if not already_enabled: + print('Automatically enabling file data scrub.') + sys.stdout.flush() + + return res + def main(): '''Find mounts, schedule scrub runs.''' def thr(mnt, devs): @@ -262,13 +325,24 @@ def main(): action = "store_true") parser.add_argument("-x", help = "Scrub file data after filesystem metadata.", \ action = "store_true") + parser.add_argument("--auto-media-scan-interval", help = "Automatically scrub file data at this interval.", \ + default = None) + parser.add_argument("--auto-media-scan-stamp", help = "Stamp file for automatic file data scrub.", \ + default = '@stampfile@') args = parser.parse_args() if args.V: print("xfs_scrub_all version @pkg_version@") sys.exit(0) - scrub_media = args.x + if args.auto_media_scan_interval is not None: + try: + scrub_media = enable_automatic_media_scan(args) + except Exception as e: + print(e) + sys.exit(16) + else: + scrub_media = args.x fs = find_mounts() diff --git a/scrub/xfs_scrub_all.service.in b/scrub/xfs_scrub_all.service.in index 478cd8d057a2..9ecc3af0c1f6 100644 --- a/scrub/xfs_scrub_all.service.in +++ b/scrub/xfs_scrub_all.service.in @@ -34,11 +34,13 @@ CapabilityBoundingSet= NoNewPrivileges=true RestrictSUIDSGID=true -# Make the entire filesystem readonly. We don't want to hide anything because -# we need to find all mounted XFS filesystems in the host. +# Make the entire filesystem readonly except for the media scan stamp file +# directory. We don't want to hide anything because we need to find all +# mounted XFS filesystems in the host. ProtectSystem=strict ProtectHome=read-only PrivateTmp=false +BindPaths=@pkg_state_dir@ # No network access except to the systemd control socket PrivateNetwork=true From patchwork Tue Jul 2 01:07:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13718812 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5EF4E9449 for ; Tue, 2 Jul 2024 01:07:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719882454; cv=none; b=lkzyuA9ibnt7nh5lct27AL/ajDrRNJ8geohmQIoPg4MT7fbPxRSjuMse/0uPSGWRY7jz/2J5shNb7O2IbLVv/a+3t3NgdBFYpbMTgzhxOturWkPFg3M4TTkhsRVRBffx24FgMVON9MTS5PO9coYSBmozTdvLyivwoBZKeH4zd28= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719882454; c=relaxed/simple; bh=4+R1Q2bAGC2xE7hAEm3oqp2ncRFlEbNW5E2lo21U50s=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Hp9p2Mjt6+2hprLP0Gt5jdZhc8n6eUZMR5xXDjNwUK6ZQOCcs9tMSJV3qghgSJkl5x3wXRm7rKXikaYYbiY7brN11/WfbdSaRGCA50i++a9Tr5EXB5i8Z/J0B+HXFTJjbi3xYVjX5ZqXj2+Ba+99KCgmnD5eEltyNA9PMA2aehU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KUyB7pMR; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="KUyB7pMR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 35B41C116B1; Tue, 2 Jul 2024 01:07:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1719882454; bh=4+R1Q2bAGC2xE7hAEm3oqp2ncRFlEbNW5E2lo21U50s=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=KUyB7pMRC5MKSjl9zaUMXA1NaJfWTDEMypONIUG4pWOxzoPTChaxHiw/+RI1QKo4P tcLe0g+RQdYzuuYpXvGlHEYlDVx01yu6KFGuKfCxlRn4zBUY0wR2oNaCHqZzpQIeHZ EVE/kNVQVZ/YgRwyYFICEisPkjWlqzEBaZPSSUrPzeUfg8MxThPWDRSv8aeEvpBrmC UVxL77IPGwLVBfwK3Qp+UepVqULeQEEnLYk87czcSv8rsIF+Umo62qrf36cezIm3iT Sqt5KpXHBpCfKJLe5ea/VxWjNZmvKKIo4j3qBqZ4Xlb8tN5ahoVAH3KxV0hYTXZUdu Fy5OKYHN5NAYA== Date: Mon, 01 Jul 2024 18:07:33 -0700 Subject: [PATCH 5/6] xfs_scrub_all: trigger automatic media scans once per month From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org, hch@lst.de Message-ID: <171988119485.2008463.18281382305199915261.stgit@frogsfrogsfrogs> In-Reply-To: <171988119402.2008463.10432604765226555660.stgit@frogsfrogsfrogs> References: <171988119402.2008463.10432604765226555660.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Teach the xfs_scrub_all background service to trigger an automatic scan of all file data once per month. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- scrub/Makefile | 8 +++++++- scrub/xfs_scrub_all.cron.in | 2 +- scrub/xfs_scrub_all.service.in | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/scrub/Makefile b/scrub/Makefile index 091a5c94baa1..0e09ed127b82 100644 --- a/scrub/Makefile +++ b/scrub/Makefile @@ -108,6 +108,9 @@ CFILES += unicrash.c LCFLAGS += -DHAVE_LIBICU $(LIBICU_CFLAGS) endif +# Automatically trigger a media scan once per month +XFS_SCRUB_ALL_AUTO_MEDIA_SCAN_INTERVAL=1mo + LDIRT = $(XFS_SCRUB_ALL_PROG) $(XFS_SCRUB_FAIL_PROG) *.service *.cron default: depend $(LTCOMMAND) $(XFS_SCRUB_ALL_PROG) $(XFS_SCRUB_FAIL_PROG) $(OPTIONAL_TARGETS) @@ -143,11 +146,14 @@ install: $(INSTALL_SCRUB) -e "s|@scrub_args@|$(XFS_SCRUB_ARGS)|g" \ -e "s|@pkg_libexec_dir@|$(PKG_LIBEXEC_DIR)|g" \ -e "s|@pkg_state_dir@|$(PKG_STATE_DIR)|g" \ + -e "s|@media_scan_interval@|$(XFS_SCRUB_ALL_AUTO_MEDIA_SCAN_INTERVAL)|g" \ < $< > $@ %.cron: %.cron.in $(builddefs) @echo " [SED] $@" - $(Q)$(SED) -e "s|@sbindir@|$(PKG_SBIN_DIR)|g" < $< > $@ + $(Q)$(SED) -e "s|@sbindir@|$(PKG_SBIN_DIR)|g" \ + -e "s|@media_scan_interval@|$(XFS_SCRUB_ALL_AUTO_MEDIA_SCAN_INTERVAL)|g" \ + < $< > $@ install-systemd: default $(SYSTEMD_SERVICES) $(INSTALL) -m 755 -d $(SYSTEMD_SYSTEM_UNIT_DIR) diff --git a/scrub/xfs_scrub_all.cron.in b/scrub/xfs_scrub_all.cron.in index e08a9daf9259..e6633e091c42 100644 --- a/scrub/xfs_scrub_all.cron.in +++ b/scrub/xfs_scrub_all.cron.in @@ -3,4 +3,4 @@ # Copyright (C) 2018-2024 Oracle. All Rights Reserved. # Author: Darrick J. Wong # -10 3 * * 0 root test -e /run/systemd/system || @sbindir@/xfs_scrub_all +10 3 * * 0 root test -e /run/systemd/system || @sbindir@/xfs_scrub_all --auto-media-scan-interval @media_scan_interval@ diff --git a/scrub/xfs_scrub_all.service.in b/scrub/xfs_scrub_all.service.in index 9ecc3af0c1f6..8ed682989048 100644 --- a/scrub/xfs_scrub_all.service.in +++ b/scrub/xfs_scrub_all.service.in @@ -12,7 +12,7 @@ After=paths.target multi-user.target network.target network-online.target system [Service] Type=oneshot Environment=SERVICE_MODE=1 -ExecStart=@sbindir@/xfs_scrub_all +ExecStart=@sbindir@/xfs_scrub_all --auto-media-scan-interval @media_scan_interval@ SyslogIdentifier=xfs_scrub_all # Create the service underneath the scrub background service slice so that we From patchwork Tue Jul 2 01:07:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13718813 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0B32E9449 for ; Tue, 2 Jul 2024 01:07:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719882470; cv=none; b=QkZUOtrdFfQstSrmQj8z/ULuwNpWMHrV9Kvz2PPRJEuhCrepTrNXN1Z0hSTQ97MuT8qxhpU5ncCWQeJ9mrOLXpdn0JAgVxyqRHts31d8zpVwLpHeOqmNq0BHdnzTJJJ2fDQqbWTlupXlqupBXOa7v6SFbQMaycoxO9Unzqi/31M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719882470; c=relaxed/simple; bh=SU/Dz3LMbFhThTWaeb2ntg30Q3ETAxtLQXdV0in4an4=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=XrYFj8HI2Ng/gS10cOFgi14HCQXgi9d7SvuZbh7N2kdg+UM6qqgnWpjlkSbqNbXAXM+rHkjAK9gSzVVoSzzHBD85WKW4JPs5t5AnC94wIlkimepsNthnMeuyhDaqRn83pIkd0fkZjhE4m7BY2q00c0M/6l7F6M2z7OwDNnSk+6c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=aKqBynYd; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="aKqBynYd" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D286DC116B1; Tue, 2 Jul 2024 01:07:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1719882469; bh=SU/Dz3LMbFhThTWaeb2ntg30Q3ETAxtLQXdV0in4an4=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=aKqBynYd4LBD3nMIXSTLYXf4W7lU21bjDkCdVEizMJbhFYucT+bLa4dSS/w5vTKtn g82mAY9aOjHkgjQe0//k+kE1D1wummZ2U5hT9AwWDpEt9Hgy8YUFhesYEYTPaty0vU h6mH/psEKA7YIhYRNm3sk5L2VuoLGb//w6uHxOX190TIvLriAS5WKosgctdq+hjkC4 a6jZgU6DGsYEmwdhbYVXDHqEUgeNxZrUdlZKzVE6ZbhQyUIVoeVmml1eMVrg+HZGvP /t1vvoJMLSwA5gZ8UWH3sL3e83KmVwy79sGxcrOpRJ0L9L2Z/0ccRMzsQWzQb0Daos LVvC1m3ztKWnw== Date: Mon, 01 Jul 2024 18:07:49 -0700 Subject: [PATCH 6/6] xfs_scrub_all: failure reporting for the xfs_scrub_all job From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org, hch@lst.de Message-ID: <171988119500.2008463.4413433891113523167.stgit@frogsfrogsfrogs> In-Reply-To: <171988119402.2008463.10432604765226555660.stgit@frogsfrogsfrogs> References: <171988119402.2008463.10432604765226555660.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Create a failure reporting service for when xfs_scrub_all fails. This shouldn't happen often, but let's report anyways. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- scrub/Makefile | 1 scrub/xfs_scrub_all.service.in | 1 scrub/xfs_scrub_all_fail.service.in | 71 +++++++++++++++++++++++++++++++++++ scrub/xfs_scrub_fail.in | 35 ++++++++++++++--- 4 files changed, 101 insertions(+), 7 deletions(-) create mode 100644 scrub/xfs_scrub_all_fail.service.in diff --git a/scrub/Makefile b/scrub/Makefile index 0e09ed127b82..7e6882450d54 100644 --- a/scrub/Makefile +++ b/scrub/Makefile @@ -26,6 +26,7 @@ SYSTEMD_SERVICES=\ $(scrub_media_svcname) \ xfs_scrub_media_fail@.service \ xfs_scrub_all.service \ + xfs_scrub_all_fail.service \ xfs_scrub_all.timer \ system-xfs_scrub.slice OPTIONAL_TARGETS += $(SYSTEMD_SERVICES) diff --git a/scrub/xfs_scrub_all.service.in b/scrub/xfs_scrub_all.service.in index 8ed682989048..b86b787d2ee3 100644 --- a/scrub/xfs_scrub_all.service.in +++ b/scrub/xfs_scrub_all.service.in @@ -5,6 +5,7 @@ [Unit] Description=Online XFS Metadata Check for All Filesystems +OnFailure=xfs_scrub_all_fail.service ConditionACPower=true Documentation=man:xfs_scrub_all(8) After=paths.target multi-user.target network.target network-online.target systemd-networkd.service NetworkManager.service connman.service diff --git a/scrub/xfs_scrub_all_fail.service.in b/scrub/xfs_scrub_all_fail.service.in new file mode 100644 index 000000000000..53479db84771 --- /dev/null +++ b/scrub/xfs_scrub_all_fail.service.in @@ -0,0 +1,71 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2018-2024 Oracle. All Rights Reserved. +# Author: Darrick J. Wong + +[Unit] +Description=Online XFS Metadata Check for All Filesystems Failure Reporting +Documentation=man:xfs_scrub_all(8) + +[Service] +Type=oneshot +Environment=EMAIL_ADDR=root +ExecStart=@pkg_libexec_dir@/xfs_scrub_fail "${EMAIL_ADDR}" xfs_scrub_all +User=mail +Group=mail +SupplementaryGroups=systemd-journal + +# No realtime scheduling +RestrictRealtime=true + +# Make the entire filesystem readonly and /home inaccessible. +ProtectSystem=full +ProtectHome=yes +PrivateTmp=true +RestrictSUIDSGID=true + +# Emailing reports requires network access, but not the ability to change the +# hostname. +ProtectHostname=true + +# Don't let the program mess with the kernel configuration at all +ProtectKernelLogs=true +ProtectKernelModules=true +ProtectKernelTunables=true +ProtectControlGroups=true +ProtectProc=invisible +RestrictNamespaces=true + +# Can't hide /proc because journalctl needs it to find various pieces of log +# information +#ProcSubset=pid + +# Only allow the default personality Linux +LockPersonality=true + +# No writable memory pages +MemoryDenyWriteExecute=true + +# Don't let our mounts leak out to the host +PrivateMounts=true + +# Restrict system calls to the native arch and only enough to get things going +SystemCallArchitectures=native +SystemCallFilter=@system-service +SystemCallFilter=~@privileged +SystemCallFilter=~@resources +SystemCallFilter=~@mount + +# xfs_scrub needs these privileges to run, and no others +CapabilityBoundingSet= +NoNewPrivileges=true + +# Failure reporting shouldn't create world-readable files +UMask=0077 + +# Clean up any IPC objects when this unit stops +RemoveIPC=true + +# No access to hardware device files +PrivateDevices=true +ProtectClock=true diff --git a/scrub/xfs_scrub_fail.in b/scrub/xfs_scrub_fail.in index e420917f699f..089b438f03c0 100755 --- a/scrub/xfs_scrub_fail.in +++ b/scrub/xfs_scrub_fail.in @@ -5,14 +5,13 @@ # Copyright (C) 2018-2024 Oracle. All Rights Reserved. # Author: Darrick J. Wong -# Email logs of failed xfs_scrub unit runs +# Email logs of failed xfs_scrub and xfs_scrub_all unit runs recipient="$1" test -z "${recipient}" && exit 0 service="$2" test -z "${service}" && exit 0 mntpoint="$3" -test -z "${mntpoint}" && exit 0 hostname="$(hostname -f 2>/dev/null)" test -z "${hostname}" && hostname="${HOSTNAME}" @@ -23,11 +22,13 @@ if [ ! -x "${mailer}" ]; then exit 1 fi -# Turn the mountpoint into a properly escaped systemd instance name -scrub_svc="$(systemd-escape --template "${service}@.service" --path "${mntpoint}")" +fail_mail_mntpoint() { + local scrub_svc -(cat << ENDL -To: $1 + # Turn the mountpoint into a properly escaped systemd instance name + scrub_svc="$(systemd-escape --template "${service}@.service" --path "${mntpoint}")" + cat << ENDL +To: ${recipient} From: <${service}@${hostname}> Subject: ${service} failure on ${mntpoint} Content-Transfer-Encoding: 8bit @@ -38,5 +39,25 @@ Please do not reply to this mesage. A log of what happened follows: ENDL -systemctl status --full --lines 4294967295 "${scrub_svc}") | "${mailer}" -t -i + systemctl status --full --lines 4294967295 "${scrub_svc}" +} + +fail_mail() { + cat << ENDL +To: ${recipient} +From: <${service}@${hostname}> +Subject: ${service} failure + +So sorry, the automatic ${service} on ${hostname} failed. + +A log of what happened follows: +ENDL + systemctl status --full --lines 4294967295 "${service}" +} + +if [ -n "${mntpoint}" ]; then + fail_mail_mntpoint | "${mailer}" -t -i +else + fail_mail | "${mailer}" -t -i +fi exit "${PIPESTATUS[1]}"