1
     ˆÁÀƒh¹¿¾      0
  #   ˆl–Ãa¾”ªe¶¥6 ¸®2Ê˜´oÁ„N _À¿ ?÷     #!/usr/bin/bash
#
# Copyright (C) 2007-2020 Red Hat, Inc. All rights reserved.
#
# 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,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
# Author: Zdenek Kabelac <zkabelac at redhat.com>
#
# Script for resizing devices (usable for LVM resize)
#
# Needed utilities:
#   mount, umount, grep, readlink, blockdev, blkid, fsck, xfs_check, cryptsetup
#
# ext2/ext3/ext4: resize2fs, tune2fs
# reiserfs: resize_reiserfs, reiserfstune
# xfs: xfs_growfs, xfs_info
#
# Return values:
#   0 success
#   1 error
#   2 break detected
#   3 unsupported online filesystem check for given mounted fs

set -euE -o pipefail

TOOL="fsadm"

_SAVEPATH=$PATH
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"
RMDIR="rmdir"
BLOCKDEV="blockdev"
BLKID="blkid"
DATE="date"
GREP="grep"
READLINK="readlink"
READLINK_E="-e"
FSCK="fsck"
XFS_CHECK="xfs_check"
# XFS_REPAIR -n is used when XFS_CHECK is not found
XFS_REPAIR="xfs_repair"
CRYPTSETUP="cryptsetup"

# user may override lvm location by setting LVM_BINARY
LVM=${LVM_BINARY:-lvm}

YES="${_FSADM_YES-}"
DRY=0
VERB=
FORCE=
EXTOFF=${_FSADM_EXTOFF:-0}
DO_LVRESIZE=0
FSTYPE="unknown"
VOLUME="unknown"
TEMPDIR="${TMPDIR:-/tmp}/${TOOL}_${RANDOM}$$/m"
DM_DEV_DIR="${DM_DEV_DIR:-/dev}"
BLOCKSIZE=
BLOCKCOUNT=
MOUNTPOINT=
MOUNTED=
REMOUNT=
PROCDIR="/proc"
PROCMOUNTS="$PROCDIR/mounts"
PROCSELFMOUNTINFO="$PROCDIR/self/mountinfo"
NULL="$DM_DEV_DIR/null"

IFS_OLD=$IFS
# without bash $'\n'
NL='
'

tool_usage() {
	echo "${TOOL}: Utility to resize or check the filesystem on a device"
	echo
	echo "  ${TOOL} [options] check <device>"
	echo "    - Check the filesystem on device using fsck"
	echo
	echo "  ${TOOL} [options] resize <device> [<new_size>[BKMGTPE]]"
	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"
	echo "    -e | --ext-offline  unmount filesystem before ext2/ext3/ext4 resize"
	echo "    -f | --force        Bypass sanity checks"
	echo "    -n | --dry-run      Print commands without running them"
	echo "    -l | --lvresize     Resize given device (if it is LVM device)"
	echo "    -c | --cryptresize  Resize given crypt device"
	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."

	exit
}

verbose() {
	test -z "$VERB" || echo "$TOOL:" "$@"
}

# Support multi-line error messages
error() {
	for i in "$@" ;  do
		echo "$TOOL: $i" >&2
	done
	cleanup 1
}

dry() {
	if [ "$DRY" -ne 0 ]; then
		verbose "Dry execution" "$@"
		return 0
	fi
	verbose "Executing" "$@"
	$@
}

# Accept as success also return code 1 with fsck
accept_0_1() {
	$@
	local ret="$?"
	test "$ret" -eq 1 || return "$ret"
	# Filesystem was corrected
}

cleanup() {
	trap '' 2
	# reset MOUNTPOINT - avoid recursion
	test "$MOUNTPOINT" = "$TEMPDIR" && MOUNTPOINT="" temp_umount
	if [ -n "$REMOUNT" ]; then
		verbose "Remounting unmounted filesystem back"
		dry "$MOUNT" "$VOLUME" "$MOUNTED"
	fi
	IFS=$IFS_OLD
	trap 2

	test "$1" -eq 2 && verbose "Break detected"

	if [ "$DO_LVRESIZE" -eq 2 ]; then
		# start LVRESIZE with the filesystem modification flag
		# and allow recursive call of fsadm
		_FSADM_YES=$YES
		_FSADM_EXTOFF=$EXTOFF
		export _FSADM