From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: sandeen@redhat.com
Cc: linux-xfs@vger.kernel.org
Subject: [PATCH v2 27/29] xfs_scrub: integrate services with systemd
Date: Fri, 26 Jan 2018 10:15:59 -0800 [thread overview]
Message-ID: <20180126181559.GV9068@magnolia> (raw)
In-Reply-To: <151622668376.31925.11115543396206091025.stgit@magnolia>
From: Darrick J. Wong <darrick.wong@oracle.com>
Create a systemd service unit so that we can run the online scrubber
under systemd with (somewhat) appropriate containment.
NOTE: The VERSION changes are due to a symbol collision between
variables the pkgconfig autoconf macros use and our own thing.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
.gitignore | 4 ++
VERSION | 8 ++--
configure.ac | 2 +
include/builddefs.in | 4 ++
m4/Makefile | 1 +
m4/package_globals.m4 | 4 +-
m4/package_services.m4 | 72 ++++++++++++++++++++++++++++++++++++++
release.sh | 2 +
scrub/Makefile | 36 ++++++++++++++++++-
scrub/xfs_scrub.c | 17 +++++++++
scrub/xfs_scrub@.service.in | 19 ++++++++++
scrub/xfs_scrub_all.cron.in | 1 +
scrub/xfs_scrub_all.in | 49 ++++++++++++++++++++++++++
scrub/xfs_scrub_all.service.in | 9 +++++
scrub/xfs_scrub_all.timer | 11 ++++++
scrub/xfs_scrub_fail | 26 ++++++++++++++
scrub/xfs_scrub_fail@.service.in | 10 +++++
17 files changed, 267 insertions(+), 8 deletions(-)
create mode 100644 m4/package_services.m4
create mode 100644 scrub/xfs_scrub@.service.in
create mode 100644 scrub/xfs_scrub_all.cron.in
create mode 100644 scrub/xfs_scrub_all.service.in
create mode 100644 scrub/xfs_scrub_all.timer
create mode 100755 scrub/xfs_scrub_fail
create mode 100644 scrub/xfs_scrub_fail@.service.in
diff --git a/.gitignore b/.gitignore
index a3db640..d887451 100644
--- a/.gitignore
+++ b/.gitignore
@@ -69,6 +69,10 @@ cscope.*
/rtcp/xfs_rtcp
/spaceman/xfs_spaceman
/scrub/xfs_scrub
+/scrub/xfs_scrub@.service
+/scrub/xfs_scrub_all
+/scrub/xfs_scrub_all.service
+/scrub/xfs_scrub_fail@.service
# generated crc files
/libxfs/crc32selftest
diff --git a/VERSION b/VERSION
index 01fda21..c724992 100644
--- a/VERSION
+++ b/VERSION
@@ -1,7 +1,7 @@
#
# This file is used by configure to get version information
#
-PKG_MAJOR=4
-PKG_MINOR=14
-PKG_REVISION=0
-PKG_BUILD=1
+XFS_PKG_MAJOR=4
+XFS_PKG_MINOR=14
+XFS_PKG_REVISION=0
+XFS_PKG_BUILD=1
diff --git a/configure.ac b/configure.ac
index bb032e5..b438165 100644
--- a/configure.ac
+++ b/configure.ac
@@ -174,6 +174,8 @@ AC_HAVE_OPENAT
AC_HAVE_FSTATAT
AC_HAVE_SG_IO
AC_HAVE_HDIO_GETGEO
+AC_CONFIG_SYSTEMD_SYSTEM_UNIT_DIR
+AC_CONFIG_CROND_DIR
if test "$enable_blkid" = yes; then
AC_HAVE_BLKID_TOPO
diff --git a/include/builddefs.in b/include/builddefs.in
index d44faf9..df76b2c 100644
--- a/include/builddefs.in
+++ b/include/builddefs.in
@@ -127,6 +127,10 @@ HAVE_OPENAT = @have_openat@
HAVE_FSTATAT = @have_fstatat@
HAVE_SG_IO = @have_sg_io@
HAVE_HDIO_GETGEO = @have_hdio_getgeo@
+HAVE_SYSTEMD = @have_systemd@
+SYSTEMD_SYSTEM_UNIT_DIR = @systemd_system_unit_dir@
+HAVE_CROND = @have_crond@
+CROND_DIR = @crond_dir@
GCCFLAGS = -funsigned-char -fno-strict-aliasing -Wall
# -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-decl
diff --git a/m4/Makefile b/m4/Makefile
index 61d617e..a6d11e9 100644
--- a/m4/Makefile
+++ b/m4/Makefile
@@ -21,6 +21,7 @@ LSRCFILES = \
package_libcdev.m4 \
package_pthread.m4 \
package_sanitizer.m4 \
+ package_services.m4 \
package_types.m4 \
package_unistring.m4 \
package_utilies.m4 \
diff --git a/m4/package_globals.m4 b/m4/package_globals.m4
index e469671..2ede859 100644
--- a/m4/package_globals.m4
+++ b/m4/package_globals.m4
@@ -11,9 +11,9 @@ AC_DEFUN([AC_PACKAGE_GLOBALS],
AC_PROG_CC
. ./VERSION
- pkg_version=${PKG_MAJOR}.${PKG_MINOR}.${PKG_REVISION}
+ pkg_version=${XFS_PKG_MAJOR}.${XFS_PKG_MINOR}.${XFS_PKG_REVISION}
AC_SUBST(pkg_version)
- pkg_release=$PKG_BUILD
+ pkg_release=$XFS_PKG_BUILD
test -z "$BUILD_VERSION" || pkg_release="$BUILD_VERSION"
AC_SUBST(pkg_release)
diff --git a/m4/package_services.m4 b/m4/package_services.m4
new file mode 100644
index 0000000..127d43c
--- /dev/null
+++ b/m4/package_services.m4
@@ -0,0 +1,72 @@
+#
+# Figure out where to put systemd service units
+#
+AC_DEFUN([AC_CONFIG_SYSTEMD_SYSTEM_UNIT_DIR],
+[
+ AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+ AC_ARG_WITH([systemd_unit_dir],
+ [AS_HELP_STRING([--with-systemd-unit-dir@<:@=DIR@:>@],
+ [Install systemd system units into DIR.])],
+ [],
+ [with_systemd_unit_dir=yes])
+ AS_IF([test "x${with_systemd_unit_dir}" != "xno"],
+ [
+ AS_IF([test "x${with_systemd_unit_dir}" = "xyes"],
+ [
+ PKG_CHECK_MODULES([SYSTEMD], [systemd])
+ with_systemd_unit_dir="$(pkg-config --variable=systemdsystemunitdir systemd 2>/dev/null)"
+ ])
+ AC_MSG_CHECKING([for systemd system unit dir])
+ systemd_system_unit_dir="${with_systemd_unit_dir}"
+ AS_IF([test -n "${systemd_system_unit_dir}"],
+ [
+ AC_MSG_RESULT(${systemd_system_unit_dir})
+ have_systemd="yes"
+ ],
+ [
+ AC_MSG_RESULT(no)
+ have_systemd="no"
+ ])
+ ],
+ [
+ have_systemd="disabled"
+ ])
+ AC_SUBST(have_systemd)
+ AC_SUBST(systemd_system_unit_dir)
+])
+
+#
+# Figure out where to install crontabs
+#
+AC_DEFUN([AC_CONFIG_CROND_DIR],
+[
+ AC_ARG_WITH([crond_dir],
+ [AS_HELP_STRING([--with-crond-dir@<:@=DIR@:>@],
+ [Install system crontabs into DIR.])],
+ [],
+ [with_crond_dir=yes])
+ AS_IF([test "x${with_crond_dir}" != "xno"],
+ [
+ AS_IF([test "x${with_crond_dir}" = "xyes"],
+ [
+ AS_IF([test -d "/etc/cron.d"],
+ [with_crond_dir="/etc/cron.d"])
+ ])
+ AC_MSG_CHECKING([for system crontab dir])
+ crond_dir="${with_crond_dir}"
+ AS_IF([test -n "${crond_dir}"],
+ [
+ AC_MSG_RESULT(${crond_dir})
+ have_crond="yes"
+ ],
+ [
+ AC_MSG_RESULT(no)
+ have_crond="no"
+ ])
+ ],
+ [
+ have_crond="disabled"
+ ])
+ AC_SUBST(have_crond)
+ AC_SUBST(crond_dir)
+])
diff --git a/release.sh b/release.sh
index 577257a..3f7d2ee 100755
--- a/release.sh
+++ b/release.sh
@@ -11,7 +11,7 @@
. ./VERSION
-version=${PKG_MAJOR}.${PKG_MINOR}.${PKG_REVISION}
+version=${XFS_PKG_MAJOR}.${XFS_PKG_MINOR}.${XFS_PKG_REVISION}
date=`date +"%-d %B %Y"`
echo "Cleaning up"
diff --git a/scrub/Makefile b/scrub/Makefile
index ca6dab0..0632794 100644
--- a/scrub/Makefile
+++ b/scrub/Makefile
@@ -15,6 +15,19 @@ LTCOMMAND = xfs_scrub
INSTALL_SCRUB = install-scrub
XFS_SCRUB_ALL_PROG = xfs_scrub_all
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
+OPTIONAL_TARGETS += $(SYSTEMD_SERVICES)
+endif
+ifeq ($(HAVE_CROND),yes)
+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_DIR)/$(PKG_NAME)
+endif
+
endif # scrub_prereqs
HFILES = \
@@ -84,7 +97,7 @@ ifeq ($(HAVE_HDIO_GETGEO),yes)
LCFLAGS += -DHAVE_HDIO_GETGEO
endif
-default: depend $(LTCOMMAND) $(XFS_SCRUB_ALL_PROG)
+default: depend $(LTCOMMAND) $(XFS_SCRUB_ALL_PROG) $(OPTIONAL_TARGETS)
xfs_scrub_all: xfs_scrub_all.in
@echo " [SED] $@"
@@ -98,6 +111,27 @@ include $(BUILDRULES)
install: $(INSTALL_SCRUB)
+%.service: %.service.in
+ @echo " [SED] $@"
+ $(Q)$(SED) -e "s|@sbindir@|$(PKG_ROOT_SBIN_DIR)|g" \
+ -e "s|@scrub_args@|$(XFS_SCRUB_ARGS)|g" \
+ -e "s|@pkg_lib_dir@|$(PKG_LIB_DIR)|g" \
+ -e "s|@pkg_name@|$(PKG_NAME)|g" < $< > $@
+
+%.cron: %.cron.in
+ @echo " [SED] $@"
+ $(Q)$(SED) -e "s|@sbindir@|$(PKG_ROOT_SBIN_DIR)|g" < $< > $@
+
+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_DIR)/$(PKG_NAME)
+ $(INSTALL) -m 755 xfs_scrub_fail $(PKG_LIB_DIR)/$(PKG_NAME)
+
+install-crond: default $(CRONTABS)
+ $(INSTALL) -m 755 -d $(CROND_DIR)
+ $(INSTALL) -m 644 $(CRONTABS) $(CROND_DIR)
+
install-scrub: default
$(INSTALL) -m 755 -d $(PKG_ROOT_SBIN_DIR)
$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_ROOT_SBIN_DIR)
diff --git a/scrub/xfs_scrub.c b/scrub/xfs_scrub.c
index baf8760..2469225 100644
--- a/scrub/xfs_scrub.c
+++ b/scrub/xfs_scrub.c
@@ -154,6 +154,12 @@ bool want_fstrim = true;
bool stderr_isatty;
bool stdout_isatty;
+/*
+ * If we are running as a service, we need to be careful about what
+ * error codes we return to the calling process.
+ */
+static bool is_service;
+
static void __attribute__((noreturn))
usage(void)
{
@@ -617,6 +623,9 @@ _("Only one of the options -n or -y may be specified.\n"));
if (stdout_isatty && !progress_fp)
progress_fp = fdopen(1, "w+");
+ if (getenv("SERVICE_MODE"))
+ is_service = true;
+
/* Find the mount record for the passed-in argument. */
if (stat(argv[optind], &ctx.mnt_sb) < 0) {
fprintf(stderr,
@@ -717,5 +726,13 @@ _("%s: %llu warnings found.\n"),
free(ctx.blkdev);
free(ctx.mntpoint);
+ /*
+ * If we're being run as a service, the return code must fit the
+ * LSB init script action error guidelines, which is to say that
+ * we compress all errors to 1 and log what actually happened.
+ */
+ if (is_service && ret > 0)
+ return 1;
+
return ret;
}
diff --git a/scrub/xfs_scrub@.service.in b/scrub/xfs_scrub@.service.in
new file mode 100644
index 0000000..a868a27
--- /dev/null
+++ b/scrub/xfs_scrub@.service.in
@@ -0,0 +1,19 @@
+[Unit]
+Description=Online XFS Metadata Check for %I
+OnFailure=xfs_scrub_fail@%i.service
+
+[Service]
+Type=oneshot
+WorkingDirectory=%I
+PrivateNetwork=true
+ProtectSystem=full
+ProtectHome=read-only
+PrivateTmp=yes
+AmbientCapabilities=CAP_SYS_ADMIN CAP_FOWNER CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_SYS_RAWIO
+NoNewPrivileges=yes
+User=nobody
+IOSchedulingClass=idle
+CPUSchedulingPolicy=idle
+Environment=SERVICE_MODE=1
+ExecStart=@sbindir@/xfs_scrub @scrub_args@ %I
+SyslogIdentifier=%N
diff --git a/scrub/xfs_scrub_all.cron.in b/scrub/xfs_scrub_all.cron.in
new file mode 100644
index 0000000..3dea929
--- /dev/null
+++ b/scrub/xfs_scrub_all.cron.in
@@ -0,0 +1 @@
+10 3 * * 0 root test -e /run/systemd/system || @sbindir@/xfs_scrub_all
diff --git a/scrub/xfs_scrub_all.in b/scrub/xfs_scrub_all.in
index 7738644..0dbfd6c 100644
--- a/scrub/xfs_scrub_all.in
+++ b/scrub/xfs_scrub_all.in
@@ -25,10 +25,19 @@ import json
import threading
import time
import sys
+import os
retcode = 0
terminate = False
+def DEVNULL():
+ '''Return /dev/null in subprocess writable format.'''
+ try:
+ from subprocess import DEVNULL
+ return DEVNULL
+ except ImportError:
+ return open(os.devnull, 'wb')
+
def find_mounts():
'''Map mountpoints to physical disks.'''
@@ -55,6 +64,13 @@ def find_mounts():
fs[mnt] = set([lastdisk])
return fs
+def kill_systemd(unit, proc):
+ '''Kill systemd unit.'''
+ proc.terminate()
+ cmd=['systemctl', 'stop', unit]
+ x = subprocess.Popen(cmd)
+ x.wait()
+
def run_killable(cmd, stdout, killfuncs, kill_fn):
'''Run a killable program. Returns program retcode or -1 if we can't start it.'''
try:
@@ -81,6 +97,19 @@ def run_scrub(mnt, cond, running_devs, mntdevs, killfuncs):
if terminate:
return
+ # Try it the systemd way
+ cmd=['systemctl', 'start', 'xfs_scrub@%s' % 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
+
# Invoke xfs_scrub manually
cmd=['@sbindir@/xfs_scrub', '@scrub_args@', mnt]
ret = run_killable(cmd, None, killfuncs, \
@@ -112,6 +141,17 @@ 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', '-t', 'xfs_scrub@*', '-o', \
+ 'cat']
+ journalthread = subprocess.Popen(cmd)
+ except:
+ pass
+
# Schedule scrub jobs...
running_devs = set()
killfuncs = set()
@@ -148,6 +188,15 @@ def main():
fs = []
cond.release()
+ if journalthread is not None:
+ journalthread.terminate()
+
+ # If we're being run as a service, the return code must fit the
+ # LSB init script action error guidelines, which is to say that
+ # we compress all errors to 1 and log what actually happened.
+ if 'SERVICE_MODE' in os.environ and retcode != 0:
+ retcode = 1
+
sys.exit(retcode)
if __name__ == '__main__':
diff --git a/scrub/xfs_scrub_all.service.in b/scrub/xfs_scrub_all.service.in
new file mode 100644
index 0000000..2831691
--- /dev/null
+++ b/scrub/xfs_scrub_all.service.in
@@ -0,0 +1,9 @@
+[Unit]
+Description=Online XFS Metadata Check for All Filesystems
+ConditionACPower=true
+
+[Service]
+Type=oneshot
+Environment=SERVICE_MODE=1
+ExecStart=@sbindir@/xfs_scrub_all
+SyslogIdentifier=xfs_scrub_all
diff --git a/scrub/xfs_scrub_all.timer b/scrub/xfs_scrub_all.timer
new file mode 100644
index 0000000..2e4a33b
--- /dev/null
+++ b/scrub/xfs_scrub_all.timer
@@ -0,0 +1,11 @@
+[Unit]
+Description=Periodic XFS Online Metadata Check for All Filesystems
+
+[Timer]
+# Run on Sunday at 3:10am, to avoid running afoul of DST changes
+OnCalendar=Sun *-*-* 03:10:00
+RandomizedDelaySec=60
+Persistent=true
+
+[Install]
+WantedBy=timers.target
diff --git a/scrub/xfs_scrub_fail b/scrub/xfs_scrub_fail
new file mode 100755
index 0000000..36dd50e
--- /dev/null
+++ b/scrub/xfs_scrub_fail
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# 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}"
+if [ ! -x "${mailer}" ]; then
+ echo "${mailer}: Mailer program not found."
+ exit 1
+fi
+
+(cat << ENDL
+To: $1
+From: <xfs_scrub@${hostname}>
+Subject: xfs_scrub failure on ${mntpoint}
+
+So sorry, the automatic xfs_scrub of ${mntpoint} on ${hostname} failed.
+
+A log of what happened follows:
+ENDL
+systemctl status --full --lines 4294967295 "xfs_scrub@${mntpoint}") | "${mailer}" -t -i
diff --git a/scrub/xfs_scrub_fail@.service.in b/scrub/xfs_scrub_fail@.service.in
new file mode 100644
index 0000000..785f881
--- /dev/null
+++ b/scrub/xfs_scrub_fail@.service.in
@@ -0,0 +1,10 @@
+[Unit]
+Description=Online XFS Metadata Check Failure Reporting for %I
+
+[Service]
+Type=oneshot
+Environment=EMAIL_ADDR=root
+ExecStart=@pkg_lib_dir@/@pkg_name@/xfs_scrub_fail "${EMAIL_ADDR}" %I
+User=mail
+Group=mail
+SupplementaryGroups=systemd-journal
next prev parent reply other threads:[~2018-01-26 18:16 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-17 22:01 [PATCH v11.1 00/29] xfsprogs: online scrub/repair support Darrick J. Wong
2018-01-17 22:01 ` [PATCH 01/29] xfs_scrub: create online filesystem scrub program Darrick J. Wong
2018-01-17 22:02 ` [PATCH 02/29] xfs_scrub: common error handling Darrick J. Wong
2018-01-17 22:02 ` [PATCH 03/29] xfs_scrub: set up command line argument parsing Darrick J. Wong
2018-01-17 22:02 ` [PATCH 04/29] xfs_scrub: dispatch the various phases of the scrub program Darrick J. Wong
2018-01-17 22:02 ` [PATCH 05/29] xfs_scrub: figure out how many threads we're going to need Darrick J. Wong
2018-01-17 22:02 ` [PATCH 06/29] xfs_scrub: create an abstraction for a block device Darrick J. Wong
2018-01-17 22:02 ` [PATCH 07/29] xfs_scrub: find XFS filesystem geometry Darrick J. Wong
2018-01-17 22:02 ` [PATCH 08/29] xfs_scrub: add inode iteration functions Darrick J. Wong
2018-01-17 22:02 ` [PATCH 09/29] xfs_scrub: add space map " Darrick J. Wong
2018-01-17 22:02 ` [PATCH 10/29] xfs_scrub: add file " Darrick J. Wong
2018-01-17 22:03 ` [PATCH 11/29] xfs_scrub: filesystem counter collection functions Darrick J. Wong
2018-01-17 22:03 ` [PATCH 12/29] xfs_scrub: wrap the scrub ioctl Darrick J. Wong
2018-01-17 22:03 ` [PATCH 13/29] xfs_scrub: scan filesystem and AG metadata Darrick J. Wong
2018-01-17 22:03 ` [PATCH 14/29] xfs_scrub: thread-safe stats counter Darrick J. Wong
2018-01-17 22:03 ` [PATCH 15/29] xfs_scrub: scan inodes Darrick J. Wong
2018-01-17 22:03 ` [PATCH 16/29] xfs_scrub: check directory connectivity Darrick J. Wong
2018-01-17 22:03 ` [PATCH 17/29] xfs_scrub: warn about suspicious characters in directory/xattr names Darrick J. Wong
2018-01-17 22:03 ` [PATCH 18/29] xfs_scrub: warn about normalized Unicode name collisions Darrick J. Wong
2018-01-17 22:03 ` [PATCH 19/29] xfs_scrub: create a bitmap data structure Darrick J. Wong
2018-01-17 22:03 ` [PATCH 20/29] xfs_scrub: create infrastructure to read verify data blocks Darrick J. Wong
2018-01-17 22:04 ` [PATCH 21/29] xfs_scrub: scrub file " Darrick J. Wong
2018-01-17 22:04 ` [PATCH 22/29] xfs_scrub: optionally use SCSI READ VERIFY commands to scrub data blocks on disk Darrick J. Wong
2018-01-17 22:04 ` [PATCH 23/29] xfs_scrub: check summary counters Darrick J. Wong
2018-01-17 22:04 ` [PATCH 24/29] xfs_scrub: fstrim the free areas if there are no errors on the filesystem Darrick J. Wong
2018-01-17 22:04 ` [PATCH 25/29] xfs_scrub: progress indicator Darrick J. Wong
2018-01-17 22:04 ` [PATCH 26/29] xfs_scrub: create a script to scrub all xfs filesystems Darrick J. Wong
2018-01-17 22:04 ` [PATCH 27/29] xfs_scrub: integrate services with systemd Darrick J. Wong
2018-01-25 21:21 ` Eric Sandeen
2018-01-25 21:44 ` Darrick J. Wong
2018-01-25 22:16 ` Eric Sandeen
2018-01-25 22:36 ` Darrick J. Wong
2018-01-25 23:10 ` Darrick J. Wong
2018-01-26 18:15 ` Darrick J. Wong [this message]
2018-01-17 22:04 ` [PATCH 28/29] xfs_scrub: wire up repair ioctl Darrick J. Wong
2018-01-17 22:04 ` [PATCH 29/29] xfs_scrub: schedule and manage optimizations/repairs to the filesystem Darrick J. Wong
-- strict thread matches above, loose matches on Subject: below --
2018-01-31 3:06 [PATCH v11.2 00/29] xfsprogs: online scrub/repair support Darrick J. Wong
2018-01-31 3:09 ` [PATCH 27/29] xfs_scrub: integrate services with systemd Darrick J. Wong
2018-01-31 6:41 ` [PATCH v2 " Darrick J. Wong
2018-01-31 20:30 ` Eric Sandeen
2018-01-31 20:52 ` Darrick J. Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180126181559.GV9068@magnolia \
--to=darrick.wong@oracle.com \
--cc=linux-xfs@vger.kernel.org \
--cc=sandeen@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.