Some useful Logical Volume management procedures
Contents
Create a new logical volume
Set the following environment variables:
X__VOLGROUP=VolGroup00 X__LV_NAME=lv_staging X__LV_SIZE_GB=8 X__MOUNT_POINT=staging
Run the following commands:
X__FS_LABEL=$(echo ${X__LV_NAME:3} | tr '[a-z]' '[A-Z]') [ -d /r ] && X__MNT_PATH=/r || X__MNT_PATH=/tmp lvcreate --size ${X__LV_SIZE_GB}G -n $X__LV_NAME $X__VOLGROUP mke2fs -m0 -j -L $X__FS_LABEL /dev/mapper/$X__VOLGROUP-$X__LV_NAME mkdir $X__MNT_PATH/$X__MOUNT_POINT mount -L $X__FS_LABEL $X__MNT_PATH/$X__MOUNT_POINT echo -e "LABEL=${X__FS_LABEL}\t\t\t$X__MNT_PATH/${X__MOUNT_POINT}\text3\tdefaults 0 2" >>/etc/fstab unset X__VOLGROUP X__LV_NAME X__LV_SIZE_GB X__FS_LABEL X__MOUNT_PATH X__MOUNT_POINT vim /etc/fstab
Increase the size of a logical volume
Set the following environment variables:
X__VOLGROUP=VolGroup00 X__MOUNT_POINT=/srv # or /home for user home directories X__LV_NAME=lv_${X__MOUNT_POINT/\//} X__EXTEND_GB=4
Run the following commands:
X__MNT_PATH= jdf | grep $X__LV_NAME umount $X__MNT_PATH/$X__MOUNT_POINT; RC=$? [ $RC = 0 ] && echo "--- e2fsck" [ $RC = 0 ] && time e2fsck -f -C0 /dev/mapper/$X__VOLGROUP-$X__LV_NAME; RC=$? [ $RC = 0 ] && echo "--- lvresize" [ $RC = 0 ] && time lvresize --size +${X__EXTEND_GB}G --resizefs $X__VOLGROUP/$X__LV_NAME; RC=$? mount $X__MNT_PATH/$X__MOUNT_POINT jdf | grep $X__LV_NAME unset X__VOLGROUP X__MNT_PATH X__MOUNT_POINT X__LV_NAME X__EXTEND_GB
Reduce the size of a logical volume
Set the following environment variables:
X__VOLGROUP=VolGroup00 X__MOUNT_POINT=ci.connect.re-trac.com X__LV_NAME=lv_rt2_ci
Determine the amount of free space currently available on the volume:
jdf | grep -e Filesystem -e $X__LV_NAME
Note the number in the “Used” column. The new size must be no less than this, plus 1 GB, and rounded up to the nearest whole number. For example, if the “Used” column shows 2.7 GB, the new logical volume size can be no less than 4 GB (2.7 + 1 = 3.7, round up to 4.)
Set the following environment variable. Note that we specify the total size of the logical volume as opposed to stating how much we want to remove:
X__NEW_LV_SIZE_GB=7G
Run the following commands:
[ -d /r ] && X__MNT_PATH=/r || X__MNT_PATH=/tmp jdf | grep $X__LV_NAME umount $X__MNT_PATH/$X__MOUNT_POINT; RC=$? [ $RC = 0 ] && echo "--- e2fsck" [ $RC = 0 ] && time e2fsck -f -C0 /dev/mapper/$X__VOLGROUP-$X__LV_NAME; RC=$? [ $RC = 0 ] && echo "--- lvresize" [ $RC = 0 ] && time lvresize --size ${X__NEW_LV_SIZE_GB}G --resizefs $X__VOLGROUP/$X__LV_NAME; RC=$? mount $X__MNT_PATH/$X__MOUNT_POINT jdf | grep $X__LV_NAME [ $RC = 0 ] && unset X__VOLGROUP X__LV_NAME X__MNT_PATH X__MOUNT_POINT X__NEW_LV_SIZE_GB
Move a logical volume from one volume group to another
Set the following environment variables:
X__LV_NAME=lv_vmhost2 X__FROM_VG=VolGroup00 X__TO_VG=VolGroup01
Run the following commands:
# Gather information about the LV X__FS_LABEL="$(e2label /dev/$X__FROM_VG/$X__LV_NAME)" dumpe2fs -h /dev/$X__FROM_VG/$X__LV_NAME 2>/dev/null | grep -q has_journal \ && X__FS_JOURNAL_SW='-j' || X__FS_JOURNAL_SW='' X__LV_SIZE_MB="$(lvs --units m | awk "/$X__LV_NAME/{print substr(\$4,1,length(\$4)-4)}")" jdf | grep $X__LV_NAME # Unmount the current LV umount /dev/mapper/${X__FROM_VG}-${X__LV_NAME} RC=$? # Create a new LV with the same parameters as the old one [ $RC = 0 ] && lvcreate --size ${X__LV_SIZE_MB}M -n $X__LV_NAME $X__TO_VG; RC=$? [ $RC = 0 ] && mke2fs -m0 $X__FS_JOURNAL_SW -L $X__FS_LABEL /dev/$X__TO_VG/$X__LV_NAME; RC=$? # Copy the contents of the old LV to the new [ $RC = 0 ] && (sleep 2; while DDPID=$(pidof dd); do kill -USR1 $DDPID; sleep 10; done) & [ $RC = 0 ] && dd if=/dev/$X__FROM_VG/$X__LV_NAME of=/dev/$X__TO_VG/$X__LV_NAME bs=1M; RC=0 echo "Return code from 'dd' is $RC" # Mark the old volume as unused [ $RC = 0 ] && e2label /dev/$X__FROM_VG/$X__LV_NAME "X_${X__FS_LABEL}"; RC=$? [ $RC = 0 ] && lvchange -a n -f /dev/$X__FROM_VG/$X__LV_NAME; RC=$? [ $RC = 0 ] && lvrename /dev/$X__FROM_VG/$X__LV_NAME ${X__LV_NAME}_moved RC=$? # Mount the new LV [ $RC = 0 ] && mount -a jdf | grep $X__LV_NAME unset X__FROM_VG X__TO_VG X__LV_NAME X__LV_SIZE_MB X__FS_JOURNAL_SW X__FS_LABEL
Note that the above commands do not delete the source LV; it’s merely off-line, so it’s still available if needed.
Backout:
umount /mnt/vmhost2.oliniasystems.com; RC=$? [ $RC = 0 ] && lvremove -f /dev/VolGroup01/lv_vmhost2; RC=$? [ $RC = 0 ] && lvrename /dev/VolGroup00/lv_vmhost2_moved /dev/VolGroup00/lv_vmhost2; RC=$? [ $RC = 0 ] && lvchange -a y /dev/VolGroup00/lv_vmhost2; RC=$? [ $RC = 0 ] && e2label /dev/VolGroup00/lv_vmhost2 VMHOST2; RC=$? [ $RC = 0 ] && mount -L VMHOST2 /mnt/vmhost2.oliniasystems.com
Locate and mount unused logical volumes
(The following script was designed for rbackup)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#!/bin/bash # For each logical volume that is not mounted, creates a mount point for it in # the format '/r/unused-LVs/#-NAME' (where # is the LV's parent VolGroup (0 or # 1) and NAME is the LV's name less the leading 'lv_') and mounts the LV there ULV_PATH="/r/unused-LVs" [ -d $ULV_PATH ] || mkdir $ULV_PATH TEMP_FN='/r/rmount-unused-LVs.tmp' mount | awk -F'[ /-]' '/VolGroup/{print $5 ".*" $4}' >$TEMP_FN lvs | grep -v Attr | grep -v -f $TEMP_FN -e LogVol | awk '{print $2 "/" $1}' | sort | while read LV do MOUNT_PT="$(echo $LV | cut -b10- | tr '/' '-')" MOUNT_PT="$ULV_PATH/${MOUNT_PT/lv_/}" [ -d $MOUNT_PT ] || mkdir $MOUNT_PT echo "mount /dev/$LV $MOUNT_PT" mount /dev/$LV $MOUNT_PT done rm -f $TEMP_FN |
Cleanup:
umount /r/unused-LVs/* && rmdir /r/unused-LVs/* && rmdir /r/unused-LVs