Debian has a package called "systemctl" which provides a systemctl
executable to "manage services without systemd". So test for whether
we have a fully functional systemd system by checking for the
existence of /run/systemd/system instead testing for the presence of
the command named systemctl.
Addresses-Debian-Bug: #1070107
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Brian J. Murrell reported that e2scrub reports failures with one of his
filesystems. From the email discussion after he supplied a metadump:
AHA! This is an ext2 filesystem, since it doesn't have the
"has_journal" or "extents" features turned on:
# e2image -r /tmp/disk.qcow2 /dev/sda
# dumpe2fs /dev/sda -h
dumpe2fs 1.47.1~WIP-2023-12-27 (27-Dec-2023)
Filesystem volume name: <none>
Last mounted on: /opt
Filesystem UUID: 2c70368a-0d54-4805-8620-fda19466d819
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: ext_attr resize_inode dir_index filetype sparse_super large_file
Filesystem flags: signed_directory_hash
Default mount options: user_xattr acl
Filesystem state: not clean with errors
(Note: Filesystem state == "clean" means that EXT2_VALID_FS is set in
the superblock s_state field; "not clean with errors" means that the
flag is not set.)
I bet the "journal only" preen doesn't actually reset the filesystem
state either:
# e2fsck -E journal_only -p /dev/sda
# dumpe2fs /dev/sda -h | grep state
dumpe2fs 1.47.1~WIP-2023-12-27 (27-Dec-2023)
Filesystem state: not clean with errors
Nope.
So now I know what happened -- when mounting an ext* filesystem that
doesn't have a journal, the driver clears EXT2_VALID_FS from the primary
superblock. This forces the system to run e2fsck after a crash, because
that's what you have to do for unjournalled filesystems.
The "e2fsck -E journal_only -p" call in e2scrub only replays the
journal. Since there is no journal, it exits almost immediately.
That's the intended behavior, but then it means that the "e2fsck -fy"
call immediately after sees that the superblock doesn't have
EXT2_VALID_FS set, sets it, and makes e2fsck return 1.
So that's why you're getting the e2scrub failures.
Contrast this to what you get when the filesystem has a journal:
# dumpe2fs -h /dev/sdb
dumpe2fs 1.47.0 (5-Feb-2023)
Filesystem volume name: <none>
Last mounted on: <not available>
Filesystem UUID: e18b8b57-a75e-4316-87ce-6a08969476c3
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery sparse_super large_file
Filesystem flags: signed_directory_hash
Default mount options: user_xattr acl
Filesystem state: clean
Filesystems with journals retain their EXT4_VALID_FS state when they're
mounted.
Hmm. What e2scrub should do about unjournalled filesystems is a thorny
question. My initial thought is that it should skip them, because a
mounted unjournalled filesystem cannot by definition be kept consistent.
Therefore, teach e2scrub_all to avoid them and e2scrub to fail them at
the onset.
Restricting the scope of e2scrub sucks, but in the meantime at least it
means that your filesystem isn't massively corrupt. Thanks for the
metadump, it was very useful for root cause analysis.
Reported-by: "Brian J. Murrell" <brian@interlinx.bc.ca>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Link: https://lore.kernel.org/r/20240110055809.GD722946@frogsfrogsfrogs
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Per FHS 3.0, non-PATH executable binaries are supposed to live under
/usr/libexec, not /usr/lib. e2scrub_fail is an executable script, so
move it to libexec in case some distro some day tries to mount /usr/lib
as noexec or something. Also, there's no reason why these scripts need
to be put under an arch-dependent path.
Cc: Neal Gompa <neal@gompa.dev>
Link: https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch04s07.html
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Neal Gompa <neal@gompa.dev>
Link: https://lore.kernel.org/r/20231231203903.GC36164@frogsfrogsfrogs
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
The unending stream of syzbot bug reports and overwrought filing of CVEs
for corner case handling (i.e. things that distract from actual user
complaints) in ext4 has generated all sorts of of overheated rhetoric
about how every bug is a Serious Security Issue(tm) because anyone can
craft a malicious filesystem on a USB stick, insert the stick into a
victim machine, and mount will trigger a bug in the kernel driver that
leads to some compromise or DoS or something.
I thought that nobody would be foolish enough to automount an ext4
filesystem. What a fool I was! It turns out that udisks can be told
that it's okay to automount things, and then GNOME will do exactly that.
Including mounting mangled ext4 filesystems!
<delete angry rant about poor decisionmaking and armchair fs developers
blasting us on X while not actually doing any of the work>
Turn off /this/ idiocy by adding a udev rule to tell udisks not to
automount ext4 filesystems.
This will not stop a logged in user from unwittingly inserting a
malicious storage device and pressing [mount] and getting breached.
This is not a substitute for a thorough audit of all codebases. This is
not a substitute for lklfuse. This does not solve the general problem
of in-kernel fs drivers being a huge attack surface. I just want a
vacation from the sh*tstorm of bad ideas and threat models that I never
agreed to support.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
systemd services provide an "instance name" that can be associated with
a particular invocation of a service. This allows service users to
invoke multiple copies of a service, each with a unique string. For
e2scrub, we pass the mountpoint of the filesystem as the instance name.
However, systemd services aren't supposed to have slashes in them, so
we're supposed to escape them.
The canonical escaping scheme for pathnames is defined by the
systemd-escape --path command. Unfortunately, we've been adding our own
opinionated sauce for years, to work around the fact that --path didn't
quite work right in systemd before January 2017. The special sauce is
incorrect, and we no longer care about systemd of 7 years past.
Clean up this mess by following the systemd escaping scheme throughout
the service units. Now we can use the '%f' specifier in them, which
makes things a lot less complicated.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Fix this reported typo.
Reported-by: paul kairis <kairis@gmail.com>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
In the case where mkdir -p is not thread-safe (for example, if the
build environment is using busybox's mkdir) the configure script will
fall back to the slow (but safe) install-sh script. In that case
MKDIR_P will be using a relative pathname; so we can't use speed
optimization of defining configure substitutions in MCONFIG.in, since
the substitution will be different depending on depth of the
subdirectory in the Makefile.in file.
https://github.com/tytso/e2fsprogs/issues/51
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
The two second sleep is only needed in e2scrub, and when there is a
failure, so that systemd has a chance to gather the log output before
e2scrub exits. It's not needed if the script is exiting successfully,
and it's never needed for e2scrub_all ever.
Addresses-Debian-Bug: #948193
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
gregor herrmann reports that the weekly e2scrub cronjob emits these
errors:
/sbin/e2scrub_all: line 173: /proc/8234/fd/pipe:[90083173]: No such file or directory
The root cause of this is that the ls_targets stdout is piped to stdin
to the entire ls_targets loop body to prevent the loop body from reading
the loop iteration items. Remove all the broken hackery by reading the
target list into a bash array and iterating the bash array.
Addresses-Debian-Bug: #944033
Reported-by: gregor herrmann <gregoa@debian.org>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Dave Chinner complains that the automated on-boot e2scrub reaping takes
a long time (because the lvs command can take a while to run) even
though the automated e2scrub is disabled via e2scrub.conf on his
systems.
We still need the reaping service to kill off stale e2scrub snapshots
after a crash, but it's unnecessary to annoy everyone with slow bootup.
Because we can look for the e2scrub snapshots in /dev/mapper, let's
skip reaping if periodic e2scrub is disabled unless we find evidence of
e2scrub snapshots in /dev.
Reported-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Some versions of cron leave fd 3 open for some unknown reason. So
when e2scrub_all is run by cron (on non-systemd systems) this results
in an annoying message from the Cron Daemon because lvm will print
warning messages about "leaked file descriptors. So force close fd 3
at the beginning of e2scrub and e2scrub_all.
Addresses-Debian-Bug: #940240
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
If the volume group's free space is exactly the same as snapshot size,
e2scrub_all will skip those logical volumes in those volume groups.
Fix this by changing the test from '>' to '>='.
Fixes: c120312253 ("e2scrub_all: make sure there's enough free space...")
Addresses-Debian-Bug: #935009
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Since e2scrub_all.cron is marked as a config file, it can hang around
after the package is removed, in which case e2scrub_all might not be
present. So check to make sure e2scrub_all exists before trying to
execute it.
Addresses-Debian-Bug: #932622
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Reported-by: Laurent Bigonville <bigon@debian.org>
By default, e2scrub_all will not actually trigger online scrubs unless
periodic_e2scrub=1 is set in /etc/e2scrub.conf.
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
The e2scrub_all program was broken by commit c7d6525eca
("e2scrub_all: refactor device probe loop") so that it would use the
path of the snapshot volume instead of the base volume. This caused
"e2scrub_all -r" to pass the wrong pathname to e2scrub, with the
result that e2scrub would abort with an error instead of removing the
snapshot volume.
Fixes: c7d6525eca ("e2scrub_all: refactor device probe loop")
Addresses-Debian-Bug: #931679
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
We handle the case where an LVM's PV is stacked on top of a dm-crypt
device, but not the case where it's the other way around, where a LVM
LV contains a LUKS encrypted file system. Fix this oversight.
Addresses-Debian-Bug: #931387
Reported-by: Marc Haber <mh+debian-bugs@zugschlus.de>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
We already have the "SERVICE_MODE=1" feature that signals to e2scrub
that we're running as a background daemon and therefore we should exit
quietly if conditions aren't right.
It's therefore unnecessary to have a separate -C flag to achieve the
same outcome for cron jobs. Merge the two together.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Running lsblk when there are no valid block devicse results in
generating all block devices as the list of devices to scrub; this
results in a lot of e2scrub_all failures.
Addresses-Debian-Bug: #929186
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
In scrub/Makefile the various 'install-*' targets do not explicitly
depend on their corresponding 'installdirs-*' target, so they get run
in parallel.
Addresses-Gentoo-Bug: #680030
Signed-off-by: Lars Wendler <polynomial-c@gentoo.org>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Paul Menzel reported that the e2scrub_all reaper service that runs at
startup takes a long time to run, and Ted Ts'o pointed out that we could
do a lot less work by using lvs as the outer loop in the ext4 filesystem
probe function so that we only have to lsblk the lvm devices containing
ext4 filesystems.
Therefore, refactor the loops to put lvs first, which should boost speed
a bit.
[ Made some of the further optimizations suggested by Lukas Czerner. -- TYT ]
Reported-by: Paul Menzel <pmenzel@molgen.mpg.de>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
If there isn't, skip the volume so we don't spam the system
administrator with error messages. It's quite commkon that there is
is zero free space in the volume group.
Addresses-Debian-Bug: #924301
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Not all systems will have the lvm2 package installed, so check for
that. Pretty much all systems should have util-linux installed, but
check for that as well.
Of course, if lvm2 is installed we shouldn't find any LVM devices ---
but eventually the Demon Murphy will find a way to make it happen. :-)
Also, set the PATH so we don't have to worry about the script failing
due to /sbin not being in the path.
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Apparently newer versions of systemd than the one on this author's
laptop <cough> now complain about lack of (path) escaping in unit
instance variable contents:
# e2scrub_all
Scrubbing /home...
Invalid unit name "e2scrub@/home" was escaped as "e2scrub@-home"
(maybe you should use systemd-escape?)
Starting Online ext4 Metadata Check for /home...
So change the escape_path_for_systemd function to escape paths
unconditionally to make the warning go away.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Fix the MKINSTALLDIRS -> MKDIR_P transition in the scrub/ dir.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Add the ability to run the e2scrub utilities as a periodically scheduled
system service.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Create an e2scrub_all command to find all ext* filesystems
and run an online scrub against them all.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Andreas Dilger <adilger@dilger.ca>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Implement online fsck for ext* filesystems which live on LVM-managed
logical volumes. The basic strategy mirrors that of e2croncheck --
create a snapshot, fsck the snapshot, report whatever errors appear,
remove snapshot. Unlike e2croncheck, this utility accepts any LVM
device path, knows about snapshots running out of space, and can call
fstrim having validated that the fs metadata is ok.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>