2010-05-14 15:33:20 +04:00
#!/bin/bash
2007-12-17 15:31:50 +03:00
#
2020-10-24 01:42:31 +03:00
# Copyright (C) 2007-2020 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:
2017-10-06 17:28:35 +03:00
# mount, umount, grep, readlink, blockdev, blkid, fsck, xfs_check, cryptsetup
2007-12-17 15:31:50 +03:00
#
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
2020-10-24 02:13:42 +03:00
set -euE -o pipefail
2021-03-15 12:49:47 +03:00
TOOL = "fsadm"
2007-12-17 15:31:50 +03:00
2011-09-19 17:51:09 +04:00
_SAVEPATH = $PATH
2017-06-29 14:15:47 +03:00
PATH = " /sbin:/usr/sbin:/bin:/usr/sbin: $PATH "
2007-12-17 15:31:50 +03:00
# utilities
2021-03-15 12:49:47 +03:00
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"
RMDIR = "rmdir"
BLOCKDEV = "blockdev"
BLKID = "blkid"
DATE = "date"
GREP = "grep"
READLINK = "readlink"
2008-04-29 19:25:28 +04:00
READLINK_E = "-e"
2021-03-15 12:49:47 +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
2021-03-15 12:49:47 +03:00
XFS_REPAIR = "xfs_repair"
CRYPTSETUP = "cryptsetup"
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
2020-10-24 02:13:42 +03: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
2021-03-15 12:49:47 +03:00
FSTYPE = "unknown"
VOLUME = "unknown"
2007-12-17 15:31:50 +03:00
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 =
2017-05-10 16:32:48 +03:00
PROCDIR = "/proc"
PROCMOUNTS = " $PROCDIR /mounts "
PROCSELFMOUNTINFO = " $PROCDIR /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)"
2017-10-06 17:28:35 +03:00
echo " -c | --cryptresize Resize given crypt 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( ) {
2017-06-28 17:13:29 +03:00
test -z " $VERB " || echo " $TOOL : " " $@ "
2007-12-17 15:31:50 +03:00
}
2017-05-10 16:32:48 +03:00
# Support multi-line error messages
2007-12-17 15:31:50 +03:00
error( ) {
2017-05-10 16:32:48 +03:00
for i in " $@ " ; do
echo " $TOOL : $i " >& 2
done
2007-12-17 15:31:50 +03:00
cleanup 1
}
dry( ) {
2008-01-08 19:45:43 +03:00
if [ " $DRY " -ne 0 ] ; then
2017-06-29 17:01:42 +03:00
verbose "Dry execution" " $@ "
2008-01-08 19:45:43 +03:00
return 0
fi
2017-06-29 17:01:42 +03:00
verbose "Executing" " $@ "
2020-10-24 01:42:31 +03:00
$@
}
2024-08-30 00:05:41 +03:00
# Accept as success also return code 1 with fsck
2020-10-24 01:42:31 +03:00
accept_0_1( ) {
$@
local ret = " $? "
test " $ret " -eq 1 || return " $ret "
# Filesystem was corrected
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
2021-02-23 16:14:16 +03:00
test -n " ${ LVM_BINARY - } " && PATH = $_SAVEPATH
lvresize: add new options and defaults for fs handling
The new option "--fs String" for lvresize/lvreduce/lvextend
controls the handling of file systems before/after resizing
the LV. --resizefs is the same as --fs resize.
The new option "--fsmode String" can be used to control
mounting and unmounting of the fs during resizing.
Possible --fs values:
checksize
Only applies to reducing size; does nothing for extend.
Check the fs size and reduce the LV if the fs is not using
the affected space, i.e. the fs does not need to be shrunk.
Fail the command without reducing the fs or LV if the fs is
using the affected space.
resize
Resize the fs using the fs-specific resize command.
This may include mounting, unmounting, or running fsck.
See --fsmode to control mounting behavior, and --nofsck to
disable fsck.
resize_fsadm
Use the old method of calling fsadm to handle the fs
(deprecated.) Warning: this option does not prevent lvreduce
from destroying file systems that are unmounted (or mounted
if prompts are skipped.)
ignore
Resize the LV without checking for or handling a file system.
Warning: using ignore when reducing the LV size may destroy the
file system.
Possible --fsmode values:
manage
Mount or unmount the fs as needed to resize the fs,
and attempt to restore the original mount state at the end.
nochange
Do not mount or unmount the fs. If mounting or unmounting
is required to resize the fs, then do not resize the fs or
the LV and fail the command.
offline
Unmount the fs if it is mounted, and resize the fs while it
is unmounted. If mounting is required to resize the fs,
then do not resize the fs or the LV and fail the command.
Notes on lvreduce:
When no --fs or --resizefs option is specified:
. lvextend default behavior is fs ignore.
. lvreduce default behavior is fs checksize
(includes activating the LV.)
With the exception of --fs resize_fsadm|ignore, lvreduce requires
the recent libblkid fields FSLASTBLOCK and FSBLOCKSIZE.
FSLASTBLOCK*FSBLOCKSIZE is the last byte used by the fs on the LV,
which determines if reducing the fs is necessary.
2022-06-14 23:20:21 +03:00
dry exec " $LVM " lvresize $VERB $FORCE $YES --fs resize_fsadm -L" ${ NEWSIZE_ORIG } 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
2017-06-29 14:15:47 +03:00
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)
2017-06-29 14:15:47 +03:00
NEWBLOCKCOUNT = $(( NEWSIZE / $2 ))
2008-02-06 15:45:32 +03:00
2017-06-29 14:15:47 +03:00
if [ " $DO_LVRESIZE " -eq 1 ] ; then
2008-02-06 15:45:32 +03:00
# start lvresize, but first cleanup mounted dirs
DO_LVRESIZE = 2
cleanup 0
fi
2007-12-17 15:31:50 +03:00
}
2017-05-10 16:32:48 +03:00
decode_major_minor( ) {
# 0x00000fff00 mask MAJOR
# 0xfffff000ff mask MINOR
#MINOR=$(( $1 / 1048576 ))
#MAJOR=$(( ($1 - ${MINOR} * 1048576) / 256 ))
#MINOR=$(( $1 - ${MINOR} * 1048576 - ${MAJOR} * 256 + ${MINOR} * 256))
echo " $(( ( $1 >> 8 ) & 4095 )) : $(( ( ( $1 >> 12 ) & 268435200 ) | ( $1 & 255 ) )) "
}
2007-12-17 15:31:50 +03:00
# detect filesystem on the given device
# dereference device name if it is symbolic link
detect_fs( ) {
2020-10-24 02:13:42 +03:00
test -n " ${ VOLUME_ORIG - } " || 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
2017-05-10 16:13:35 +03:00
# hardcoded /dev since udev does not create these entries elsewhere
2010-10-08 18:55:19 +04:00
/dev/dm-[ 0-9] *)
2017-06-28 17:07:33 +03:00
read -r <" /sys/block/ ${ RVOLUME #/dev/ } /dm/name " SYSVOLUME 2>& 1 && VOLUME = " $DM_DEV_DIR /mapper/ $SYSVOLUME "
read -r <" /sys/block/ ${ RVOLUME #/dev/ } /dev " MAJORMINOR 2>& 1 || error " Cannot get major:minor for \" $VOLUME \". "
2017-05-10 16:23:54 +03:00
MAJOR = ${ MAJORMINOR %% : * }
MINOR = ${ MAJORMINOR ##* : }
2010-10-08 18:55:19 +04:00
; ;
2016-03-18 17:55:36 +03:00
*)
2017-06-29 14:15:47 +03:00
STAT = $( stat --format "MAJOR=\$((0x%t)) MINOR=\$((0x%T))" " $RVOLUME " )
2017-05-09 21:52:15 +03:00
test -n " $STAT " || error " Cannot get major:minor for \" $VOLUME \". "
2017-05-10 16:13:35 +03:00
eval " $STAT "
MAJORMINOR = " ${ MAJOR } : ${ MINOR } "
2016-03-18 17:55:36 +03:00
; ;
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
2021-03-24 18:26:17 +03:00
FSTYPE = $( " $BLKID " -c " $NULL " -s TYPE " $VOLUME " || true )
2017-05-09 21:52:15 +03:00
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 %% \" * }
2017-05-10 16:13:35 +03:00
verbose " \" $FSTYPE \" filesystem found on \" $VOLUME \". "
2007-12-17 15:31:50 +03:00
}
2017-05-10 16:32:48 +03:00
# Check that passed mounted MAJOR:MINOR is not matching $MAJOR:MINOR of resized $VOLUME
validate_mounted_major_minor( ) {
test " $1 " = " $MAJORMINOR " || {
2017-06-28 17:02:13 +03:00
local REFNAME
local CURNAME
2020-10-24 01:40:34 +03:00
REFNAME = $( dmsetup info -c -j " ${ 1 %% : * } " -m " ${ 1 ##* : } " -o name --noheadings 2>" $NULL " )
CURNAME = $( dmsetup info -c -j " $MAJOR " -m " $MINOR " -o name --noheadings 2>" $NULL " )
2017-05-10 16:32:48 +03:00
error " Cannot ${ CHECK +CHECK } ${ RESIZE +RESIZE } device \" $VOLUME \" without umounting filesystem $MOUNTED first. " \
" Mounted filesystem is using device $CURNAME , but referenced device is $REFNAME . " \
"Filesystem utilities currently do not support renamed devices."
}
}
# ATM fsresize & fsck tools are not able to work properly
# when mounted device has changed its name.
# So whenever such device no longer exists with original name
# abort further command processing
check_valid_mounted_device( ) {
local MOUNTEDMAJORMINOR
2017-06-28 17:02:13 +03:00
local VOL
local CURNAME
2017-05-10 16:32:48 +03:00
2017-06-28 17:02:13 +03:00
VOL = $( " $READLINK " $READLINK_E " $1 " )
CURNAME = $( dmsetup info -c -j " $MAJOR " -m " $MINOR " -o name --noheadings)
2017-05-10 16:32:48 +03:00
# more confused, device is not DM....
2020-10-24 02:13:42 +03:00
local SUGGEST = " Possibly device \" $1 \" has been renamed to \" $CURNAME \"? "
2017-05-10 16:32:48 +03:00
test -n " $CURNAME " || SUGGEST = "Mounted volume is not a device mapper device???"
test -n " $VOL " ||
error " Cannot access device \" $1 \" referenced by mounted filesystem \" $MOUNTED \". " \
" $SUGGEST " \
"Filesystem utilities currently do not support renamed devices."
case " $VOL " in
2020-10-24 02:13:42 +03:00
# hardcoded /dev since kernel does not create these entries elsewhere
2017-05-10 16:32:48 +03:00
/dev/dm-[ 0-9] *)
2017-06-28 17:07:33 +03:00
read -r <" /sys/block/ ${ VOL #/dev/ } /dev " MOUNTEDMAJORMINOR 2>& 1 || error " Cannot get major:minor for \" $VOLUME \". "
2017-05-10 16:32:48 +03:00
; ;
*)
STAT = $( stat --format "MOUNTEDMAJORMINOR=\$((0x%t)):\$((0x%T))" " $VOL " )
test -n " $STAT " || error " Cannot get major:minor for \" $VOLUME \". "
eval " $STAT "
; ;
esac
validate_mounted_major_minor " $MOUNTEDMAJORMINOR "
}
2017-05-10 16:13:35 +03:00
detect_mounted_with_proc_self_mountinfo( ) {
2017-05-10 16:32:48 +03:00
# Check self mountinfo
# grab major:minor mounted_device mount_point
2020-10-24 01:40:34 +03:00
MOUNTED = $( " $GREP " " ^[0-9]* [0-9]* $MAJORMINOR " " $PROCSELFMOUNTINFO " 2>" $NULL " | head -1)
2017-05-10 16:32:48 +03:00
# If device is opened and not yet found as self mounted
# check all other mountinfos (since it can be mounted in cgroups)
# Use 'find' to not fail on to long list of args with too many pids
# only 1st. line is needed
test -z " $MOUNTED " &&
2017-06-29 14:15:47 +03:00
test " $( dmsetup info -c --noheading -o open -j " $MAJOR " -m " $MINOR " ) " -gt 0 &&
2020-10-24 01:40:34 +03:00
MOUNTED = $( find " $PROCDIR " -maxdepth 2 -name mountinfo -print0 | xargs -0 " $GREP " " ^[0-9]* [0-9]* $MAJORMINOR " 2>" $NULL " | head -1 2>" $NULL " )
2016-03-18 15:42:06 +03:00
2017-05-10 16:32:48 +03:00
# TODO: for performance compare with sed and stop with 1st. match:
# sed -n "/$MAJORMINOR/ {;p;q;}"
# extract 2nd field after ' - ' separator as mouted device
2017-06-29 14:15:47 +03:00
MOUNTDEV = $( echo " ${ MOUNTED ##* - } " | cut -d ' ' -f 2)
MOUNTDEV = $( echo -n -e " $MOUNTDEV " )
2017-05-10 16:32:48 +03:00
# extract 5th field as mount point
2016-03-18 15:42:06 +03:00
# echo -e translates \040 to spaces
2017-06-29 14:15:47 +03:00
MOUNTED = $( echo " $MOUNTED " | cut -d ' ' -f 5)
MOUNTED = $( echo -n -e " $MOUNTED " )
2016-03-18 15:42:06 +03:00
2017-05-10 16:32:48 +03:00
test -n " $MOUNTED " || return 1 # Not seen mounted anywhere
check_valid_mounted_device " $MOUNTDEV "
2016-03-18 15:42:06 +03:00
}
2010-10-08 18:55:19 +04:00
2017-05-10 16:32:48 +03:00
# With older systems without /proc/*/mountinfo we may need to check
# every mount point as cannot easily depend on the name of mounted
# device (which could have been renamed).
# We need to visit every mount point and check it's major minor
2017-05-10 16:13:35 +03:00
detect_mounted_with_proc_mounts( ) {
2021-03-15 12:49:47 +03:00
MOUNTED = $( " $GREP " " ^ ${ VOLUME } [ \\t] " " $PROCMOUNTS " )
2010-10-08 18:55:19 +04:00
# for empty string try again with real volume name
2021-03-15 12:49:47 +03:00
test -z " $MOUNTED " && MOUNTED = $( " $GREP " " ^ ${ RVOLUME } [ \\t] " " $PROCMOUNTS " )
2010-10-08 18:55:19 +04:00
2017-06-29 14:15:47 +03:00
MOUNTDEV = $( echo -n -e " ${ MOUNTED %% * } " )
2010-10-08 18:55:19 +04:00
# cut device name prefix and trim everything past mountpoint
# echo translates \040 to spaces
MOUNTED = ${ MOUNTED #* }
2017-06-29 14:15:47 +03:00
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
2017-05-10 16:32:48 +03:00
# will not work with spaces in paths
2021-03-15 12:49:47 +03:00
MOUNTED = $( LC_ALL = C " $MOUNT " | " $GREP " " ^ ${ VOLUME } [ \\t] " )
test -z " $MOUNTED " && MOUNTED = $( LC_ALL = C " $MOUNT " | " $GREP " " ^ ${ RVOLUME } [ \\t] " )
2017-05-10 16:32:48 +03:00
MOUNTDEV = ${ MOUNTED %% on * }
2010-11-10 19:14:02 +03:00
MOUNTED = ${ MOUNTED ##* on }
MOUNTED = ${ MOUNTED % type * } # allow type in the mount name
fi
2017-05-10 16:32:48 +03:00
if test -n " $MOUNTED " ; then
check_valid_mounted_device " $MOUNTDEV "
return 0 # mounted
fi
# If still nothing found and volume is in use
# check every known mount point against MAJOR:MINOR
2017-06-29 14:15:47 +03:00
if test " $( dmsetup info -c --noheading -o open -j " $MAJOR " -m " $MINOR " ) " -gt 0 ; then
2017-05-10 16:32:48 +03:00
while IFS = $'\n' read -r i ; do
2017-06-29 14:15:47 +03:00
MOUNTDEV = $( echo -n -e " ${ i %% * } " )
2017-05-10 16:32:48 +03:00
MOUNTED = ${ i #* }
2017-06-29 14:15:47 +03:00
MOUNTED = $( echo -n -e " ${ MOUNTED %% * } " )
STAT = $( stat --format "%d" " $MOUNTED " )
validate_mounted_major_minor " $( decode_major_minor " $STAT " ) "
2017-05-10 16:32:48 +03:00
done < " $PROCMOUNTS "
fi
return 1 # nothing is mounted
2007-12-17 15:31:50 +03:00
}
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
2017-05-10 16:13:35 +03:00
detect_mounted( ) {
2016-03-18 15:42:06 +03:00
if test -e " $PROCSELFMOUNTINFO " ; then
detect_mounted_with_proc_self_mountinfo
elif test -e " $PROCMOUNTS " ; then
detect_mounted_with_proc_mounts
else
2017-05-10 16:13:35 +03:00
error " Cannot detect mounted device \" $VOLUME \". "
2016-03-18 15:42:06 +03:00
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
2020-10-25 22:19:31 +03:00
DEVSIZE = $( " $BLOCKDEV " --getsize64 " $VOLUME " 2>" $NULL " || true )
2021-03-24 18:11:55 +03:00
if test -z " $DEVSIZE " ; then
2020-10-25 22:19:31 +03:00
DEVSIZE = $( " $BLOCKDEV " --getsize " $VOLUME " || true )
2017-05-09 21:52:15 +03:00
test -n " $DEVSIZE " || error " Cannot read size of device \" $VOLUME \". "
2020-10-25 22:19:31 +03:00
SSSIZE = $( " $BLOCKDEV " --getss " $VOLUME " || true )
2017-05-09 21:52:15 +03:00
test -n " $SSSIZE " || error " Cannot read sector size of device \" $VOLUME \". "
2021-04-23 00:22:01 +03:00
DEVSIZE = $(( DEVSIZE * SSSIZE ))
2008-04-29 19:25:28 +04:00
fi
2007-12-17 15:31:50 +03:00
}
# round up $1 / $2
2024-08-30 00:05:41 +03:00
# could be needed to guarantee 'at least given size'
2007-12-17 15:31:50 +03:00
# but it makes many troubles
round_up_block_size( ) {
echo $(( ( $1 + $2 - 1 ) / $2 ))
}
temp_mount( ) {
2017-05-10 16:13:35 +03: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( ) {
2017-05-10 16:13:35 +03: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( ) {
2017-06-29 17:01:42 +03:00
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
2017-05-23 14:58:12 +03:00
"y" | "Y" ) echo y ; return 0 ; ;
2017-06-19 13:37:40 +03:00
"n" | "N" ) break ; ;
2017-05-23 14:58:12 +03:00
"" ) if [ -t 1 ] ; then
echo y ; return 0
fi ; ;
2009-02-24 18:48:00 +03:00
esac
done
2017-05-23 14:58:12 +03:00
echo n
return 1
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
2017-05-10 16:13:35 +03:00
error " Cannot proceed with mounted filesystem \" $MOUNTED \". "
2007-12-17 15:31:50 +03:00
}
validate_parsing( ) {
2017-06-28 17:13:29 +03:00
if test -z " $BLOCKSIZE " || test -z " $BLOCKCOUNT " ; then
error " Cannot parse $1 output. "
fi
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( ) {
2017-05-22 15:39:10 +03:00
local IS_MOUNTED = 0
detect_mounted && IS_MOUNTED = 1
2007-12-17 15:31:50 +03:00
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 "
2017-06-29 14:15:47 +03:00
decode_size " $1 " " $BLOCKSIZE "
2007-12-17 15:31:50 +03:00
FSFORCE = $FORCE
2017-06-28 17:13:29 +03:00
if test " $NEWBLOCKCOUNT " -lt " $BLOCKCOUNT " || test " $EXTOFF " -eq 1 ; then
2017-06-29 14:15:47 +03:00
test " $IS_MOUNTED " -eq 1 && verbose " $RESIZE_EXT needs unmounted filesystem " && try_umount
2007-12-17 15:31:50 +03:00
REMOUNT = $MOUNTED
2010-11-10 19:14:02 +03:00
if test -n " $MOUNTED " ; then
# Forced fsck -f for umounted extX filesystem.
case " $- " in
2020-10-24 01:42:31 +03:00
*i*) FLAG = $YES ; ;
*) FLAG = "-p" ; ;
2010-11-10 19:14:02 +03:00
esac
2020-10-24 01:42:31 +03:00
accept_0_1 dry " $FSCK " -f $FLAG " $VOLUME " || error " Failed to fsck $VOLUME "
2010-11-10 19:14:02 +03:00
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) "
2017-06-29 14:15:47 +03: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 "
2017-06-29 14:15:47 +03:00
decode_size " $1 " " $BLOCKSIZE "
2007-12-17 15:31:50 +03:00
verbose " Resizing \" $VOLUME \" $BLOCKCOUNT -> $NEWBLOCKCOUNT blocks ( $NEWSIZE bytes, bs: $NEWBLOCKCOUNT ) "
if [ -n " $YES " ] ; then
2017-06-29 14:15:47 +03:00
echo y | dry " $RESIZE_REISER " -s " $NEWSIZE " " $VOLUME "
2007-12-17 15:31:50 +03:00
else
2017-06-29 14:15:47 +03: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
2017-05-10 16:13:35 +03:00
temp_mount || error "Cannot mount Xfs filesystem."
2007-12-17 15:31:50 +03:00
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 "
2017-06-29 14:15:47 +03:00
decode_size " $1 " " $BLOCKSIZE "
if [ " $NEWBLOCKCOUNT " -gt " $BLOCKCOUNT " ] ; then
2007-12-17 15:31:50 +03:00
verbose " Resizing Xfs mounted on \" $MOUNTPOINT \" to fill device \" $VOLUME \" "
2017-06-29 14:15:47 +03:00
dry " $RESIZE_XFS " " $MOUNTPOINT "
elif [ " $NEWBLOCKCOUNT " -eq " $BLOCKCOUNT " ] ; then
2007-12-17 15:31:50 +03:00
verbose "Xfs filesystem already has the right size"
else
2017-05-10 16:13:35 +03:00
error "Xfs filesystem shrinking is unsupported."
2007-12-17 15:31:50 +03:00
fi
}
2017-10-06 17:28:35 +03:00
# Find active LUKS device on original volume
# 1) look for LUKS device with well-known UUID format (CRYPT-LUKS[12]-<uuid>-<dmname>)
2024-08-30 00:05:41 +03:00
# 2) the dm-crypt device has to be on top of original device (don't support detached LUKS headers)
2017-10-06 17:28:35 +03:00
detect_luks_device( ) {
2017-10-23 19:11:32 +03:00
local _LUKS_VERSION
local _LUKS_UUID
2017-10-06 17:28:35 +03:00
CRYPT_NAME = ""
CRYPT_DATA_OFFSET = ""
2020-10-24 01:40:34 +03:00
_LUKS_VERSION = $( " $CRYPTSETUP " luksDump " $VOLUME " 2>" $NULL " | " $GREP " "Version:" )
2017-10-06 17:28:35 +03:00
2017-10-11 12:17:36 +03:00
if [ -z " $_LUKS_VERSION " ] ; then
2017-10-06 17:28:35 +03:00
verbose " Failed to parse LUKS version on volume \" $VOLUME \" "
return
fi
_LUKS_VERSION = ${ _LUKS_VERSION //[Version : [ : space : ]]/ }
2020-10-24 01:40:34 +03:00
_LUKS_UUID = $( " $CRYPTSETUP " luksDump " $VOLUME " 2>" $NULL " | " $GREP " "UUID:" )
2017-10-06 17:28:35 +03:00
2017-10-11 12:17:36 +03:00
if [ -z " $_LUKS_UUID " ] ; then
2017-10-06 17:28:35 +03:00
verbose " Failed to parse LUKS UUID on volume \" $VOLUME \" "
return
fi
2017-10-10 16:21:28 +03:00
_LUKS_UUID = " CRYPT-LUKS $_LUKS_VERSION - ${ _LUKS_UUID //[UID : [ : space : ]-]/ } - "
2017-10-06 17:28:35 +03:00
2017-10-10 16:21:28 +03:00
CRYPT_NAME = $( dmsetup info -c --noheadings -S " UUID=~^ $_LUKS_UUID &&segments=1&&devnos_used=' $MAJOR : $MINOR ' " -o name)
2017-11-05 20:22:02 +03:00
test -z " $CRYPT_NAME " || CRYPT_DATA_OFFSET = $( dmsetup table " $CRYPT_NAME " | cut -d ' ' -f 8)
2017-10-11 12:17:36 +03:00
# LUKS device must be active and mapped over volume where detected
2017-11-05 20:22:02 +03:00
if [ -z " $CRYPT_NAME " ] || [ -z " $CRYPT_DATA_OFFSET " ] ; then
2017-10-11 12:17:36 +03:00
error " Can not find active LUKS device. Unlock \" $VOLUME \" volume first. "
fi
2017-10-06 17:28:35 +03:00
}
######################################
# Resize active LUKS device
# - LUKS must be active for fs resize
######################################
resize_luks( ) {
2017-10-23 19:11:32 +03:00
local L_NEWSIZE
local L_NEWBLOCKCOUNT
local NAME
2017-10-06 17:28:35 +03:00
local SHRINK = 0
detect_luks_device
NAME = $CRYPT_NAME
verbose " Found active LUKS device \" $NAME \" for volume \" $VOLUME \" "
decode_size " $1 " 512
if [ $(( NEWSIZE % 512 )) -gt 0 ] ; then
2024-08-30 00:06:04 +03:00
error "New size is not sector aligned."
2017-10-06 17:28:35 +03:00
fi
2017-10-23 16:31:44 +03:00
if [ $(( NEWBLOCKCOUNT - CRYPT_DATA_OFFSET)) -lt 1 ] ; then
error " New size is smaller than minimum ( $(( ( CRYPT_DATA_OFFSET + 1 ) * 512 )) bytes) for LUKS device $VOLUME "
fi
2017-10-23 19:11:32 +03:00
L_NEWBLOCKCOUNT = $(( NEWBLOCKCOUNT - CRYPT_DATA_OFFSET))
L_NEWSIZE = $(( L_NEWBLOCKCOUNT * 512 ))
2017-10-06 17:28:35 +03:00
2017-10-10 18:43:45 +03:00
VOLUME = " $DM_DEV_DIR /mapper/ $NAME "
2017-10-06 17:28:35 +03:00
detect_device_size
2017-10-23 19:11:32 +03:00
test " $DEVSIZE " -le " $L_NEWSIZE " || SHRINK = 1
2017-10-06 17:28:35 +03:00
if [ $SHRINK -eq 1 ] ; then
# shrink fs on LUKS device first
2017-10-23 19:11:32 +03:00
resize " $DM_DEV_DIR /mapper/ $NAME " " $L_NEWSIZE " b
2017-10-06 17:28:35 +03:00
fi
# resize LUKS device
2017-11-05 20:22:02 +03:00
dry " $CRYPTSETUP " resize " $NAME " --size $L_NEWBLOCKCOUNT || error "Failed to resize active LUKS device"
2017-10-06 17:28:35 +03:00
if [ $SHRINK -eq 0 ] ; then
# grow fs on top of LUKS device
2017-10-23 19:11:32 +03:00
resize " $DM_DEV_DIR /mapper/ $NAME " " $L_NEWSIZE " b
2017-10-06 17:28:35 +03:00
fi
}
2017-10-24 12:53:22 +03:00
detect_crypt_device( ) {
local CRYPT_TYPE
local L_NEWSIZE
local TMP
2017-10-06 17:28:35 +03:00
2020-10-24 01:40:34 +03:00
which " $CRYPTSETUP " >" $NULL " 2>& 1 || error " $CRYPTSETUP utility required to resize crypt device "
2017-10-06 17:28:35 +03:00
2020-10-24 01:40:34 +03:00
CRYPT_TYPE = $( " $CRYPTSETUP " status " $1 " 2>" $NULL " | " $GREP " "type:" )
2017-10-06 17:28:35 +03:00
test -n " $CRYPT_TYPE " || error " $CRYPTSETUP failed to detect device type on $1 . "
CRYPT_TYPE = ${ CRYPT_TYPE ##*[[ : space : ]] }
2017-10-24 12:53:22 +03:00
case " $CRYPT_TYPE " in
LUKS[ 12] | PLAIN)
verbose " \" $1 \" crypt device is type $CRYPT_TYPE "
; ;
*)
error " Unsupported crypt type \" $CRYPT_TYPE \" "
esac
2017-10-06 17:28:35 +03:00
2017-10-24 12:53:22 +03:00
TMP = $NEWSIZE
2017-10-06 17:28:35 +03:00
decode_size " $2 " 512
2017-10-24 12:53:22 +03:00
L_NEWSIZE = $NEWSIZE
NEWSIZE = $TMP
2017-10-06 17:28:35 +03:00
2017-10-24 12:53:22 +03:00
if [ $(( L_NEWSIZE % 512 )) -ne 0 ] ; then
2024-08-30 00:06:04 +03:00
error "New size is not sector aligned."
2017-10-06 17:28:35 +03:00
fi
2017-10-24 12:53:22 +03:00
CRYPT_RESIZE_BLOCKS = $NEWBLOCKCOUNT
2017-10-06 17:28:35 +03:00
2017-10-24 12:53:22 +03:00
if [ " $DEVSIZE " -ge " $L_NEWSIZE " ] ; then
CRYPT_SHRINK = 1
else
CRYPT_GROW = 1
2017-10-06 17:28:35 +03:00
fi
2017-10-24 12:53:22 +03:00
}
2017-10-06 17:28:35 +03:00
2017-10-24 12:53:22 +03:00
#################################
# Resize active crypt device
# (on direct user request only)
#################################
resize_crypt( ) {
2017-11-05 20:22:02 +03:00
dry " $CRYPTSETUP " resize " $1 " --size $CRYPT_RESIZE_BLOCKS || error " $CRYPTSETUP failed to resize device $1 "
2017-10-06 17:28:35 +03:00
}
2007-12-17 15:31:50 +03:00
####################
# 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
2020-10-24 02:13:42 +03:00
NEWSIZE_ORIG = ${ NEWSIZE_ORIG :- $NEWSIZE }
2009-06-09 19:31:36 +04:00
IFS = $NL
2020-10-24 02:13:42 +03:00
test -z " ${ DO_CRYPTRESIZE - } " || detect_crypt_device " $VOLUME_ORIG " " $NEWSIZE_ORIG "
test -z " ${ CRYPT_GROW - } " || resize_crypt " $VOLUME_ORIG "
2007-12-17 15:31:50 +03:00
case " $FSTYPE " in
2020-10-24 02:13:42 +03:00
ext[ 234] ) CMD = resize_ext ; ;
"reiserfs" ) CMD = resize_reiser ; ;
"xfs" ) CMD = resize_xfs ; ;
2017-10-06 17:28:35 +03:00
"crypto_LUKS" )
2020-10-24 01:40:34 +03:00
which " $CRYPTSETUP " >" $NULL " 2>& 1 || error " $CRYPTSETUP utility required to resize LUKS volume "
2020-10-24 02:13:42 +03:00
CMD = resize_luks ; ;
2017-05-10 16:13:35 +03:00
*) error " Filesystem \" $FSTYPE \" on device \" $VOLUME \" is not supported by this tool. " ; ;
2020-10-24 02:13:42 +03:00
esac
$CMD $NEWSIZE || error " $FSTYPE resize failed. "
test -z " ${ CRYPT_SHRINK - } " || resize_crypt " $VOLUME_ORIG "
2007-12-17 15:31:50 +03:00
}
2010-11-10 19:14:02 +03:00
####################################
2024-08-30 00:05:41 +03:00
# Calculate 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
}
2017-10-11 12:17:36 +03:00
check_luks( ) {
detect_luks_device
check " $DM_DEV_DIR /mapper/ $CRYPT_NAME "
}
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
2020-10-24 02:13:42 +03:00
ext[ 234] )
2010-11-10 19:14:02 +03:00
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
*)
2017-06-29 14:15:47 +03:00
LASTDIFF = $( diff_dates " $LASTMOUNT " " $LASTCHECKED " )
2010-11-10 19:14:02 +03:00
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
2020-10-24 02:13:42 +03:00
dry " $XFS_CHECK " " $VOLUME " || error "Xfs check failed."
2014-01-20 14:57:39 +04:00
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....
2020-10-24 02:13:42 +03:00
dry " $XFS_REPAIR " -n -o force_geometry " $VOLUME " || error "Xfs repair failed."
2014-01-20 14:57:39 +04:00
fi ; ;
2020-10-24 02:13:42 +03:00
ext[ 234] | "reiserfs" )
2017-10-11 11:20:38 +03:00
# check if executed from interactive shell environment
2010-10-08 19:02:05 +04:00
case " $- " in
2020-10-24 01:42:31 +03:00
*i*) FLAG = $YES ; ;
*) FLAG = "-p" ; ;
esac
accept_0_1 dry " $FSCK " $FORCE $FLAG " $VOLUME " || error " Fsck $FSTYPE failed. "
; ;
2017-10-11 12:17:36 +03:00
"crypto_LUKS" )
2020-10-24 01:40:34 +03:00
which " $CRYPTSETUP " >" $NULL " 2>& 1 || error " $CRYPTSETUP utility required. "
2020-10-24 02:13:42 +03:00
check_luks || error "Crypto luks check failed."
; ;
2017-10-11 11:20:38 +03:00
*)
error " Filesystem \" $FSTYPE \" on device \" $VOLUME \" is not supported by this tool. " ; ;
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
2020-10-24 02:13:42 +03:00
test -n " ${ FSADM_RUNNING - } " && exit 0
2008-02-06 15:45:32 +03:00
2024-08-30 00:05:41 +03:00
# test some prerequisites
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
2017-05-10 16:13:35 +03:00
" $LVM " version >" $NULL " 2>& 1 || error " Could not run lvm binary \" $LVM \". "
2017-06-29 17:04:19 +03:00
" $READLINK " -e / >" $NULL " 2>& 1 || READLINK_E = "-f"
2008-01-08 19:45:43 +03:00
TEST64BIT = $(( 1000 * 1000000000000 ))
2017-05-10 16:13:35 +03:00
test " $TEST64BIT " -eq 1000000000000000 || error "Shell does not handle 64bit arithmetic."
2017-06-29 17:04:19 +03:00
echo Y | " $GREP " Y >" $NULL " || error "Grep does not work properly."
2017-06-29 14:15:47 +03: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
2020-10-24 02:13:42 +03:00
CHECK = ""
RESIZE = ""
2020-12-07 18:16:55 +03:00
NEWSIZE = ""
2020-10-24 02:13:42 +03:00
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 ; ;
2017-10-06 17:28:35 +03:00
"-c" | "--cryptresize" ) DO_CRYPTRESIZE = 1 ; ;
2020-12-07 18:16:55 +03:00
"check" ) test -z " ${ 2 - } " && error " Missing <device>. (see: $TOOL --help) "
CHECK = $2 ; shift ; ;
"resize" ) test -z " ${ 2 - } " && error " Missing <device>. (see: $TOOL --help) "
RESIZE = $2 ; shift
if test -n " ${ 2 - } " ; then NEWSIZE = " ${ 2 - } " ; shift ; fi ; ;
2009-02-24 18:48:00 +03:00
*) error " Wrong argument \" $1 \". (see: $TOOL --help) "
2007-12-17 15:31:50 +03:00
esac
shift
done
2017-07-04 12:55:17 +03:00
test " $YES " = "-y" || YES = ""
2012-03-16 16:53:05 +04:00
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 "
2017-10-06 17:28:35 +03:00
cleanup 0
2007-12-17 15:31:50 +03:00
else
error " Missing command. (see: $TOOL --help) "
fi