From patchwork Thu Dec 7 18:48:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Darrick Wong X-Patchwork-Id: 845770 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=oracle.com header.i=@oracle.com header.b="gL/k4Vlu"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yt4J60t45z9s82 for ; Fri, 8 Dec 2017 05:48:38 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750779AbdLGSsh (ORCPT ); Thu, 7 Dec 2017 13:48:37 -0500 Received: from aserp2120.oracle.com ([141.146.126.78]:57348 "EHLO aserp2120.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750828AbdLGSsg (ORCPT ); Thu, 7 Dec 2017 13:48:36 -0500 Received: from pps.filterd (aserp2120.oracle.com [127.0.0.1]) by aserp2120.oracle.com (8.16.0.21/8.16.0.21) with SMTP id vB7ImWj2058187; Thu, 7 Dec 2017 18:48:32 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=subject : from : to : cc : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=corp-2017-10-26; bh=idKvGHqsdbmhDXUVY91kRTXG1ePsVU2Qr4cnx65EGow=; b=gL/k4Vluj9Q0BOjS8ILXmz+PNYyf8PWwG26oo6KhiOsY+0Agkox4Mo32yFULIs4gqql/ e3eJfBng7t7xcSsYmZ0B4l7RVvpBjRrttRSoaege7Z6HLkUKF1TybsbA/RTCUc+BVVBp dED7Rzf71v8j4t8plmWXpiUB/Rs2Lx3sseQYeHTLSIqntYsHGwhqcM0alM1xwfztyVN7 yV8nDE85gVst+TBVxzUzbmSRHTL/jG6JK7pE9WF597KyeL5QWpc2abyCXxdb8uhVn55b CRlXqwTEHCDXScTZDftfCVFpr9kWTq/OXzWhJPZsLWv6Kh3CCD1QdcAyJtOILwOd/PqQ Sg== Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp2120.oracle.com with ESMTP id 2eqb8er00m-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 07 Dec 2017 18:48:32 +0000 Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0021.oracle.com (8.14.4/8.14.4) with ESMTP id vB7ImVNT026413 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 7 Dec 2017 18:48:32 GMT Received: from abhmp0016.oracle.com (abhmp0016.oracle.com [141.146.116.22]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id vB7ImVqB025969; Thu, 7 Dec 2017 18:48:31 GMT Received: from localhost (/67.169.218.210) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 07 Dec 2017 10:48:30 -0800 Subject: [PATCH 1/4] e2scrub: create online fsck tool of sorts From: "Darrick J. Wong" To: tytso@mit.edu, darrick.wong@oracle.com Cc: adilger@dilger.ca, linux-ext4@vger.kernel.org Date: Thu, 07 Dec 2017 10:48:29 -0800 Message-ID: <151267250988.1350.5015827346025680275.stgit@magnolia> In-Reply-To: <151267250365.1350.7799938074608034424.stgit@magnolia> References: <151267250365.1350.7799938074608034424.stgit@magnolia> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=8738 signatures=668644 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=29 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1711220000 definitions=main-1712070275 Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org From: Darrick J. Wong 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 --- MCONFIG.in | 3 + Makefile.in | 3 + configure | 21 +++++- configure.ac | 24 ++++++ debian/control.in | 2 - debian/e2fsprogs.files | 1 scrub/Makefile.in | 97 ++++++++++++++++++++++++++ scrub/e2scrub.8.in | 31 ++++++++ scrub/e2scrub.conf.in | 10 +++ scrub/e2scrub.in | 182 ++++++++++++++++++++++++++++++++++++++++++++++++ scrub/e2scrub.rules.in | 2 + util/subst.conf.in | 2 + 12 files changed, 374 insertions(+), 4 deletions(-) create mode 100644 scrub/Makefile.in create mode 100644 scrub/e2scrub.8.in create mode 100644 scrub/e2scrub.conf.in create mode 100644 scrub/e2scrub.in create mode 100644 scrub/e2scrub.rules.in diff --git a/MCONFIG.in b/MCONFIG.in index 22b74eb..a244728 100644 --- a/MCONFIG.in +++ b/MCONFIG.in @@ -33,6 +33,9 @@ infodir = @infodir@ datadir = @datadir@ pkgconfigdir = $(libdir)/pkgconfig +HAVE_UDEV = @have_udev@ +UDEVRULESDIR = @udevrulesdir@ + @SET_MAKE@ @ifGNUmake@ V = diff --git a/Makefile.in b/Makefile.in index 37b6069..ddd94ec 100644 --- a/Makefile.in +++ b/Makefile.in @@ -13,10 +13,11 @@ INSTALL = @INSTALL@ @DEBUGFS_CMT@DEBUGFS_DIR= debugfs @UUID_CMT@UUID_LIB_SUBDIR= lib/uuid @BLKID_CMT@BLKID_LIB_SUBDIR= lib/blkid +@E2SCRUB_CMT@E2SCRUB_DIR= scrub SUPPORT_LIB_SUBDIR= lib/support LIB_SUBDIRS=lib/et lib/ss lib/e2p $(UUID_LIB_SUBDIR) $(BLKID_LIB_SUBDIR) $(SUPPORT_LIB_SUBDIR) lib/ext2fs intl -PROG_SUBDIRS=e2fsck $(DEBUGFS_DIR) misc $(RESIZE_DIR) tests/progs po +PROG_SUBDIRS=e2fsck $(DEBUGFS_DIR) misc $(RESIZE_DIR) tests/progs po $(E2SCRUB_DIR) SUBDIRS=util $(LIB_SUBDIRS) $(PROG_SUBDIRS) tests SUBS= util/subst.conf lib/config.h $(top_builddir)/lib/dirpaths.h \ diff --git a/configure b/configure index b62da1b..c911469 100755 --- a/configure +++ b/configure @@ -625,6 +625,8 @@ gl_use_threads_default= ac_func_list= ac_subst_vars='LTLIBOBJS LIBOBJS +udevrulesdir +have_udev LDFLAGS_SHLIB CFLAGS_STLIB CFLAGS_SHLIB @@ -639,6 +641,7 @@ root_libdir root_sbindir root_bindir root_prefix +E2SCRUB_CMT UNIX_CMT CYGWIN_CMT LINUX_CMT @@ -13711,6 +13714,8 @@ esac +E2SCRUB_CMT="$LINUX_CMT" + case "$host_os" in linux* | gnu* | k*bsd*-gnu) if test "$prefix" = NONE -a "$root_prefix" = NONE ; then @@ -13876,6 +13881,20 @@ LDFLAGS_SHLIB=${LDFLAGS_SHLIB:-$LDFLAGS} + +pkg_udevrulesdir="$(pkg-config --variable=udevdir udev 2>/dev/null)/rules" +case "${pkg_udevrulesdir}" in +"") + udevrulesdir="" + have_udev=no + ;; +*) + udevrulesdir="${pkg_udevrulesdir}" + have_udev=yes + ;; +esac + + test -d lib || mkdir lib test -d include || mkdir include test -d include/linux || mkdir include/linux @@ -13897,7 +13916,7 @@ for i in MCONFIG Makefile e2fsprogs.spec \ misc/Makefile ext2ed/Makefile e2fsck/Makefile \ debugfs/Makefile tests/Makefile tests/progs/Makefile \ resize/Makefile doc/Makefile intl/Makefile \ - intl/libgnuintl.h po/Makefile.in ; do + intl/libgnuintl.h po/Makefile.in scrub/Makefile; do if test -d `dirname ${srcdir}/$i` ; then outlist="$outlist $i" fi diff --git a/configure.ac b/configure.ac index 4ec4617..ad2884d 100644 --- a/configure.ac +++ b/configure.ac @@ -1311,6 +1311,11 @@ AC_SUBST(LINUX_CMT) AC_SUBST(CYGWIN_CMT) AC_SUBST(UNIX_CMT) dnl +dnl e2scrub only builds on linux +dnl +E2SCRUB_CMT="$LINUX_CMT" +AC_SUBST(E2SCRUB_CMT) +dnl dnl Linux and Hurd places root files in the / by default dnl case "$host_os" in @@ -1468,6 +1473,23 @@ LDFLAGS_SHLIB=${LDFLAGS_SHLIB:-$LDFLAGS} AC_SUBST(CFLAGS_SHLIB) AC_SUBST(CFLAGS_STLIB) AC_SUBST(LDFLAGS_SHLIB) + +dnl +dnl Where do udev rules go? +dnl +pkg_udevrulesdir="$(pkg-config --variable=udevdir udev 2>/dev/null)/rules" +case "${pkg_udevrulesdir}" in +"") + udevrulesdir="" + have_udev=no + ;; +*) + udevrulesdir="${pkg_udevrulesdir}" + have_udev=yes + ;; +esac +AC_SUBST([have_udev]) +AC_SUBST([udevrulesdir]) dnl dnl Make our output files, being sure that we create the some miscellaneous dnl directories @@ -1493,7 +1515,7 @@ for i in MCONFIG Makefile e2fsprogs.spec \ misc/Makefile ext2ed/Makefile e2fsck/Makefile \ debugfs/Makefile tests/Makefile tests/progs/Makefile \ resize/Makefile doc/Makefile intl/Makefile \ - intl/libgnuintl.h po/Makefile.in ; do + intl/libgnuintl.h po/Makefile.in scrub/Makefile; do if test -d `dirname ${srcdir}/$i` ; then outlist="$outlist $i" fi diff --git a/debian/control.in b/debian/control.in index 89e8801..6efaef9 100644 --- a/debian/control.in +++ b/debian/control.in @@ -155,7 +155,7 @@ Essential: yes Pre-Depends: ${shlibs:Depends}, ${misc:Depends}, libblkid1, libuuid1 Multi-Arch: foreign Suggests: gpart, parted, fuse2fs, e2fsck-static -Recommends: e2fsprogs-l10n +Recommends: e2fsprogs-l10n, lvm2, util-linux, coreutils Architecture: any Description: ext2/ext3/ext4 file system utilities The ext2, ext3 and ext4 file systems are successors of the original ext diff --git a/debian/e2fsprogs.files b/debian/e2fsprogs.files index 37e54da..7dd64ac 100644 --- a/debian/e2fsprogs.files +++ b/debian/e2fsprogs.files @@ -4,3 +4,4 @@ usr/sbin usr/share/man usr/share/locale etc +lib/udev/rules diff --git a/scrub/Makefile.in b/scrub/Makefile.in new file mode 100644 index 0000000..1f3253d --- /dev/null +++ b/scrub/Makefile.in @@ -0,0 +1,97 @@ +# +# Makefile for e2scrub +# + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +top_builddir = .. +my_dir = scrub +INSTALL = @INSTALL@ + +@MCONFIG@ + +PROGS= e2scrub +MANPAGES= e2scrub.8 +CONFFILES= e2scrub.conf + +ifeq ($(HAVE_UDEV),yes) +UDEVRULES = e2scrub.rules +INSTALLDIRS_TGT += installdirs-udev +INSTALL_TGT += install-udev +UNINSTALL_TGT += uninstall-udev +endif + +all:: $(PROGS) $(MANPAGES) $(CONFFILES) $(UDEVRULES) + +e2scrub: $(DEP_SUBSTITUTE) e2scrub.in + $(E) " SUBST $@" + $(Q) $(SUBSTITUTE_UPTIME) $(srcdir)/e2scrub.in $@ + $(Q) chmod a+x $@ + +%.8: %.8.in $(DEP_SUBSTITUTE) + $(E) " SUBST $@" + $(Q) $(SUBSTITUTE_UPTIME) $< $@ + +%.conf: %.conf.in $(DEP_SUBSTITUTE) + $(E) " SUBST $@" + $(Q) $(SUBSTITUTE_UPTIME) $< $@ + +%.rules: %.rules.in $(DEP_SUBSTITUTE) + $(E) " SUBST $@" + $(Q) $(SUBSTITUTE_UPTIME) $< $@ + +installdirs-udev: + $(E) " MKINSTALLDIRS $(udevdir)" + $(Q) $(MKINSTALLDIRS) $(DESTDIR)$(UDEVRULESDIR) + +installdirs: $(INSTALLDIRS_TGT) + $(E) " MKINSTALLDIRS $(root_sbindir) $(man8dir) $(root_sysconfdir)" + $(Q) $(MKINSTALLDIRS) $(DESTDIR)$(root_sbindir) \ + $(DESTDIR)$(man8dir) $(DESTDIR)$(root_sysconfdir) + +install-udev: + $(Q) for i in $(UDEVRULES); do \ + $(ES) " INSTALL $(UDEVRULESDIR)/$$i"; \ + $(INSTALL_PROGRAM) $$i $(DESTDIR)$(UDEVRULESDIR)/96-$$i; \ + done + +install: $(PROGS) $(MANPAGES) $(FMANPAGES) installdirs $(INSTALL_TGT) + $(Q) for i in $(PROGS); do \ + $(ES) " INSTALL $(root_sbindir)/$$i"; \ + $(INSTALL_PROGRAM) $$i $(DESTDIR)$(root_sbindir)/$$i; \ + done + $(Q) for i in $(MANPAGES); do \ + for j in $(COMPRESS_EXT); do \ + $(RM) -f $(DESTDIR)$(man8dir)/$$i.$$j; \ + done; \ + $(ES) " INSTALL_DATA $(man8dir)/$$i"; \ + $(INSTALL_DATA) $$i $(DESTDIR)$(man8dir)/$$i; \ + done + $(Q) for i in $(CONFFILES); do \ + $(ES) " INSTALL_DATA $(root_sysconfdir)/$$i"; \ + $(INSTALL_DATA) $$i $(DESTDIR)$(root_sysconfdir)/$$i; \ + done + +uninstall-udev: + for i in $(UDEVRULES); do \ + $(RM) -f $(DESTDIR)$(UDEVRULESDIR)/$$i; \ + done + +uninstall: $(UNINSTALL_TGT) + for i in $(PROGS); do \ + $(RM) -f $(DESTDIR)$(root_sbindir)/$$i; \ + done + for i in $(MANPAGES); do \ + $(RM) -f $(DESTDIR)$(man8dir)/$$i; \ + done + for i in $(CONFFILES); do \ + $(RM) -f $(DESTDIR)$(root_sysconfdir)/$$i; \ + done + +clean:: + $(RM) -f $(PROGS) + +mostlyclean: clean +distclean: clean + $(RM) -f .depend Makefile $(srcdir)/TAGS $(srcdir)/Makefile.in.old diff --git a/scrub/e2scrub.8.in b/scrub/e2scrub.8.in new file mode 100644 index 0000000..e3d037b --- /dev/null +++ b/scrub/e2scrub.8.in @@ -0,0 +1,31 @@ +.TH E2SCRUB 8 "@E2FSPROGS_MONTH@ @E2FSPROGS_YEAR@" "E2fsprogs version @E2FSPROGS_VERSION@" +.SH NAME +e2scrub - check a mounted ext2/ext3/ext4 file system on an LVM volume for errors. +.SH SYNOPSYS +.B +e2scrub [OPTION] [LVM DEVICE PATH] +.SH DESCRIPTION +Given a live file system on a LVM volume, this program snapshots the +logical volume and runs a file system check to look for serious errors. +If no errors are found, fstrim can be called on the mounted file system. +However, if errors are found, the file system should be unmounted and +fixed. +.SH OPTIONS +.TP +\fB-t\fR +Run +.B +fstrim(1) +on the mounted filesystem if no errors are found. +.SH EXIT CODE +The exit codes are the same as in +.BR e2fsck (8) +.SH BUGS +This utility is capable of checking any ext* filesystem on an LVM volume, +regardless of whether it is mounted. +.SH SEE ALSO +.BR e2fsck (8) +.SH AUTHOR +Darrick J. Wong +.SH COPYRIGHT +Copyright ©2017 Darrick J. Wong. License is GPLv2+. diff --git a/scrub/e2scrub.conf.in b/scrub/e2scrub.conf.in new file mode 100644 index 0000000..fec828a --- /dev/null +++ b/scrub/e2scrub.conf.in @@ -0,0 +1,10 @@ +# e2scrub configuration file + +# Snapshots will be created to run fsck; the snapshot will be of this size. +# snap_size_mb=256 + +# Set this to 1 to enable fstrim for everyone +# fstrim=0 + +# Arguments passed into e2fsck +# e2fsck_opts="-vtt" diff --git a/scrub/e2scrub.in b/scrub/e2scrub.in new file mode 100644 index 0000000..75e0639 --- /dev/null +++ b/scrub/e2scrub.in @@ -0,0 +1,182 @@ +#!/bin/bash + +# Copyright (C) 2017 Oracle. All Rights Reserved. +# +# Author: Darrick J. Wong +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +# Automatically check a LVM-managed filesystem online. +# We use lvm snapshots to do this, which means that we can only +# check filesystems in VGs that have at least 256mb (or so) of +# free space. + +snap_size_mb=256 +fstrim=0 +e2fsck_opts="" +conffile="@root_sysconfdir@/e2scrub.conf" + +test -f "${conffile}" && . "${conffile}" + +print_help() { + echo "Usage: $0 [-t] device" + echo + echo "device must be a LVM-managed block device" + echo "-t: Run fstrim if successful." +} + +exitcode() { + ret="$1" + + exit "${ret}" +} + +prog_path() { + path="$1" + displayname="$2" + + if ! type -P "${path}" && [ -n "${displayname}" ]; then + echo "${displayname}: Command not found." + exitcode 8 + fi +} + +LVS_PROG="$(prog_path "@root_sbindir@/lvs" "lvs")" +BLKID_PROG="$(prog_path "@root_sbindir@/blkid" "blkid")" +LVCREATE_PROG="$(prog_path "@root_sbindir@/lvcreate" "lvcreate")" +LVREMOVE_PROG="$(prog_path "@root_sbindir@/lvremove" "lvremove")" +FSTRIM_PROG="$(prog_path "@root_sbindir@/fstrim")" +UDEVADM_PROG="$(prog_path "@root_sbindir@/udevadm")" +SLEEP_PROG="$(prog_path "@root_bindir@/sleep")" + +while getopts "t" opt; do + case "${opt}" in + "t") fstrim=1;; + *) print_help; exitcode 2;; + esac +done +shift "$((OPTIND - 1))" + +dev="$1" +if [ -z "${dev}" ]; then + print_help + exitcode 1 +elif [ ! -b "${dev}" ]; then + echo "${dev}: Not a block device?" + print_help + exitcode 16 +fi + +# Make sure this is an LVM device we can snapshot +vg="$("${LVS_PROG}" --noheadings -o vg_name "${dev}" 2> /dev/null | sed -e 's/^ //g')" +lv="$("${LVS_PROG}" --noheadings -o lv_name "${dev}" 2> /dev/null | sed -e 's/^ //g')" +if [ -z "${vg}" ] || [ -z "${lv}" ]; then + echo "${dev}: Not a LVM device." + exitcode 16 +fi +start_time="$(date +'%Y%m%d%H%M%S')" +snap="${lv}.e2scrub" +snap_dev="/dev/${vg}/${snap}" +fstype="$("${BLKID_PROG}" -p -s TYPE "${dev}" | sed -e 's/^.*TYPE="\(.*\)".*$/\1/g')" + +case "${fstype}" in +"ext2"|"ext3"|"ext4") + ;; +*) + echo "${dev}: Filesystem of type ${fstype} not supported." + exitcode 16 + ;; +esac + +teardown() { + # Remove and wait for removal to succeed. + "${LVREMOVE_PROG}" -f "${vg}/${snap}" 3>&- + while [ -b "${snap_dev}" ] && [ "$?" -eq "5" ]; do + /bin/sleep 0.5 + "${LVREMOVE_PROG}" -f "${vg}/${snap}" 3>&- + done +} + +check() { + # First we preen the filesystem to recover the journal, then + # we see if e2fsck tries any non-optimization repairs. If + # either of these two returns a non-zero status (errors fixed + # or remaining) then this fs is bad. + E2FSCK_FIXES_ONLY=1 + export E2FSCK_FIXES_ONLY + ${DBG} "@root_sbindir@/e2fsck" -p ${e2fsck_opts} "${snap_dev}" || return 1 + ${DBG} "@root_sbindir@/e2fsck" -fy ${e2fsck_opts} "${snap_dev}" || return 1 + return 0 +} + +mark_clean() { + ${DBG} "@root_sbindir@/tune2fs" -C 0 -T "${start_time}" "${dev}" +} + +mark_corrupt() { + ${DBG} "@root_sbindir@/tune2fs" -C 16000 -T "19000101" "${dev}" +} + +setup() { + # Create the snapshot, wait for device to appear + teardown > /dev/null 2> /dev/null + "${LVCREATE_PROG}" -s -L "${snap_size_mb}m" -n "${snap}" "${vg}/${lv}" 3>&- + test $? -ne 0 && return 1 + test -x "${UDEVADM_PROG}" && "${UDEVADM_PROG}" settle + return 0 +} + +trap "teardown" EXIT INT QUIT TERM +if ! setup; then + echo "Snapshot of ${dev} FAILED, will not check!" + exitcode 1 +fi + +# Check and react +if check; then + echo "Scrub of ${dev} succeeded." + mark_clean + + if [ "${fstrim}" -eq 1 ] && [ -x "${FSTRIM_PROG}" ]; then + dir="$(lsblk -o MOUNTPOINT -n "${dev}")" + if [ -d "${dir}" ]; then + # NB: fstrim fails with snapshot present + trap '' EXIT + teardown + "${FSTRIM_PROG}" -v "${dir}" + fi + fi + + ret=0 +else + # fsck failed. Check if the snapshot is invalid; if so, make a + # note of that at the end of the log. This isn't necessarily a + # failure because the mounted fs could have overflowed the + # snapshot with regular disk writes /or/ our repair process + # could have done it by repairing too much. + # + # If it's really corrupt we ought to fsck at next boot. + is_invalid="$("${LVS_PROG}" -o lv_snapshot_invalid --noheadings "${snapdev}")" + if [ -n "${is_invalid}" ]; then + echo "Scrub of ${dev} FAILED due to invalid snapshot." + ret=8 + else + echo "Scrub of ${dev} FAILED! Reboot soon to fsck." + mark_corrupt + ret=6 + fi +fi + +exitcode "${ret}" diff --git a/scrub/e2scrub.rules.in b/scrub/e2scrub.rules.in new file mode 100644 index 0000000..5e1b35b --- /dev/null +++ b/scrub/e2scrub.rules.in @@ -0,0 +1,2 @@ +# Try to hide our fsck snapshots from udev's /dev/disk linking... +ACTION=="add|change", ENV{DM_LV_NAME}=="*.e2scrub", OPTIONS="link_priority=-100" diff --git a/util/subst.conf.in b/util/subst.conf.in index fbc044d..effac78 100644 --- a/util/subst.conf.in +++ b/util/subst.conf.in @@ -18,3 +18,5 @@ $prefix @prefix@ JDEV # Enable the documentation for the tdb profile in e2fsck.conf's man page TDB_MAN_COMMENT @TDB_MAN_COMMENT@ +root_sbindir @root_sbindir@ +root_bindir @root_bindir@ From patchwork Thu Dec 7 18:48:36 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Darrick Wong X-Patchwork-Id: 845771 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=oracle.com header.i=@oracle.com header.b="IsVjCy8D"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yt4JB45C6z9s82 for ; Fri, 8 Dec 2017 05:48:42 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750967AbdLGSsm (ORCPT ); Thu, 7 Dec 2017 13:48:42 -0500 Received: from aserp2120.oracle.com ([141.146.126.78]:57482 "EHLO aserp2120.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750828AbdLGSsl (ORCPT ); Thu, 7 Dec 2017 13:48:41 -0500 Received: from pps.filterd (aserp2120.oracle.com [127.0.0.1]) by aserp2120.oracle.com (8.16.0.21/8.16.0.21) with SMTP id vB7ImSSL058123; Thu, 7 Dec 2017 18:48:38 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=subject : from : to : cc : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=corp-2017-10-26; bh=o41eiBwMNNcya32Pfpj/RVhvoH8Q1LepbcV8x2eS0XQ=; b=IsVjCy8DlcnYCN+PgZ821GDAus0SGx/mofyRGPcUPd599gXHJObEnwim45MSXf7LjiWX xKH9Cipm1gi8eWuAg9D0jAW5k+/lHBr+NBIToxdPwn32EJ/+R5QGi1ITuRPcm+cmMVpA y/C5aHOMs2AcT+wULneGPpUuRTimWg4kk7QcvaJg6kcZZjOJfAufq/frqwvF14B2Y0kZ /j1Rf46Gt551auF7kGu7FWUR+9ezn1YxznlO2aVjaYjPHowX9vyAZ41Hz1AddMTxk8Hy gYJe+tu+9FOS0+z0Kc12UAmnHht+1d9h3xfjsUKOEh6wfIABbN0aYS0Jm8KGdjtSVBG0 KQ== Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp2120.oracle.com with ESMTP id 2eqb8er01j-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 07 Dec 2017 18:48:38 +0000 Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.14.4/8.14.4) with ESMTP id vB7Imb34028268 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 7 Dec 2017 18:48:37 GMT Received: from abhmp0017.oracle.com (abhmp0017.oracle.com [141.146.116.23]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id vB7Imb8U000455; Thu, 7 Dec 2017 18:48:37 GMT Received: from localhost (/67.169.218.210) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 07 Dec 2017 10:48:37 -0800 Subject: [PATCH 2/4] e2scrub: create a script to scrub all ext* filesystems From: "Darrick J. Wong" To: tytso@mit.edu, darrick.wong@oracle.com Cc: adilger@dilger.ca, linux-ext4@vger.kernel.org Date: Thu, 07 Dec 2017 10:48:36 -0800 Message-ID: <151267251622.1350.5012077999744307213.stgit@magnolia> In-Reply-To: <151267250365.1350.7799938074608034424.stgit@magnolia> References: <151267250365.1350.7799938074608034424.stgit@magnolia> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=8738 signatures=668644 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=9 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1711220000 definitions=main-1712070275 Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org From: Darrick J. Wong Create an e2scrub_all command to find all ext* filesystems and run an online scrub against them all. Signed-off-by: Darrick J. Wong --- scrub/Makefile.in | 9 +++++++- scrub/e2scrub_all.8.in | 14 +++++++++++++ scrub/e2scrub_all.in | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 scrub/e2scrub_all.8.in create mode 100644 scrub/e2scrub_all.in diff --git a/scrub/Makefile.in b/scrub/Makefile.in index 1f3253d..ce8c85f 100644 --- a/scrub/Makefile.in +++ b/scrub/Makefile.in @@ -11,8 +11,8 @@ INSTALL = @INSTALL@ @MCONFIG@ -PROGS= e2scrub -MANPAGES= e2scrub.8 +PROGS= e2scrub e2scrub_all +MANPAGES= e2scrub.8 e2scrub_all.8 CONFFILES= e2scrub.conf ifeq ($(HAVE_UDEV),yes) @@ -29,6 +29,11 @@ e2scrub: $(DEP_SUBSTITUTE) e2scrub.in $(Q) $(SUBSTITUTE_UPTIME) $(srcdir)/e2scrub.in $@ $(Q) chmod a+x $@ +e2scrub_all: e2scrub_all.in + $(E) " SUBST $@" + $(Q) $(SUBSTITUTE_UPTIME) $(srcdir)/e2scrub_all.in $@ + $(Q) chmod a+x $@ + %.8: %.8.in $(DEP_SUBSTITUTE) $(E) " SUBST $@" $(Q) $(SUBSTITUTE_UPTIME) $< $@ diff --git a/scrub/e2scrub_all.8.in b/scrub/e2scrub_all.8.in new file mode 100644 index 0000000..b05f13c --- /dev/null +++ b/scrub/e2scrub_all.8.in @@ -0,0 +1,14 @@ +.TH E2SCRUB 8 "@E2FSPROGS_MONTH@ @E2FSPROGS_YEAR@" "E2fsprogs version @E2FSPROGS_VERSION@" +.SH NAME +e2scrub_all - Check all mounted btrfs/ext4/XFS LVM file systems for errors. +.SH SYNOPSYS +.B +e2scrub_all +.SH DESCRIPTION +Searches the system for all LVM volumes containing an ext2, ext3, or +ext4 file system, and checks them all for errors. +If the file system has no errors, it will be fstrim'd. +.SH AUTHOR +Darrick J. Wong +.SH COPYRIGHT +Copyright ©2017 Darrick J. Wong. License is GPLv2+. diff --git a/scrub/e2scrub_all.in b/scrub/e2scrub_all.in new file mode 100644 index 0000000..a9ba670 --- /dev/null +++ b/scrub/e2scrub_all.in @@ -0,0 +1,51 @@ +#!/bin/bash + +# Copyright (C) 2017 Oracle. All Rights Reserved. +# +# Author: Darrick J. Wong +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +# Check all ext[234] filesystems mounted on LVM +types="ext2,ext3,ext4" + +exitcode() { + ret="$1" + + exit "${ret}" +} + +prog_path() { + path="$1" + displayname="$2" + + if ! type -P "${path}" && [ -n "${displayname}" ]; then + echo "${displayname}: Command not found." + exitcode 8 + fi +} + +LVS_PROG="$(prog_path "@root_sbindir@/lvs" "lvs")" +BLKID_PROG="$(prog_path "@root_sbindir@/blkid" "blkid")" + +# Scrub any fs on lvm by creating a snapshot and fscking that. +"${LVS_PROG}" -o vg_name,lv_name --noheadings 2> /dev/null | while read vg lv; do + dev="/dev/${vg}/${lv}" + "${BLKID_PROG}" -p -n "${types}" "${dev}" > /dev/null 2>&1 || continue + + ${DBG} "@root_sbindir@/e2scrub" "${dev}" +done + +exitcode 0 From patchwork Thu Dec 7 18:48:42 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Darrick Wong X-Patchwork-Id: 845772 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=oracle.com header.i=@oracle.com header.b="KSZC1gPx"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yt4JL1fF1z9s9Y for ; Fri, 8 Dec 2017 05:48:50 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751002AbdLGSst (ORCPT ); Thu, 7 Dec 2017 13:48:49 -0500 Received: from aserp2130.oracle.com ([141.146.126.79]:59768 "EHLO aserp2130.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750986AbdLGSss (ORCPT ); Thu, 7 Dec 2017 13:48:48 -0500 Received: from pps.filterd (aserp2130.oracle.com [127.0.0.1]) by aserp2130.oracle.com (8.16.0.21/8.16.0.21) with SMTP id vB7ImiSU084798; Thu, 7 Dec 2017 18:48:45 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=subject : from : to : cc : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=corp-2017-10-26; bh=wmYjbO/P1q8EoO0y1TMcUhdDIrD9idCbpy+pFrXGDa8=; b=KSZC1gPx89IY/qaVhboAGl2IYoKKgXuRLAYrgdXbEpkTGLoNX3h+tFEZvcPeJQR8Ic93 hrsY0vk6k3FMfJv5j3CHGoBKSShsH+hTK5FgI4J+bF1dEaoD3skEkBQ+khVjyhfMLhYj bmgyGnsJCPtXHcgKU93EXUiX9kJIEFzlywTomEUff9YZIWydGdyUZ0CKJEXVqlkI/A68 76MrGC3XRuC1c5SMZCgqUlO4fCCLsFPwa2FGdZvsvPFdMgDtwLTo7mpxJrf9sSldgJ6H 7BJ75O5VCOszL6tB2eGacOzDvOvFVYyOiT9eUZgz1R89yYU/AYFY9Oc5T2EilITecnHD 7Q== Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp2130.oracle.com with ESMTP id 2eqb8j8005-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 07 Dec 2017 18:48:45 +0000 Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.14.4/8.14.4) with ESMTP id vB7ImieU028590 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 7 Dec 2017 18:48:44 GMT Received: from abhmp0015.oracle.com (abhmp0015.oracle.com [141.146.116.21]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id vB7Imhan000494; Thu, 7 Dec 2017 18:48:43 GMT Received: from localhost (/67.169.218.210) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 07 Dec 2017 10:48:43 -0800 Subject: [PATCH 3/4] e2scrub: add service (cron, systemd) support From: "Darrick J. Wong" To: tytso@mit.edu, darrick.wong@oracle.com Cc: adilger@dilger.ca, linux-ext4@vger.kernel.org Date: Thu, 07 Dec 2017 10:48:42 -0800 Message-ID: <151267252240.1350.14080940928827658377.stgit@magnolia> In-Reply-To: <151267250365.1350.7799938074608034424.stgit@magnolia> References: <151267250365.1350.7799938074608034424.stgit@magnolia> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=8738 signatures=668644 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=9 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1711220000 definitions=main-1712070275 Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org From: Darrick J. Wong Add the ability to run the e2scrub utilities as a periodically scheduled system service. Signed-off-by: Darrick J. Wong --- MCONFIG.in | 4 ++ configure | 24 +++++++++++++++ configure.ac | 28 ++++++++++++++++- debian/e2fsprogs.files | 2 + debian/e2fsprogs.postinst | 19 ++++++++++++ scrub/Makefile.in | 66 ++++++++++++++++++++++++++++++++++++++-- scrub/e2scrub.in | 12 +++++++ scrub/e2scrub@.service.in | 18 +++++++++++ scrub/e2scrub_all.cron.in | 2 + scrub/e2scrub_all.in | 24 ++++++++++++++- scrub/e2scrub_all.service.in | 8 +++++ scrub/e2scrub_all.timer.in | 11 +++++++ scrub/e2scrub_fail.in | 26 ++++++++++++++++ scrub/e2scrub_fail@.service.in | 10 ++++++ util/subst.conf.in | 2 + 15 files changed, 250 insertions(+), 6 deletions(-) create mode 100644 scrub/e2scrub@.service.in create mode 100644 scrub/e2scrub_all.cron.in create mode 100644 scrub/e2scrub_all.service.in create mode 100644 scrub/e2scrub_all.timer.in create mode 100644 scrub/e2scrub_fail.in create mode 100644 scrub/e2scrub_fail@.service.in diff --git a/MCONFIG.in b/MCONFIG.in index a244728..aa7d0d1 100644 --- a/MCONFIG.in +++ b/MCONFIG.in @@ -23,6 +23,7 @@ libdir = @libdir@ datadir= @datadir@ localedir = $(datadir)/locale root_sysconfdir= @root_sysconfdir@ +root_crondir= @root_crondir@ includedir = @includedir@ mandir = @mandir@ man1dir = $(mandir)/man1 @@ -32,6 +33,9 @@ man8dir = $(mandir)/man8 infodir = @infodir@ datadir = @datadir@ pkgconfigdir = $(libdir)/pkgconfig +pkglibdir = @pkglibdir@ +HAVE_SYSTEMD= @have_systemd@ +SYSTEMDSYSTEMUNITDIR= @systemdsystemunitdir@ HAVE_UDEV = @have_udev@ UDEVRULESDIR = @udevrulesdir@ diff --git a/configure b/configure index c911469..cca0c23 100755 --- a/configure +++ b/configure @@ -625,6 +625,8 @@ gl_use_threads_default= ac_func_list= ac_subst_vars='LTLIBOBJS LIBOBJS +systemdsystemunitdir +have_systemd udevrulesdir have_udev LDFLAGS_SHLIB @@ -636,6 +638,8 @@ MKINSTALLDIRS INCLUDES DO_TEST_SUITE LDFLAGS_STATIC +pkglibdir +root_crondir root_sysconfdir root_libdir root_sbindir @@ -13749,11 +13753,13 @@ if test "$root_prefix" = NONE ; then root_sbindir=$sbindir root_libdir=$libdir root_sysconfdir=$sysconfdir + root_crondir=$sysconfdir/cron.d else root_bindir='${root_prefix}/bin' root_sbindir='${root_prefix}/sbin' root_libdir='${root_prefix}/lib' root_sysconfdir='${root_prefix}/etc' + root_crondir='${root_sysconfdir}/cron.d' fi if test "$bindir" != '${exec_prefix}/bin'; then root_bindir=$bindir @@ -13781,6 +13787,7 @@ fi + # Check whether --with-multiarch was given. if test "${with_multiarch+set}" = set; then : withval=$with_multiarch; if test "$withval" = "lib64"; then @@ -13792,6 +13799,9 @@ else fi fi + +pkglibdir=$libdir/e2fsprogs + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we can link with -static" >&5 $as_echo_n "checking whether we can link with -static... " >&6; } if ${ac_cv_e2fsprogs_use_static+:} false; then : @@ -13895,6 +13905,20 @@ case "${pkg_udevrulesdir}" in esac +pkg_systemdsystemunitdir="$(pkg-config --variable=systemdsystemunitdir systemd 2>/dev/null)" +case "${pkg_systemdsystemunitdir}" in +"") + systemdsystemunitdir="" + have_systemd=no + ;; +*) + systemdsystemunitdir="${pkg_systemdsystemunitdir}" + have_systemd=yes + ;; +esac + + + test -d lib || mkdir lib test -d include || mkdir include test -d include/linux || mkdir include/linux diff --git a/configure.ac b/configure.ac index ad2884d..28172bd 100644 --- a/configure.ac +++ b/configure.ac @@ -1351,11 +1351,13 @@ if test "$root_prefix" = NONE ; then root_sbindir=$sbindir root_libdir=$libdir root_sysconfdir=$sysconfdir + root_crondir=$sysconfdir/cron.d else root_bindir='${root_prefix}/bin' root_sbindir='${root_prefix}/sbin' root_libdir='${root_prefix}/lib' root_sysconfdir='${root_prefix}/etc' + root_crondir='${root_sysconfdir}/cron.d' fi if test "$bindir" != '${exec_prefix}/bin'; then root_bindir=$bindir @@ -1378,6 +1380,7 @@ AC_SUBST(root_bindir) AC_SUBST(root_sbindir) AC_SUBST(root_libdir) AC_SUBST(root_sysconfdir) +AC_SUBST(root_crondir) dnl dnl Allow specification of the multiarch arch dnl @@ -1390,7 +1393,13 @@ else libdir=$libdir/$withval root_libdir=$root_libdir/$withval fi -)dnl +) +dnl +dnl define pkglibdir for /usr/lib/e2fsprogs +dnl +pkglibdir=$libdir/e2fsprogs +AC_SUBST(pkglibdir) +dnl dnl dnl See if -static works. This could fail if the linker does not dnl support -static, or if required external libraries are not available @@ -1491,6 +1500,23 @@ esac AC_SUBST([have_udev]) AC_SUBST([udevrulesdir]) dnl +dnl Where do systemd services go? +dnl +pkg_systemdsystemunitdir="$(pkg-config --variable=systemdsystemunitdir systemd 2>/dev/null)" +case "${pkg_systemdsystemunitdir}" in +"") + systemdsystemunitdir="" + have_systemd=no + ;; +*) + systemdsystemunitdir="${pkg_systemdsystemunitdir}" + have_systemd=yes + ;; +esac +AC_SUBST([have_systemd]) +AC_SUBST([systemdsystemunitdir]) + +dnl dnl Make our output files, being sure that we create the some miscellaneous dnl directories dnl diff --git a/debian/e2fsprogs.files b/debian/e2fsprogs.files index 7dd64ac..677367c 100644 --- a/debian/e2fsprogs.files +++ b/debian/e2fsprogs.files @@ -1,7 +1,9 @@ sbin usr/bin +usr/lib usr/sbin usr/share/man usr/share/locale etc +lib/systemd/system lib/udev/rules diff --git a/debian/e2fsprogs.postinst b/debian/e2fsprogs.postinst index 00ac363..fceda61 100644 --- a/debian/e2fsprogs.postinst +++ b/debian/e2fsprogs.postinst @@ -10,4 +10,23 @@ fi #DEBHELPER# +# debhelper doesn't know what timers are... +deb-systemd-helper unmask e2scrub_all.timer >/dev/null || true + +if deb-systemd-helper --quiet was-enabled e2scrub_all.timer; then + # Enables the unit on first installation, creates new + # symlinks on upgrades if the unit file has changed. + deb-systemd-helper enable e2scrub_all.timer >/dev/null || true +else + # Update the statefile to add new symlinks (if any), which need to be + # cleaned up on purge. Also remove old symlinks. + deb-systemd-helper update-state e2scrub_all.timer >/dev/null || true +fi + +# Start our new services +if [ -d /run/systemd/system ]; then + systemctl --system daemon-reload >/dev/null || true + deb-systemd-invoke start e2scrub_all.timer >/dev/null || true +fi + exit 0 diff --git a/scrub/Makefile.in b/scrub/Makefile.in index ce8c85f..65ecc8c 100644 --- a/scrub/Makefile.in +++ b/scrub/Makefile.in @@ -22,7 +22,18 @@ INSTALL_TGT += install-udev UNINSTALL_TGT += uninstall-udev endif -all:: $(PROGS) $(MANPAGES) $(CONFFILES) $(UDEVRULES) +CRONTABS= e2scrub_all.cron + +ifeq ($(HAVE_SYSTEMD),yes) +INSTALLDIRS_TGT += installdirs-systemd +INSTALL_TGT += install-systemd +UNINSTALL_TGT += uninstall-systemd +LIBPROGS += e2scrub_fail +SERVICE_FILES = e2scrub@.service e2scrub_all.service e2scrub_all.timer e2scrub_fail@.service +SYSTEMD_DIRS = $(DESTDIR)/$(pkglibdir) $(DESTDIR)$(SYSTEMDSYSTEMUNITDIR) +endif + +all:: $(PROGS) $(MANPAGES) $(CONFFILES) $(UDEVRULES) $(SERVICE_FILES) $(CRONTABS) $(LIBPROGS) e2scrub: $(DEP_SUBSTITUTE) e2scrub.in $(E) " SUBST $@" @@ -34,6 +45,11 @@ e2scrub_all: e2scrub_all.in $(Q) $(SUBSTITUTE_UPTIME) $(srcdir)/e2scrub_all.in $@ $(Q) chmod a+x $@ +e2scrub_fail: e2scrub_fail.in + $(E) " SUBST $@" + $(Q) $(SUBSTITUTE_UPTIME) $(srcdir)/e2scrub_fail.in $@ + $(Q) chmod a+x $@ + %.8: %.8.in $(DEP_SUBSTITUTE) $(E) " SUBST $@" $(Q) $(SUBSTITUTE_UPTIME) $< $@ @@ -46,14 +62,31 @@ e2scrub_all: e2scrub_all.in $(E) " SUBST $@" $(Q) $(SUBSTITUTE_UPTIME) $< $@ +%.service: %.service.in $(DEP_SUBSTITUTE) + $(E) " SUBST $@" + $(Q) $(SUBSTITUTE_UPTIME) $< $@ + +%.cron: %.cron.in $(DEP_SUBSTITUTE) + $(E) " SUBST $@" + $(Q) $(SUBSTITUTE_UPTIME) $< $@ + +%.timer: %.timer.in $(DEP_SUBSTITUTE) + $(E) " SUBST $@" + $(Q) $(SUBSTITUTE_UPTIME) $< $@ + installdirs-udev: $(E) " MKINSTALLDIRS $(udevdir)" $(Q) $(MKINSTALLDIRS) $(DESTDIR)$(UDEVRULESDIR) +installdirs-systemd: + $(E) " MKINSTALLDIRS $(SYSTEMD_DIRS) $(pkglibdir)" + $(Q) $(MKINSTALLDIRS) $(DESTDIR)$(SYSTEMD_DIRS) $(DESTDIR)$(pkglibdir) + installdirs: $(INSTALLDIRS_TGT) - $(E) " MKINSTALLDIRS $(root_sbindir) $(man8dir) $(root_sysconfdir)" + $(E) " MKINSTALLDIRS $(root_sbindir) $(man8dir) $(root_sysconfdir) $(root_crondir)" $(Q) $(MKINSTALLDIRS) $(DESTDIR)$(root_sbindir) \ - $(DESTDIR)$(man8dir) $(DESTDIR)$(root_sysconfdir) + $(DESTDIR)$(man8dir) $(DESTDIR)$(root_sysconfdir) \ + $(DESTDIR)$(root_crondir) install-udev: $(Q) for i in $(UDEVRULES); do \ @@ -61,7 +94,17 @@ install-udev: $(INSTALL_PROGRAM) $$i $(DESTDIR)$(UDEVRULESDIR)/96-$$i; \ done -install: $(PROGS) $(MANPAGES) $(FMANPAGES) installdirs $(INSTALL_TGT) +install-systemd: $(SERVICE_FILES) + $(Q) for i in $(SERVICE_FILES); do \ + $(ES) " INSTALL_DATA $(SYSTEMDSYSTEMUNITDIR)/$$i"; \ + $(INSTALL_DATA) $$i $(DESTDIR)$(SYSTEMDSYSTEMUNITDIR)/$$i; \ + done + $(Q) for i in $(LIBPROGS); do \ + $(ES) " INSTALL $(pkglibdir)/$$i"; \ + $(INSTALL_PROGRAM) $$i $(DESTDIR)$(pkglibdir)/$$i; \ + done + +install: $(PROGS) $(MANPAGES) $(FMANPAGES) installdirs $(INSTALL_TGT) $(CRONTABS) $(Q) for i in $(PROGS); do \ $(ES) " INSTALL $(root_sbindir)/$$i"; \ $(INSTALL_PROGRAM) $$i $(DESTDIR)$(root_sbindir)/$$i; \ @@ -77,12 +120,24 @@ install: $(PROGS) $(MANPAGES) $(FMANPAGES) installdirs $(INSTALL_TGT) $(ES) " INSTALL_DATA $(root_sysconfdir)/$$i"; \ $(INSTALL_DATA) $$i $(DESTDIR)$(root_sysconfdir)/$$i; \ done + $(Q) for i in $(CRONTABS); do \ + $(ES) " INSTALL_DATA $(root_crondir)/$$i"; \ + $(INSTALL_DATA) $$i $(DESTDIR)$(root_crondir)/$$i; \ + done uninstall-udev: for i in $(UDEVRULES); do \ $(RM) -f $(DESTDIR)$(UDEVRULESDIR)/$$i; \ done +uninstall-systemd: + for i in $(SERVICE_FILES); do \ + $(RM) -f $(DESTDIR)$(SYSTEMDSYSTEMUNITDIR)/$$i; \ + done + for i in $(LIBPROGS); do \ + $(RM) -f $(DESTDIR)$(pkglibdir)/$(package)/$$i; \ + done + uninstall: $(UNINSTALL_TGT) for i in $(PROGS); do \ $(RM) -f $(DESTDIR)$(root_sbindir)/$$i; \ @@ -93,6 +148,9 @@ uninstall: $(UNINSTALL_TGT) for i in $(CONFFILES); do \ $(RM) -f $(DESTDIR)$(root_sysconfdir)/$$i; \ done + for i in $(CRONTABS); do \ + $(RM) -f $(DESTDIR)$(root_crondir)/$$i; \ + done clean:: $(RM) -f $(PROGS) diff --git a/scrub/e2scrub.in b/scrub/e2scrub.in index 75e0639..9ea9b19 100644 --- a/scrub/e2scrub.in +++ b/scrub/e2scrub.in @@ -40,6 +40,18 @@ print_help() { exitcode() { ret="$1" + # If we're in service mode, add 150 to the error code to + # avoid conflicting with sysvinit error codes + if [ -n "${SERVICE_MODE}" ] && [ "${ret}" -ne 0 ]; then + ret="$((ret + 150))" + fi + + # Stupid journald bug where the process still has to exist for + # the last few messages to get tagged to the service... + if [ -n "${SERVICE_MODE}" ] && [ -x "${SLEEP_PROG}" ]; then + "${SLEEP_PROG}" 2 + fi + exit "${ret}" } diff --git a/scrub/e2scrub@.service.in b/scrub/e2scrub@.service.in new file mode 100644 index 0000000..213cffc --- /dev/null +++ b/scrub/e2scrub@.service.in @@ -0,0 +1,18 @@ +[Unit] +Description=Online ext4 Metadata Check for %I +OnFailure=e2scrub_fail@%i.service + +[Service] +Type=oneshot +WorkingDirectory=/ +PrivateNetwork=true +ProtectSystem=true +ProtectHome=read-only +PrivateTmp=yes +AmbientCapabilities=CAP_SYS_ADMIN CAP_SYS_RAWIO +NoNewPrivileges=yes +User=root +IOSchedulingClass=idle +CPUSchedulingPolicy=idle +Environment=SERVICE_MODE=1 +ExecStart=@root_sbindir@/e2scrub -t %I diff --git a/scrub/e2scrub_all.cron.in b/scrub/e2scrub_all.cron.in new file mode 100644 index 0000000..6551a77 --- /dev/null +++ b/scrub/e2scrub_all.cron.in @@ -0,0 +1,2 @@ +SERVICE_MODE=1 +10 3 * * 0 root test -e /run/systemd/system || @root_sbindir@/e2scrub_all diff --git a/scrub/e2scrub_all.in b/scrub/e2scrub_all.in index a9ba670..71fb343 100644 --- a/scrub/e2scrub_all.in +++ b/scrub/e2scrub_all.in @@ -24,6 +24,18 @@ types="ext2,ext3,ext4" exitcode() { ret="$1" + # If we're in service mode, add 150 to the error code to + # avoid conflicting with sysvinit error codes + if [ -n "${SERVICE_MODE}" ] && [ "${ret}" -ne 0 ]; then + ret="$((ret + 150))" + fi + + # Stupid journald bug where the process still has to exist for + # the last few messages to get tagged to the service... + if [ -n "${SERVICE_MODE}" ]; then + "${SLEEP_PROG}" 2 + fi + exit "${ret}" } @@ -39,13 +51,23 @@ prog_path() { LVS_PROG="$(prog_path "@root_sbindir@/lvs" "lvs")" BLKID_PROG="$(prog_path "@root_sbindir@/blkid" "blkid")" +SYSTEMCTL_PROG="$(prog_path "@root_bindir@/systemctl")" +SLEEP_PROG="$(prog_path "@root_bindir@/sleep")" # Scrub any fs on lvm by creating a snapshot and fscking that. "${LVS_PROG}" -o vg_name,lv_name --noheadings 2> /dev/null | while read vg lv; do dev="/dev/${vg}/${lv}" "${BLKID_PROG}" -p -n "${types}" "${dev}" > /dev/null 2>&1 || continue - ${DBG} "@root_sbindir@/e2scrub" "${dev}" + if [ ! -x "${SYSTEMCTL_PROG}" ]; then + ${DBG} "@root_sbindir@/e2scrub" "${dev}" + else + ${DBG} "${SYSTEMCTL_PROG}" start "e2scrub@${dev}" 2> /dev/null + res=$? + if [ "${res}" -ne 0 ] && [ "${res}" -ne 1 ]; then + ${DBG} "@root_sbindir@/e2scrub" "${dev}" + fi + fi done exitcode 0 diff --git a/scrub/e2scrub_all.service.in b/scrub/e2scrub_all.service.in new file mode 100644 index 0000000..89a76e2 --- /dev/null +++ b/scrub/e2scrub_all.service.in @@ -0,0 +1,8 @@ +[Unit] +Description=Online ext4 Metadata Check for All Filesystems +ConditionACPower=true + +[Service] +Type=oneshot +Environment=SERVICE_MODE=1 +ExecStart=@root_sbindir@/e2scrub_all diff --git a/scrub/e2scrub_all.timer.in b/scrub/e2scrub_all.timer.in new file mode 100644 index 0000000..3d558bb --- /dev/null +++ b/scrub/e2scrub_all.timer.in @@ -0,0 +1,11 @@ +[Unit] +Description=Periodic ext4 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/e2scrub_fail.in b/scrub/e2scrub_fail.in new file mode 100644 index 0000000..b95db1b --- /dev/null +++ b/scrub/e2scrub_fail.in @@ -0,0 +1,26 @@ +#!/bin/bash + +# Email logs of failed e2scrub 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: +Subject: e2scrub failure on ${mntpoint} + +So sorry, the automatic e2scrub of ${mntpoint} on ${hostname} failed. + +A log of what happened follows: +ENDL +systemctl status --full --lines 4294967295 "e2scrub@${mntpoint}") | "${mailer}" -t -i diff --git a/scrub/e2scrub_fail@.service.in b/scrub/e2scrub_fail@.service.in new file mode 100644 index 0000000..df87949 --- /dev/null +++ b/scrub/e2scrub_fail@.service.in @@ -0,0 +1,10 @@ +[Unit] +Description=Online ext4 Metadata Check Failure Reporting for %I + +[Service] +Type=oneshot +Environment=EMAIL_ADDR=root +ExecStart=@pkglibdir@/e2scrub_fail "${EMAIL_ADDR}" %I +User=mail +Group=mail +SupplementaryGroups=systemd-journal diff --git a/util/subst.conf.in b/util/subst.conf.in index effac78..f534f67 100644 --- a/util/subst.conf.in +++ b/util/subst.conf.in @@ -20,3 +20,5 @@ JDEV TDB_MAN_COMMENT @TDB_MAN_COMMENT@ root_sbindir @root_sbindir@ root_bindir @root_bindir@ +pkglibdir @pkglibdir@ +$exec_prefix @exec_prefix@ From patchwork Thu Dec 7 18:48:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Darrick Wong X-Patchwork-Id: 845773 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=oracle.com header.i=@oracle.com header.b="nfBEnKSp"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yt4Jc5Xrgz9s82 for ; Fri, 8 Dec 2017 05:49:04 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751010AbdLGStE (ORCPT ); Thu, 7 Dec 2017 13:49:04 -0500 Received: from aserp2130.oracle.com ([141.146.126.79]:59938 "EHLO aserp2130.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750929AbdLGStD (ORCPT ); Thu, 7 Dec 2017 13:49:03 -0500 Received: from pps.filterd (aserp2130.oracle.com [127.0.0.1]) by aserp2130.oracle.com (8.16.0.21/8.16.0.21) with SMTP id vB7ImnCP084836; Thu, 7 Dec 2017 18:49:00 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=subject : from : to : cc : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=corp-2017-10-26; bh=KgoP1Gq7KZV73Yoh8LpudEoKjb2rLF0/WgjUa2tA8Uc=; b=nfBEnKSpNOFb0NGwaZuEPACa8l/fWrOmAwypXptyqBK3DwGNmAYnv/cC+4wvCmSRA42I ZOQQMZrB04nivN410MPyK8VVU3t+VRB4o8FOEer2D6lWZlRm6tMK9KCDQGscSwsQAkFf vDC2ORAskM/3OFyp04n6hku6R8hIaR5chClt6Wg8MFs44xRzEQmFfv2FICa/jVvnplSy Y6UwRyL/zGlpSUYmwow29tnVHNWCvLd2k55gqmbl6uoZ3YUzwACv+YLNksJAvHEzpKZO vyIpQetx5aBSIAdtF+k25Nm6iOp+duTRQg3teOc/Xkux8UoVUoTZPCCwfE0xySnTEKZ0 ow== Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp2130.oracle.com with ESMTP id 2eqb8j8019-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 07 Dec 2017 18:49:00 +0000 Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0021.oracle.com (8.14.4/8.14.4) with ESMTP id vB7ImxDI029156 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 7 Dec 2017 18:48:59 GMT Received: from abhmp0008.oracle.com (abhmp0008.oracle.com [141.146.116.14]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id vB7Imxv3026185; Thu, 7 Dec 2017 18:48:59 GMT Received: from localhost (/67.169.218.210) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 07 Dec 2017 10:48:58 -0800 Subject: [PATCH 4/4] misc: enable link time optimization, if requested From: "Darrick J. Wong" To: tytso@mit.edu, darrick.wong@oracle.com Cc: adilger@dilger.ca, linux-ext4@vger.kernel.org Date: Thu, 07 Dec 2017 10:48:48 -0800 Message-ID: <151267252874.1350.6941160583740966622.stgit@magnolia> In-Reply-To: <151267250365.1350.7799938074608034424.stgit@magnolia> References: <151267250365.1350.7799938074608034424.stgit@magnolia> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=8738 signatures=668644 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=9 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1711220000 definitions=main-1712070275 Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org From: Darrick J. Wong Enable link time optimization (LTO) if the builder requests it. The extra link optimization results in smaller binaries. Signed-off-by: Darrick J. Wong --- MCONFIG.in | 16 +++---- configure | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 35 +++++++++++++++ debian/rules | 2 - 4 files changed, 183 insertions(+), 9 deletions(-) diff --git a/MCONFIG.in b/MCONFIG.in index aa7d0d1..a396935 100644 --- a/MCONFIG.in +++ b/MCONFIG.in @@ -82,19 +82,19 @@ UDEVRULESDIR = @udevrulesdir@ CC = @CC@ BUILD_CC = @BUILD_CC@ -CFLAGS = @CFLAGS@ -CFLAGS_SHLIB = @CFLAGS_SHLIB@ -CFLAGS_STLIB = @CFLAGS_STLIB@ +CFLAGS = @lto_cflags@ @CFLAGS@ +CFLAGS_SHLIB = @lto_cflags@ @CFLAGS_SHLIB@ +CFLAGS_STLIB = @lto_cflags@ @CFLAGS_STLIB@ CPPFLAGS = @INCLUDES@ ALL_CFLAGS = $(CPPFLAGS) $(CFLAGS) $(CFLAGS_WARN) @DEFS@ $(LOCAL_CFLAGS) ALL_CFLAGS_SHLIB = $(CPPFLAGS) $(CFLAGS_SHLIB) $(CFLAGS_WARN) @DEFS@ $(LOCAL_CFLAGS) ALL_CFLAGS_STLIB = $(CPPFLAGS) $(CFLAGS_STLIB) $(CFLAGS_WARN) @DEFS@ $(LOCAL_CFLAGS) -LDFLAGS = @LDFLAGS@ -LDFLAGS_SHLIB = @LDFLAGS_SHLIB@ +LDFLAGS = @lto_ldflags@ @LDFLAGS@ +LDFLAGS_SHLIB = @lto_ldflags@ @LDFLAGS_SHLIB@ ALL_LDFLAGS = $(LDFLAGS) @LDFLAG_DYNAMIC@ -LDFLAGS_STATIC = @LDFLAGS_STATIC@ -BUILD_CFLAGS = @BUILD_CFLAGS@ -BUILD_LDFLAGS = @BUILD_LDFLAGS@ +LDFLAGS_STATIC = @lto_ldflags@ @LDFLAGS_STATIC@ +BUILD_CFLAGS = @lto_cflags@ @BUILD_CFLAGS@ +BUILD_LDFLAGS = @lto_ldflags@ @BUILD_LDFLAGS@ RDYNAMIC = @RDYNAMIC@ LINK_BUILD_FLAGS = @LINK_BUILD_FLAGS@ LINK_INSTALL_FLAGS = @LINK_INSTALL_FLAGS@ diff --git a/configure b/configure index cca0c23..26a027e 100755 --- a/configure +++ b/configure @@ -649,6 +649,11 @@ E2SCRUB_CMT UNIX_CMT CYGWIN_CMT LINUX_CMT +lto_ldflags +lto_cflags +have_lto +gcc_ranlib +gcc_ar UNI_DIFF_OPTS SEM_INIT_LIB FUSE_CMT @@ -898,6 +903,7 @@ with_libiconv_prefix with_included_gettext with_libintl_prefix enable_fuse2fs +enable_lto with_multiarch ' ac_precious_vars='build_alias @@ -1569,6 +1575,7 @@ Optional Features: --disable-threads build without multithread safety --disable-rpath do not hardcode runtime library paths --disable-fuse2fs do not build fuse2fs + --enable-lto enable link time optimization Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -13703,6 +13710,138 @@ $as_echo "#define HAVE_EXT2_IOCTLS 1" >>confdefs.h ;; esac +# Check whether --enable-lto was given. +if test "${enable_lto+set}" = set; then : + enableval=$enable_lto; +else + enable_lto=probe +fi + +if test "$enable_lto" = "yes" || test "$enable_lto" = "probe"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if C compiler supports LTO" >&5 +$as_echo_n "checking if C compiler supports LTO... " >&6; } + OLD_CFLAGS="$CFLAGS" + OLD_LDFLAGS="$LDFLAGS" + LTO_FLAGS="-flto -ffat-lto-objects" + CFLAGS="$CFLAGS $LTO_FLAGS" + LDFLAGS="$LDFLAGS $LTO_FLAGS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + lto_cflags=$LTO_FLAGS + lto_ldflags=$LTO_FLAGS + # Extract the first word of "gcc-ar", so it can be a program name with args. +set dummy gcc-ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_gcc_ar+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $gcc_ar in + [\\/]* | ?:[\\/]*) + ac_cv_path_gcc_ar="$gcc_ar" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_gcc_ar="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +gcc_ar=$ac_cv_path_gcc_ar +if test -n "$gcc_ar"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_ar" >&5 +$as_echo "$gcc_ar" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + # Extract the first word of "gcc-ranlib", so it can be a program name with args. +set dummy gcc-ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_gcc_ranlib+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $gcc_ranlib in + [\\/]* | ?:[\\/]*) + ac_cv_path_gcc_ranlib="$gcc_ranlib" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_gcc_ranlib="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +gcc_ranlib=$ac_cv_path_gcc_ranlib +if test -n "$gcc_ranlib"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_ranlib" >&5 +$as_echo "$gcc_ranlib" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -x "$gcc_ar" && test -x "$gcc_ranlib"; then + have_lto=yes + AR="${gcc_ar}" + RANLIB="${gcc_ranlib}" + fi + CFLAGS="${OLD_CFLAGS}" + LDFLAGS="${OLD_LDFLAGS}" + + + +fi +if test "$enable_lto" = "yes" && test "$have_lto" != "yes"; then + echo "MUGGA \"${enable_lto}\" OR \"${have_lto}\"" + as_fn_error $? "LTO not supported by compiler." "$LINENO" 5 +fi LINUX_CMT="#" CYGWIN_CMT="#" UNIX_CMT= diff --git a/configure.ac b/configure.ac index 28172bd..e44d040 100644 --- a/configure.ac +++ b/configure.ac @@ -1293,6 +1293,41 @@ linux*) ;; esac dnl +dnl Enable LTO for all packages +dnl +AC_ARG_ENABLE([lto], +[ --enable-lto enable link time optimization],, +enable_lto=probe) +if test "$enable_lto" = "yes" || test "$enable_lto" = "probe"; then + AC_MSG_CHECKING([if C compiler supports LTO]) + OLD_CFLAGS="$CFLAGS" + OLD_LDFLAGS="$LDFLAGS" + LTO_FLAGS="-flto -ffat-lto-objects" + CFLAGS="$CFLAGS $LTO_FLAGS" + LDFLAGS="$LDFLAGS $LTO_FLAGS" + AC_LINK_IFELSE([AC_LANG_PROGRAM([])], + [AC_MSG_RESULT([yes])] + [lto_cflags=$LTO_FLAGS] + [lto_ldflags=$LTO_FLAGS] + [AC_PATH_PROG(gcc_ar, gcc-ar,,)] + [AC_PATH_PROG(gcc_ranlib, gcc-ranlib,,)], + [AC_MSG_RESULT([no])]) + if test -x "$gcc_ar" && test -x "$gcc_ranlib"; then + have_lto=yes + AR="${gcc_ar}" + RANLIB="${gcc_ranlib}" + fi + CFLAGS="${OLD_CFLAGS}" + LDFLAGS="${OLD_LDFLAGS}" + AC_SUBST(have_lto) + AC_SUBST(lto_cflags) + AC_SUBST(lto_ldflags) +fi +if test "$enable_lto" = "yes" && test "$have_lto" != "yes"; then + echo "MUGGA \"${enable_lto}\" OR \"${have_lto}\"" + AC_MSG_ERROR([LTO not supported by compiler.]) +fi +dnl dnl OS-specific uncomment control dnl LINUX_CMT="#" diff --git a/debian/rules b/debian/rules index 841715d..3a22c35 100755 --- a/debian/rules +++ b/debian/rules @@ -147,7 +147,7 @@ endif BACKTRACE_CONF_FLAGS ?= $(shell if ${debdir}/scripts/test-backtrace ; then echo --disable-backtrace ; fi) -COMMON_CONF_FLAGS = --disable-e2initrd-helper \ +COMMON_CONF_FLAGS = --enable-lto --disable-e2initrd-helper \ --infodir=/usr/share/info --enable-symlink-install \ --with-multiarch=$(DEB_HOST_MULTIARCH) \ $(BACKTRACE_CONF_FLAGS) $(UTIL_CONF_FLAGS)