1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

fsadm: add support for crypt devices

This commit is contained in:
Ondrej Kozina 2017-10-06 16:28:35 +02:00
parent 22789563de
commit 30293baaa0
3 changed files with 146 additions and 5 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.176 - Version 2.02.176 -
=================================== ===================================
Support for encrypted devices in fsadm.
Improve thin pool overprovisioning and repair warning messages. Improve thin pool overprovisioning and repair warning messages.
Version 2.02.175 - 6th October 2017 Version 2.02.175 - 6th October 2017

View File

@ -65,6 +65,11 @@ Be more verbose.
Answer "yes" at any prompts. Answer "yes" at any prompts.
. .
.HP .HP
.BR -c | --cryptresize
.br
Resize dm-crypt mapping together with filesystem detected on the device. The dm-crypt device must be recognizable by cryptsetup(8).
.
.HP
.BR \fInew_size [ B | K | M | G | T | P | E ] .BR \fInew_size [ B | K | M | G | T | P | E ]
.br .br
Absolute number of filesystem blocks to be in the filesystem, Absolute number of filesystem blocks to be in the filesystem,
@ -111,4 +116,5 @@ Defaults to "\fI/dev\fP" and must be an absolute path.
.BR resize_reiserfs (8), .BR resize_reiserfs (8),
.BR xfs_info (8), .BR xfs_info (8),
.BR xfs_growfs (8), .BR xfs_growfs (8),
.BR xfs_check (8) .BR xfs_check (8),
.BR cryptsetup (8)

View File

@ -17,7 +17,7 @@
# Script for resizing devices (usable for LVM resize) # Script for resizing devices (usable for LVM resize)
# #
# Needed utilities: # Needed utilities:
# mount, umount, grep, readlink, blockdev, blkid, fsck, xfs_check # mount, umount, grep, readlink, blockdev, blkid, fsck, xfs_check, cryptsetup
# #
# ext2/ext3/ext4: resize2fs, tune2fs # ext2/ext3/ext4: resize2fs, tune2fs
# reiserfs: resize_reiserfs, reiserfstune # reiserfs: resize_reiserfs, reiserfstune
@ -56,6 +56,7 @@ FSCK=fsck
XFS_CHECK=xfs_check XFS_CHECK=xfs_check
# XFS_REPAIR -n is used when XFS_CHECK is not found # XFS_REPAIR -n is used when XFS_CHECK is not found
XFS_REPAIR=xfs_repair XFS_REPAIR=xfs_repair
CRYPTSETUP=cryptsetup
# user may override lvm location by setting LVM_BINARY # user may override lvm location by setting LVM_BINARY
LVM=${LVM_BINARY:-lvm} LVM=${LVM_BINARY:-lvm}
@ -101,6 +102,7 @@ tool_usage() {
echo " -f | --force Bypass sanity checks" echo " -f | --force Bypass sanity checks"
echo " -n | --dry-run Print commands without running them" echo " -n | --dry-run Print commands without running them"
echo " -l | --lvresize Resize given device (if it is LVM device)" 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 " -y | --yes Answer \"yes\" at any prompts"
echo echo
echo " new_size - Absolute number of filesystem blocks to be in the filesystem," echo " new_size - Absolute number of filesystem blocks to be in the filesystem,"
@ -152,7 +154,7 @@ cleanup() {
export _FSADM_YES _FSADM_EXTOFF export _FSADM_YES _FSADM_EXTOFF
unset FSADM_RUNNING unset FSADM_RUNNING
test -n "$LVM_BINARY" && PATH=$_SAVEPATH test -n "$LVM_BINARY" && PATH=$_SAVEPATH
dry exec "$LVM" lvresize $VERB $FORCE -r -L"${NEWSIZE}b" "$VOLUME_ORIG" dry exec "$LVM" lvresize $VERB $FORCE -r -L"${NEWSIZE_ORIG}b" "$VOLUME_ORIG"
fi fi
# error exit status for break # error exit status for break
@ -196,7 +198,7 @@ decode_major_minor() {
# detect filesystem on the given device # detect filesystem on the given device
# dereference device name if it is symbolic link # dereference device name if it is symbolic link
detect_fs() { detect_fs() {
VOLUME_ORIG=$1 test -n "$VOLUME_ORIG" || VOLUME_ORIG=$1
VOLUME=${1/#"${DM_DEV_DIR}/"/} VOLUME=${1/#"${DM_DEV_DIR}/"/}
VOLUME=$("$READLINK" $READLINK_E "$DM_DEV_DIR/$VOLUME") VOLUME=$("$READLINK" $READLINK_E "$DM_DEV_DIR/$VOLUME")
test -n "$VOLUME" || error "Cannot get readlink \"$1\"." test -n "$VOLUME" || error "Cannot get readlink \"$1\"."
@ -520,6 +522,131 @@ resize_xfs() {
fi fi
} }
# Find active LUKS device on original volume
# 1) look for LUKS device with well-known UUID format (CRYPT-LUKS[12]-<uuid>-<dmname>)
# 2) the dm-crypt device has to be on top of original device (dont't support detached LUKS headers)
detect_luks_device() {
local _LUKS_VERSION=
local _LUKS_UUID=
CRYPT_NAME=""
CRYPT_DATA_OFFSET=""
_LUKS_VERSION=$($CRYPTSETUP luksDump $VOLUME 2> /dev/null | $GREP "Version:")
if [ -z $_LUKS_VERSION ]; then
verbose "Failed to parse LUKS version on volume \"$VOLUME\""
return
fi
_LUKS_VERSION=${_LUKS_VERSION//[Version:[:space:]]/}
_LUKS_UUID=$($CRYPTSETUP luksDump $VOLUME 2> /dev/null | $GREP "UUID:")
if [ -z $_LUKS_UUID ]; then
verbose "Failed to parse LUKS UUID on volume \"$VOLUME\""
return
fi
_LUKS_UUID="CRYPT-LUKS$_LUKS_VERSION-${_LUKS_UUID//[UID:[:space:]-]/}-*"
CRYPT_NAME=$(dmsetup info -c --noheadings -S "UUID=~$_LUKS_UUID&&segments=1&&devnos_used='$MAJOR:$MINOR'" -o name)
test -z "$CRYPT_NAME" || CRYPT_DATA_OFFSET=$(dmsetup table $CRYPT_NAME | cut -d ' ' -f 8)
}
######################################
# Resize active LUKS device
# - LUKS must be active for fs resize
######################################
resize_luks() {
local NEWFSIZE=
local NEWCBLOCKCOUNT=
local NAME=""
local SHRINK=0
detect_luks_device
# LUKS device must be active and mapped over volume where detected
if [ -z "$CRYPT_NAME" -o -z "$CRYPT_DATA_OFFSET" ]; then
error "Can not find active LUKS device. Unlock \"$VOLUME\" volume first."
fi
NAME=$CRYPT_NAME
verbose "Found active LUKS device \"$NAME\" for volume \"$VOLUME\""
decode_size "$1" 512
if [ $((NEWSIZE % 512)) -gt 0 ]; then
error "New size is not sector alligned"
fi
NEWCBLOCKCOUNT=$((NEWBLOCKCOUNT - CRYPT_DATA_OFFSET))
NEWFSIZE=$(( NEWCBLOCKCOUNT * 512))
VOLUME="/dev/mapper/$NAME"
detect_device_size
test "$DEVSIZE" -le "$NEWSIZE" || SHRINK=1
if [ $SHRINK -eq 1 ]; then
# shrink fs on LUKS device first
resize "/dev/mapper/$NAME" "$NEWFSIZE"b
fi
# resize LUKS device
dry $CRYPTSETUP resize $NAME --size $NEWCBLOCKCOUNT || error "Failed to resize active LUKS device"
if [ $SHRINK -eq 0 ]; then
# grow fs on top of LUKS device
resize "/dev/mapper/$NAME" "$NEWFSIZE"b
fi
}
#################################
# Resize active crypt device
# (on direct user request only)
#################################
resize_crypt() {
local CRYPT_TYPE=
local TMP=
local SHRINK=0
which $CRYPTSETUP > /dev/null 2>&1 || error "$CRYPTSETUP utility required to resize LUKS volume"
CRYPT_TYPE=$($CRYPTSETUP status $1 2> /dev/null | $GREP "type:")
test -n "$CRYPT_TYPE" || error "$CRYPTSETUP failed to detect device type on $1."
CRYPT_TYPE=${CRYPT_TYPE##*[[:space:]]}
TMP=$NEWSIZE
decode_size "$2" 512
detect_device_size
if [ "$DEVSIZE" -gt "$NEWSIZE" ]; then
SHRINK=1
fi
NEWSIZE=$TMP
if [ $SHRINK -eq 1 -a -z "$3" ]; then
return
fi
# going to resize, drop the request flag
unset DO_CRYPTRESIZE
case "$CRYPT_TYPE" in
LUKS[12]|PLAIN)
dry $CRYPTSETUP resize "$1" --size $NEWBLOCKCOUNT || error "Failed to resize device $1"
;;
*)
error "Unsupported crypt type \"$CRYPT_TYPE\""
esac
}
#################### ####################
# Resize filesystem # Resize filesystem
#################### ####################
@ -531,14 +658,19 @@ resize() {
# if the size parameter is missing use device size # if the size parameter is missing use device size
#if [ -n "$NEWSIZE" -a $NEWSIZE < #if [ -n "$NEWSIZE" -a $NEWSIZE <
test -z "$NEWSIZE" && NEWSIZE=${DEVSIZE}b test -z "$NEWSIZE" && NEWSIZE=${DEVSIZE}b
test -n "$NEWSIZE_ORIG" || NEWSIZE_ORIG=$NEWSIZE
IFS=$NL IFS=$NL
test -z "$DO_CRYPTRESIZE" || resize_crypt "$VOLUME_ORIG" "$NEWSIZE_ORIG"
case "$FSTYPE" in case "$FSTYPE" in
"ext3"|"ext2"|"ext4") resize_ext $NEWSIZE ;; "ext3"|"ext2"|"ext4") resize_ext $NEWSIZE ;;
"reiserfs") resize_reiser $NEWSIZE ;; "reiserfs") resize_reiser $NEWSIZE ;;
"xfs") resize_xfs $NEWSIZE ;; "xfs") resize_xfs $NEWSIZE ;;
"crypto_LUKS")
which $CRYPTSETUP > /dev/null 2>&1 || error "$CRYPTSETUP utility required to resize LUKS volume"
resize_luks $NEWSIZE ;;
*) error "Filesystem \"$FSTYPE\" on device \"$VOLUME\" is not supported by this tool." ;; *) error "Filesystem \"$FSTYPE\" on device \"$VOLUME\" is not supported by this tool." ;;
esac || error "Resize $FSTYPE failed." esac || error "Resize $FSTYPE failed."
cleanup 0 test -z "$DO_CRYPTRESIZE" || resize_crypt "$VOLUME_ORIG" "$NEWSIZE_ORIG" do_shrink
} }
#################################### ####################################
@ -641,6 +773,7 @@ do
"-e"|"--ext-offline") EXTOFF=1 ;; "-e"|"--ext-offline") EXTOFF=1 ;;
"-y"|"--yes") YES="-y" ;; "-y"|"--yes") YES="-y" ;;
"-l"|"--lvresize") DO_LVRESIZE=1 ;; "-l"|"--lvresize") DO_LVRESIZE=1 ;;
"-c"|"--cryptresize") DO_CRYPTRESIZE=1 ;;
"check") CHECK=$2 ; shift ;; "check") CHECK=$2 ; shift ;;
"resize") RESIZE=$2 ; NEWSIZE=$3 ; shift 2 ;; "resize") RESIZE=$2 ; NEWSIZE=$3 ; shift 2 ;;
*) error "Wrong argument \"$1\". (see: $TOOL --help)" *) error "Wrong argument \"$1\". (see: $TOOL --help)"
@ -656,6 +789,7 @@ if [ -n "$CHECK" ]; then
elif [ -n "$RESIZE" ]; then elif [ -n "$RESIZE" ]; then
export FSADM_RUNNING="fsadm" export FSADM_RUNNING="fsadm"
resize "$RESIZE" "$NEWSIZE" resize "$RESIZE" "$NEWSIZE"
cleanup 0
else else
error "Missing command. (see: $TOOL --help)" error "Missing command. (see: $TOOL --help)"
fi fi