2010-05-14 15:33:20 +04:00
#!/bin/bash
2007-12-17 15:31:50 +03:00
#
2012-03-16 16:53:05 +04:00
# Copyright (C) 2007-2012 Red Hat, Inc. All rights reserved.
2007-12-17 15:31:50 +03:00
#
# This file is part of LVM2.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
2016-01-21 13:49:46 +03:00
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2007-12-17 15:31:50 +03:00
#
2008-01-08 19:45:43 +03:00
# Author: Zdenek Kabelac <zkabelac at redhat.com>
2007-12-17 15:31:50 +03:00
#
# Script for resizing devices (usable for LVM resize)
#
# Needed utilities:
# mount, umount, grep, readlink, blockdev, blkid, fsck, xfs_check
#
2009-02-04 15:47:05 +03:00
# ext2/ext3/ext4: resize2fs, tune2fs
2007-12-17 15:31:50 +03:00
# reiserfs: resize_reiserfs, reiserfstune
# xfs: xfs_growfs, xfs_info
#
2010-11-01 17:08:51 +03:00
# Return values:
# 0 success
# 1 error
# 2 break detected
# 3 unsupported online filesystem check for given mounted fs
2007-12-17 15:31:50 +03:00
TOOL = fsadm
2011-09-19 17:51:09 +04:00
_SAVEPATH = $PATH
2007-12-17 15:31:50 +03:00
PATH = /sbin:/usr/sbin:/bin:/usr/sbin:$PATH
# utilities
TUNE_EXT = tune2fs
RESIZE_EXT = resize2fs
TUNE_REISER = reiserfstune
RESIZE_REISER = resize_reiserfs
TUNE_XFS = xfs_info
RESIZE_XFS = xfs_growfs
MOUNT = mount
UMOUNT = umount
MKDIR = mkdir
2008-01-08 19:45:43 +03:00
RMDIR = rmdir
BLOCKDEV = blockdev
BLKID = blkid
2010-11-11 15:17:15 +03:00
DATE = date
2007-12-17 15:31:50 +03:00
GREP = grep
READLINK = readlink
2008-04-29 19:25:28 +04:00
READLINK_E = "-e"
2007-12-17 15:31:50 +03:00
FSCK = fsck
XFS_CHECK = xfs_check
2014-01-20 14:57:39 +04:00
# XFS_REPAIR -n is used when XFS_CHECK is not found
XFS_REPAIR = xfs_repair
2007-12-17 15:31:50 +03:00
2009-06-09 19:31:36 +04:00
# user may override lvm location by setting LVM_BINARY
2010-10-08 18:49:25 +04:00
LVM = ${ LVM_BINARY :- lvm }
2008-02-06 15:45:32 +03:00
2010-10-08 17:49:20 +04:00
YES = ${ _FSADM_YES }
2007-12-17 15:31:50 +03:00
DRY = 0
2008-02-06 15:45:32 +03:00
VERB =
2007-12-17 15:31:50 +03:00
FORCE =
2012-03-16 16:53:05 +04:00
EXTOFF = ${ _FSADM_EXTOFF :- 0 }
2008-02-06 15:45:32 +03:00
DO_LVRESIZE = 0
2007-12-17 15:31:50 +03:00
FSTYPE = unknown
VOLUME = unknown
TEMPDIR = " ${ TMPDIR :- /tmp } / ${ TOOL } _ ${ RANDOM } $$ /m "
2011-09-19 23:36:52 +04:00
DM_DEV_DIR = " ${ DM_DEV_DIR :- /dev } "
2007-12-17 15:31:50 +03:00
BLOCKSIZE =
BLOCKCOUNT =
MOUNTPOINT =
MOUNTED =
REMOUNT =
2010-10-08 18:55:19 +04:00
PROCMOUNTS = "/proc/mounts"
2016-03-18 15:42:06 +03:00
PROCSELFMOUNTINFO = "/proc/self/mountinfo"
2011-09-19 23:36:52 +04:00
NULL = " $DM_DEV_DIR /null "
2007-12-17 15:31:50 +03:00
IFS_OLD = $IFS
2009-06-09 19:31:36 +04:00
# without bash $'\n'
NL = '
'
2007-12-17 15:31:50 +03:00
tool_usage( ) {
2007-12-17 17:47:22 +03:00
echo " ${ TOOL } : Utility to resize or check the filesystem on a device "
echo
2015-10-05 13:28:00 +03:00
echo " ${ TOOL } [options] check <device> "
2007-12-17 17:47:22 +03:00
echo " - Check the filesystem on device using fsck"
echo
2015-10-05 13:28:00 +03:00
echo " ${ TOOL } [options] resize <device> [<new_size>[BKMGTPE]] "
2007-12-17 17:47:22 +03:00
echo " - Change the size of the filesystem on device to new_size"
echo
echo " Options:"
echo " -h | --help Show this help message"
echo " -v | --verbose Be verbose"
2009-02-04 15:47:05 +03:00
echo " -e | --ext-offline unmount filesystem before ext2/ext3/ext4 resize"
2007-12-17 17:47:22 +03:00
echo " -f | --force Bypass sanity checks"
echo " -n | --dry-run Print commands without running them"
2008-02-06 15:45:32 +03:00
echo " -l | --lvresize Resize given device (if it is LVM device)"
2007-12-17 17:47:22 +03:00
echo " -y | --yes Answer \"yes\" at any prompts"
echo
echo " new_size - Absolute number of filesystem blocks to be in the filesystem,"
echo " or an absolute size using a suffix (in powers of 1024)."
echo " If new_size is not supplied, the whole device is used."
2007-12-17 15:31:50 +03:00
exit
}
verbose( ) {
2008-02-06 15:45:32 +03:00
test -n " $VERB " && echo " $TOOL : $@ " || true
2007-12-17 15:31:50 +03:00
}
error( ) {
echo " $TOOL : $@ " >& 2
cleanup 1
}
dry( ) {
2008-01-08 19:45:43 +03:00
if [ " $DRY " -ne 0 ] ; then
verbose " Dry execution $@ "
return 0
fi
2007-12-17 15:31:50 +03:00
verbose " Executing $@ "
2012-03-16 16:53:05 +04:00
" $@ "
2007-12-17 15:31:50 +03:00
}
cleanup( ) {
trap '' 2
# reset MOUNTPOINT - avoid recursion
test " $MOUNTPOINT " = " $TEMPDIR " && MOUNTPOINT = "" temp_umount
if [ -n " $REMOUNT " ] ; then
verbose "Remounting unmounted filesystem back"
2011-09-19 17:47:37 +04:00
dry " $MOUNT " " $VOLUME " " $MOUNTED "
2007-12-17 15:31:50 +03:00
fi
IFS = $IFS_OLD
trap 2
2008-02-06 15:45:32 +03:00
2010-11-01 17:08:51 +03:00
test " $1 " -eq 2 && verbose "Break detected"
2010-10-08 17:47:10 +04:00
if [ " $DO_LVRESIZE " -eq 2 ] ; then
# start LVRESIZE with the filesystem modification flag
# and allow recursive call of fsadm
2010-10-08 17:49:20 +04:00
_FSADM_YES = $YES
2012-03-16 16:53:05 +04:00
_FSADM_EXTOFF = $EXTOFF
export _FSADM_YES _FSADM_EXTOFF
2010-10-08 17:47:10 +04:00
unset FSADM_RUNNING
2011-09-19 17:51:09 +04:00
test -n " $LVM_BINARY " && PATH = $_SAVEPATH
2011-09-19 17:47:37 +04:00
dry exec " $LVM " lvresize $VERB $FORCE -r -L${ NEWSIZE } b " $VOLUME_ORIG "
2010-10-08 17:47:10 +04:00
fi
2011-09-19 17:51:09 +04:00
2010-10-08 16:35:56 +04:00
# error exit status for break
exit ${ 1 :- 1 }
2007-12-17 15:31:50 +03:00
}
2008-01-08 19:45:43 +03:00
# convert parameter from Exa/Peta/Tera/Giga/Mega/Kilo/Bytes and blocks
# (2^(60/50/40/30/20/10/0))
2007-12-17 15:31:50 +03:00
decode_size( ) {
case " $1 " in
2008-01-08 19:45:43 +03:00
*[ eE] ) NEWSIZE = $(( ${ 1 %[eE] } * 1152921504606846976 )) ; ;
*[ pP] ) NEWSIZE = $(( ${ 1 %[pP] } * 1125899906842624 )) ; ;
2007-12-17 15:31:50 +03:00
*[ tT] ) NEWSIZE = $(( ${ 1 %[tT] } * 1099511627776 )) ; ;
*[ gG] ) NEWSIZE = $(( ${ 1 %[gG] } * 1073741824 )) ; ;
*[ mM] ) NEWSIZE = $(( ${ 1 %[mM] } * 1048576 )) ; ;
*[ kK] ) NEWSIZE = $(( ${ 1 %[kK] } * 1024 )) ; ;
*[ bB] ) NEWSIZE = ${ 1 %[bB] } ; ;
*) NEWSIZE = $(( $1 * $2 )) ; ;
esac
#NEWBLOCKCOUNT=$(round_block_size $NEWSIZE $2)
NEWBLOCKCOUNT = $(( $NEWSIZE / $2 ))
2008-02-06 15:45:32 +03:00
if [ $DO_LVRESIZE -eq 1 ] ; then
# start lvresize, but first cleanup mounted dirs
DO_LVRESIZE = 2
cleanup 0
fi
2007-12-17 15:31:50 +03:00
}
# detect filesystem on the given device
# dereference device name if it is symbolic link
detect_fs( ) {
2010-10-08 18:55:19 +04:00
VOLUME_ORIG = $1
2011-09-19 23:36:52 +04:00
VOLUME = ${ 1 /# " ${ DM_DEV_DIR } / " / }
2017-05-09 21:52:15 +03:00
VOLUME = $( " $READLINK " $READLINK_E " $DM_DEV_DIR / $VOLUME " )
test -n " $VOLUME " || error " Cannot get readlink \" $1 \". "
2010-10-08 18:55:19 +04:00
RVOLUME = $VOLUME
case " $RVOLUME " in
2011-09-19 23:36:52 +04:00
# hardcoded /dev since udev does not create these entries elsewhere
2010-10-08 18:55:19 +04:00
/dev/dm-[ 0-9] *)
2011-09-19 23:36:52 +04:00
read </sys/block/${ RVOLUME #/dev/ } /dm/name SYSVOLUME 2>& 1 && VOLUME = " $DM_DEV_DIR /mapper/ $SYSVOLUME "
2016-03-18 15:42:06 +03:00
read </sys/block/${ RVOLUME #/dev/ } /dev MAJORMINOR 2>& 1 || error " Cannot get major:minor for \" $VOLUME \" "
2010-10-08 18:55:19 +04:00
; ;
2016-03-18 17:55:36 +03:00
*)
2017-05-09 21:52:15 +03:00
STAT = $( stat --format "MAJOR=%t MINOR=%T" ${ RVOLUME } )
test -n " $STAT " || error " Cannot get major:minor for \" $VOLUME \". "
2016-03-18 17:55:36 +03:00
eval $STAT
MAJOR = $(( 0 x${ MAJOR } ))
MINOR = $(( 0 x${ MINOR } ))
MAJORMINOR = ${ MAJOR } :${ MINOR }
; ;
2010-10-08 18:55:19 +04:00
esac
2011-09-19 23:36:52 +04:00
# use null device as cache file to be sure about the result
2009-02-06 17:28:06 +03:00
# not using option '-o value' to be compatible with older version of blkid
2017-05-09 21:52:15 +03:00
FSTYPE = $( " $BLKID " -c " $NULL " -s TYPE " $VOLUME " )
test -n " $FSTYPE " || error " Cannot get FSTYPE of \" $VOLUME \". "
2009-02-06 17:28:06 +03:00
FSTYPE = ${ FSTYPE ##*TYPE= \" } # cut quotation marks
FSTYPE = ${ FSTYPE %% \" * }
2007-12-17 15:31:50 +03:00
verbose " \" $FSTYPE \" filesystem found on \" $VOLUME \" "
}
2016-03-18 15:42:06 +03:00
detect_mounted_with_proc_self_mountinfo( ) {
MOUNTED = $( " $GREP " " ^[0-9]* [0-9]* $MAJORMINOR " " $PROCSELFMOUNTINFO " )
# extract 5th field which is mount point
# echo -e translates \040 to spaces
MOUNTED = $( echo ${ MOUNTED } | cut -d " " -f 5)
MOUNTED = $( echo -n -e ${ MOUNTED } )
test -n " $MOUNTED "
}
2010-10-08 18:55:19 +04:00
2016-03-18 15:42:06 +03:00
detect_mounted_with_proc_mounts( ) {
2012-03-16 16:53:05 +04:00
MOUNTED = $( " $GREP " " ^ $VOLUME [ \t] " " $PROCMOUNTS " )
2010-10-08 18:55:19 +04:00
# for empty string try again with real volume name
2012-03-16 16:53:05 +04:00
test -z " $MOUNTED " && MOUNTED = $( " $GREP " " ^ $RVOLUME [ \t] " " $PROCMOUNTS " )
2010-10-08 18:55:19 +04:00
# cut device name prefix and trim everything past mountpoint
# echo translates \040 to spaces
MOUNTED = ${ MOUNTED #* }
MOUNTED = $( echo -n -e ${ MOUNTED %% * } )
2010-11-10 19:14:02 +03:00
# for systems with different device names - check also mount output
if test -z " $MOUNTED " ; then
2013-01-22 14:25:02 +04:00
MOUNTED = $( LC_ALL = C " $MOUNT " | " $GREP " " ^ $VOLUME [ \t] " )
test -z " $MOUNTED " && MOUNTED = $( LC_ALL = C " $MOUNT " | " $GREP " " ^ $RVOLUME [ \t] " )
2010-11-10 19:14:02 +03:00
MOUNTED = ${ MOUNTED ##* on }
MOUNTED = ${ MOUNTED % type * } # allow type in the mount name
fi
2007-12-17 15:31:50 +03:00
test -n " $MOUNTED "
}
2016-03-18 15:42:06 +03:00
# check if the given device is already mounted and where
# FIXME: resolve swap usage and device stacking
detect_mounted( ) {
if test -e " $PROCSELFMOUNTINFO " ; then
detect_mounted_with_proc_self_mountinfo
elif test -e " $PROCMOUNTS " ; then
detect_mounted_with_proc_mounts
else
error " Cannot detect mounted device \" $VOLUME \" "
fi
}
2007-12-17 15:31:50 +03:00
# get the full size of device in bytes
detect_device_size( ) {
2008-04-29 19:25:28 +04:00
# check if blockdev supports getsize64
2011-09-19 23:36:52 +04:00
" $BLOCKDEV " 2>& 1 | " $GREP " getsize64 >" $NULL "
2009-02-24 18:48:00 +03:00
if test $? -eq 0; then
2017-05-09 21:52:15 +03:00
DEVSIZE = $( " $BLOCKDEV " --getsize64 " $VOLUME " )
test -n " $DEVSIZE " || error " Cannot read size of device \" $VOLUME \". "
2008-04-29 19:25:28 +04:00
else
2017-05-09 21:52:15 +03:00
DEVSIZE = $( " $BLOCKDEV " --getsize " $VOLUME " )
test -n " $DEVSIZE " || error " Cannot read size of device \" $VOLUME \". "
SSSIZE = $( " $BLOCKDEV " --getss " $VOLUME " )
test -n " $SSSIZE " || error " Cannot read sector size of device \" $VOLUME \". "
2008-04-29 19:25:28 +04:00
DEVSIZE = $(( $DEVSIZE * $SSSIZE ))
fi
2007-12-17 15:31:50 +03:00
}
# round up $1 / $2
# could be needed to gaurantee 'at least given size'
# but it makes many troubles
round_up_block_size( ) {
echo $(( ( $1 + $2 - 1 ) / $2 ))
}
temp_mount( ) {
2011-09-19 17:47:37 +04:00
dry " $MKDIR " -p -m 0000 " $TEMPDIR " || error " Failed to create $TEMPDIR "
dry " $MOUNT " " $VOLUME " " $TEMPDIR " || error " Failed to mount $TEMPDIR "
2007-12-17 15:31:50 +03:00
}
temp_umount( ) {
2011-09-19 17:47:37 +04:00
dry " $UMOUNT " " $TEMPDIR " || error " Failed to umount \" $TEMPDIR \" "
dry " $RMDIR " " ${ TEMPDIR } " || error " Failed to remove \" $TEMPDIR \" "
dry " $RMDIR " " ${ TEMPDIR %%m } " || error " Failed to remove \" ${ TEMPDIR %%m } \" "
2007-12-17 15:31:50 +03:00
}
yes_no( ) {
echo -n " $@ ? [Y|n] "
2009-02-24 18:48:00 +03:00
2007-12-17 15:31:50 +03:00
if [ -n " $YES " ] ; then
2009-02-24 18:48:00 +03:00
echo y ; return 0
2007-12-17 15:31:50 +03:00
fi
2009-02-24 18:48:00 +03:00
while read -r -s -n 1 ANS ; do
case " $ANS " in
"y" | "Y" | "" ) echo y ; return 0 ; ;
"n" | "N" ) echo n ; return 1 ; ;
esac
done
2007-12-17 15:31:50 +03:00
}
try_umount( ) {
2011-09-19 17:47:37 +04:00
yes_no " Do you want to unmount \" $MOUNTED \" " && dry " $UMOUNT " " $MOUNTED " && return 0
2010-10-08 15:18:29 +04:00
error " Cannot proceed with mounted filesystem \" $MOUNTED \" "
2007-12-17 15:31:50 +03:00
}
validate_parsing( ) {
2014-06-30 22:03:05 +04:00
test -n " $BLOCKSIZE " && test -n " $BLOCKCOUNT " || error " Cannot parse $1 output "
2007-12-17 15:31:50 +03:00
}
####################################
2009-02-04 15:47:05 +03:00
# Resize ext2/ext3/ext4 filesystem
2007-12-17 15:31:50 +03:00
# - unmounted or mounted for upsize
# - unmounted for downsize
####################################
resize_ext( ) {
verbose " Parsing $TUNE_EXT -l \" $VOLUME \" "
2013-01-22 14:25:02 +04:00
for i in $( LC_ALL = C " $TUNE_EXT " -l " $VOLUME " ) ; do
2007-12-17 15:31:50 +03:00
case " $i " in
"Block size" *) BLOCKSIZE = ${ i ##* } ; ;
"Block count" *) BLOCKCOUNT = ${ i ##* } ; ;
esac
done
2011-09-19 17:47:37 +04:00
validate_parsing " $TUNE_EXT "
2007-12-17 15:31:50 +03:00
decode_size $1 $BLOCKSIZE
FSFORCE = $FORCE
2008-01-08 19:45:43 +03:00
if [ " $NEWBLOCKCOUNT " -lt " $BLOCKCOUNT " -o " $EXTOFF " -eq 1 ] ; then
2007-12-17 15:31:50 +03:00
detect_mounted && verbose " $RESIZE_EXT needs unmounted filesystem " && try_umount
REMOUNT = $MOUNTED
2010-11-10 19:14:02 +03:00
if test -n " $MOUNTED " ; then
# Forced fsck -f for umounted extX filesystem.
case " $- " in
2011-09-19 17:47:37 +04:00
*i*) dry " $FSCK " $YES -f " $VOLUME " ; ;
*) dry " $FSCK " -f -p " $VOLUME " ; ;
2010-11-10 19:14:02 +03:00
esac
fi
2007-12-17 15:31:50 +03:00
fi
2009-02-24 18:48:00 +03:00
verbose " Resizing filesystem on device \" $VOLUME \" to $NEWSIZE bytes ( $BLOCKCOUNT -> $NEWBLOCKCOUNT blocks of $BLOCKSIZE bytes) "
2011-09-19 17:47:37 +04:00
dry " $RESIZE_EXT " $FSFORCE " $VOLUME " $NEWBLOCKCOUNT
2007-12-17 15:31:50 +03:00
}
#############################
# Resize reiserfs filesystem
# - unmounted for upsize
# - unmounted for downsize
#############################
resize_reiser( ) {
2009-02-24 18:48:00 +03:00
detect_mounted && verbose "ReiserFS resizes only unmounted filesystem" && try_umount
REMOUNT = $MOUNTED
2007-12-17 15:31:50 +03:00
verbose " Parsing $TUNE_REISER \" $VOLUME \" "
2013-01-22 14:25:02 +04:00
for i in $( LC_ALL = C " $TUNE_REISER " " $VOLUME " ) ; do
2007-12-17 15:31:50 +03:00
case " $i " in
"Blocksize" *) BLOCKSIZE = ${ i ##* : } ; ;
"Count of blocks" *) BLOCKCOUNT = ${ i ##* : } ; ;
esac
done
2011-09-19 17:47:37 +04:00
validate_parsing " $TUNE_REISER "
2007-12-17 15:31:50 +03:00
decode_size $1 $BLOCKSIZE
verbose " Resizing \" $VOLUME \" $BLOCKCOUNT -> $NEWBLOCKCOUNT blocks ( $NEWSIZE bytes, bs: $NEWBLOCKCOUNT ) "
if [ -n " $YES " ] ; then
2011-09-19 17:47:37 +04:00
echo y | dry " $RESIZE_REISER " -s $NEWSIZE " $VOLUME "
2007-12-17 15:31:50 +03:00
else
2011-09-19 17:47:37 +04:00
dry " $RESIZE_REISER " -s $NEWSIZE " $VOLUME "
2007-12-17 15:31:50 +03:00
fi
}
########################
# Resize XFS filesystem
# - mounted for upsize
2010-10-08 15:18:29 +04:00
# - cannot downsize
2007-12-17 15:31:50 +03:00
########################
resize_xfs( ) {
detect_mounted
MOUNTPOINT = $MOUNTED
if [ -z " $MOUNTED " ] ; then
MOUNTPOINT = $TEMPDIR
temp_mount || error "Cannot mount Xfs filesystem"
fi
verbose " Parsing $TUNE_XFS \" $MOUNTPOINT \" "
2013-01-22 14:25:02 +04:00
for i in $( LC_ALL = C " $TUNE_XFS " " $MOUNTPOINT " ) ; do
2007-12-17 15:31:50 +03:00
case " $i " in
"data" *) BLOCKSIZE = ${ i ##*bsize= } ; BLOCKCOUNT = ${ i ##*blocks= } ; ;
esac
done
BLOCKSIZE = ${ BLOCKSIZE %%[^0-9]* }
BLOCKCOUNT = ${ BLOCKCOUNT %%[^0-9]* }
2011-09-19 17:47:37 +04:00
validate_parsing " $TUNE_XFS "
2007-12-17 15:31:50 +03:00
decode_size $1 $BLOCKSIZE
if [ $NEWBLOCKCOUNT -gt $BLOCKCOUNT ] ; then
verbose " Resizing Xfs mounted on \" $MOUNTPOINT \" to fill device \" $VOLUME \" "
2011-09-19 17:47:37 +04:00
dry " $RESIZE_XFS " $MOUNTPOINT
2007-12-17 15:31:50 +03:00
elif [ $NEWBLOCKCOUNT -eq $BLOCKCOUNT ] ; then
verbose "Xfs filesystem already has the right size"
else
error "Xfs filesystem shrinking is unsupported"
fi
}
####################
# Resize filesystem
####################
resize( ) {
2008-02-06 15:45:32 +03:00
NEWSIZE = $2
2007-12-17 15:31:50 +03:00
detect_fs " $1 "
detect_device_size
2009-02-24 18:48:00 +03:00
verbose " Device \" $VOLUME \" size is $DEVSIZE bytes "
2007-12-17 15:31:50 +03:00
# if the size parameter is missing use device size
2008-02-06 15:45:32 +03:00
#if [ -n "$NEWSIZE" -a $NEWSIZE <
2008-01-08 19:45:43 +03:00
test -z " $NEWSIZE " && NEWSIZE = ${ DEVSIZE } b
2009-06-09 19:31:36 +04:00
IFS = $NL
2007-12-17 15:31:50 +03:00
case " $FSTYPE " in
2009-02-04 15:47:05 +03:00
"ext3" | "ext2" | "ext4" ) resize_ext $NEWSIZE ; ;
2007-12-17 15:31:50 +03:00
"reiserfs" ) resize_reiser $NEWSIZE ; ;
"xfs" ) resize_xfs $NEWSIZE ; ;
*) error " Filesystem \" $FSTYPE \" on device \" $VOLUME \" is not supported by this tool " ; ;
esac || error " Resize $FSTYPE failed "
2008-02-06 15:45:32 +03:00
cleanup 0
2007-12-17 15:31:50 +03:00
}
2010-11-10 19:14:02 +03:00
####################################
# Calclulate diff between two dates
2013-01-22 14:25:02 +04:00
# LC_ALL=C input is expected the
2010-11-10 19:14:02 +03:00
# only one supported
####################################
diff_dates( ) {
2011-09-19 23:36:52 +04:00
echo $(( $( " $DATE " -u -d" $1 " +%s 2>" $NULL " ) - $( " $DATE " -u -d" $2 " +%s 2>" $NULL " ) ))
2010-11-10 19:14:02 +03:00
}
2007-12-17 15:31:50 +03:00
###################
# Check filesystem
###################
check( ) {
detect_fs " $1 "
2010-11-01 17:08:51 +03:00
if detect_mounted ; then
verbose " Skipping filesystem check for device \" $VOLUME \" as the filesystem is mounted on $MOUNTED " ;
cleanup 3
fi
2010-11-10 19:14:02 +03:00
case " $FSTYPE " in
"ext2" | "ext3" | "ext4" )
IFS_CHECK = $IFS
IFS = $NL
2013-01-22 14:25:02 +04:00
for i in $( LC_ALL = C " $TUNE_EXT " -l " $VOLUME " ) ; do
2010-11-10 19:14:02 +03:00
case " $i " in
"Last mount" *) LASTMOUNT = ${ i ##* : } ; ;
"Last checked" *) LASTCHECKED = ${ i ##* : } ; ;
esac
done
case " $LASTMOUNT " in
*"n/a" ) ; ; # nothing to do - system was not mounted yet
*)
LASTDIFF = $( diff_dates $LASTMOUNT $LASTCHECKED )
if test " $LASTDIFF " -gt 0 ; then
verbose "Filesystem has not been checked after the last mount, using fsck -f"
FORCE = "-f"
fi
; ;
esac
IFS = $IFS_CHECK
esac
2007-12-17 15:31:50 +03:00
case " $FSTYPE " in
2014-01-20 14:57:39 +04:00
"xfs" ) if which " $XFS_CHECK " >" $NULL " 2>& 1 ; then
dry " $XFS_CHECK " " $VOLUME "
else
# Replacement for outdated xfs_check
# FIXME: for small devices we need to force_geometry,
# since we run in '-n' mode, it shouldn't be problem.
# Think about better way....
dry " $XFS_REPAIR " -n -o force_geometry " $VOLUME "
fi ; ;
2010-10-08 19:02:05 +04:00
*) # check if executed from interactive shell environment
case " $- " in
2011-09-19 17:47:37 +04:00
*i*) dry " $FSCK " $YES $FORCE " $VOLUME " ; ;
*) dry " $FSCK " $FORCE -p " $VOLUME " ; ;
2010-10-08 19:02:05 +04:00
esac
2007-12-17 15:31:50 +03:00
esac
}
#############################
# start point of this script
# - parsing parameters
#############################
2010-11-01 17:08:51 +03:00
trap "cleanup 2" 2
2008-01-08 19:45:43 +03:00
2008-02-06 15:45:32 +03:00
# test if we are not invoked recursively
test -n " $FSADM_RUNNING " && exit 0
2008-01-08 19:45:43 +03:00
# test some prerequisities
2014-06-30 22:03:05 +04:00
for i in " $TUNE_EXT " " $RESIZE_EXT " " $TUNE_REISER " " $RESIZE_REISER " \
" $TUNE_XFS " " $RESIZE_XFS " " $MOUNT " " $UMOUNT " " $MKDIR " \
" $RMDIR " " $BLOCKDEV " " $BLKID " " $GREP " " $READLINK " \
" $DATE " " $FSCK " " $XFS_CHECK " " $XFS_REPAIR " " $LVM " ; do
test -n " $i " || error "Required command definitions in the script are missing!"
done
2008-04-29 19:25:28 +04:00
2011-09-19 23:36:52 +04:00
" $LVM " version >" $NULL " 2>& 1 || error " Could not run lvm binary \" $LVM \" "
$( " $READLINK " -e / >" $NULL " 2>& 1) || READLINK_E = "-f"
2008-01-08 19:45:43 +03:00
TEST64BIT = $(( 1000 * 1000000000000 ))
2011-09-19 17:47:37 +04:00
test " $TEST64BIT " -eq 1000000000000000 || error "Shell does not handle 64bit arithmetic"
2011-09-19 23:36:52 +04:00
$( echo Y | " $GREP " Y >" $NULL " ) || error "Grep does not work properly"
2011-09-19 17:47:37 +04:00
test $( " $DATE " -u -d"Jan 01 00:00:01 1970" +%s) -eq 1 || error "Date translation does not work"
2008-01-08 19:45:43 +03:00
2009-02-24 18:48:00 +03:00
if [ " $# " -eq 0 ] ; then
2007-12-17 15:31:50 +03:00
tool_usage
fi
2009-02-24 18:48:00 +03:00
while [ " $# " -ne 0 ]
2007-12-17 15:31:50 +03:00
do
2009-02-24 18:48:00 +03:00
case " $1 " in
"" ) ; ;
"-h" | "--help" ) tool_usage ; ;
"-v" | "--verbose" ) VERB = "-v" ; ;
"-n" | "--dry-run" ) DRY = 1 ; ;
"-f" | "--force" ) FORCE = "-f" ; ;
"-e" | "--ext-offline" ) EXTOFF = 1 ; ;
"-y" | "--yes" ) YES = "-y" ; ;
"-l" | "--lvresize" ) DO_LVRESIZE = 1 ; ;
"check" ) CHECK = " $2 " ; shift ; ;
"resize" ) RESIZE = " $2 " ; NEWSIZE = " $3 " ; shift 2 ; ;
*) error " Wrong argument \" $1 \". (see: $TOOL --help) "
2007-12-17 15:31:50 +03:00
esac
shift
done
2012-03-16 16:53:05 +04:00
test " $YES " = "-y" || YES =
test " $EXTOFF " -eq 1 || EXTOFF = 0
2007-12-17 15:31:50 +03:00
if [ -n " $CHECK " ] ; then
check " $CHECK "
elif [ -n " $RESIZE " ] ; then
2008-02-06 15:45:32 +03:00
export FSADM_RUNNING = "fsadm"
2007-12-17 15:31:50 +03:00
resize " $RESIZE " " $NEWSIZE "
else
error " Missing command. (see: $TOOL --help) "
fi