Higor Aparecido Vieira Alves
2011-May-25 12:29 UTC
[Ovirt-devel] Hook script to preserve one partition untouched during install
This hook script tries to address the fact that a RHEV-H installation will format all the storage devices available in the machine in order to create HostVG and AppVG with all the available space. It may be the case that RHEV-H needs to respect and co-exist with a proposed partitioning scheme, not getting all the storage space for HostVG and AppVG volume groups. The proposed solution adds the required logic as a hook script to ovirt-config-boot service that is activated only during the end of the installation process (firstboot parameter), right before rebooting into the installed RHEV-H. In high level, this script behaves as the following: a) Consume a kernel parameter that indicates which is the HDD device and partition to preserve. The syntax for this kernel parameter is the following: ignore_vol=/dev/sdb:1 In this example, /dev/sdb is the device, and partition #1 will be left untouched. Notice that the device listed in ignore_vol cannot be present in storage_init also --- devices in storage_init will be formated by the RHEV-H install process. Also, AppVG logical volumes sizes should not be specified in storage_vol kernel parameter. Hence, the RHEV-H installation process will only create HostVG with the device not listed in ignore_vol. b) Implement some partition probe scanning logic that identifies the adjacent partitions to be preserved. Initially this hook script will duplicate some functionalities of the ovirt-config-storage function. Long term, if it integrated into ovirt-config-storage function, then the additional logic is no longer needed. c) With that information, and if required, remove all partitions but the ones set to be preserved. d) Create the AppVG with backup and data partitions on the reminder of the disk (the region with the partitions that were removed) e) Format backup and data partitions f) add data partition to fstab ## ## Partition Script ## #!/bin/bash #VERSION: 0.10 LOG_FILE="/var/log/partition.log" RETURN="" CMDLINE="/proc/cmdline" VG_NAME="AppVG" LV_BACKUP="Backup" LV_BACKUP_SIZE="-l 100%FREE" LV_DATA="Data2" LV_DATA_SIZE="-L 290M" # Write log messages in /var/log/partition # Parameters: # - MSG: Log message log() { local MSG=$1 echo "$MSG" >> $LOG_FILE } # Scan a hard disk to find all available partitions to create # AppVG Volume Group. # Parameter: # - DISK: hard disk to be analized (example, sdb) # - PARTITION: partition number to be preserved (example, 1) # Return: # - ARRAY_PV: array with partitions available disk_scan() { local DISK=$1 local PART=$2 local DM='' local DM_NAME='' local PATTERN='' local DIR='' RETURN='' if [ -z "$DISK" -o -z "$PART" ]; then log "ERROR: $FUNCTION missing parameter" return 1 fi if [ ! -e "/dev/$DISK" -o ! -e "/dev/$DISK$PART" ]; then log "ERROR: $DISK or $DISK$PART not found" return 1 fi DM=$(ls /sys/block/$DISK/holders/) if [ -n "$DM" ]; then log "Found a device mapper assigned to $DISK" DM_NAME=$(cat /sys/block/${DM[0]}/dm/name) if [ $? -ne 0 ]; then log "ERROR: 'name' not present at /sys/block/$DEVICE/dm/name" return 1 fi PATTERN="*""$DM_NAME""p?" DIR="/dev/disk/by-id/" RETURN=( $(find "$DIR" -type l -name "$PATTERN" -regex ".*[^ $PART]$") ) if [ $? -ne 0 ]; then log "ERROR: Can not identify partitions available in $DISK/$DM_NAME" return 1 fi else PATTERN="$DISK?" DIR="/dev/" RETURN=( $(find "$DIR" -type b -name "$PATTERN" -regex ".*[^ $PART]$") ) if [ $? -ne 0 ]; then log "ERROR: Can not identify partitions available in $DISK/$DM_NAME" return 1 fi fi return 0 } main() { local DEVICE='' local IGNORE_VOL='' local VG='' local PV='' local ARRAY_PV='' local OUTPUT='' local DISK'' local PART='' if grep -q "firstboot" $CMDLINE && grep -q "ignore_vol" $CMDLINE; then IGNORE_VOL=$(cat $CMDLINE | sed 's/^.*ignore_vol=//' | awk '{print $1}') else log "Parameters firstboot or ignore_vol not found in $CMDLINE. Aborting" return 1 fi DISK=`echo $IGNORE_VOL | sed -e 's/^\/dev\///' -e 's/:.*$//'\ -e 's/[[:digit:]].*$//'` PART=$(echo $IGNORE_VOL | sed -e 's/^.*://' -e 's/^.*[[:lower:]]//') if ! disk_scan $DISK $PART; then log "ERROR: Can not scan $DISK" return 1 fi ARRAY_PV=${RETURN[*]} if [ ${#ARRAY_PV[*]} -eq 0 ]; then log "ERROR: Partitions not found, verify your disk." return 1 fi for PV in ${ARRAY_PV[*]}; do # Looking if partition has a PV pvs --noheadings "$PV" if [ $? -eq 0 ]; then log "Physical Volume found in $PV" # Looking if PV has Volume Group OUTPUT=( $(pvs --noheadings -o vg_name "$PV") ) if [ ${#OUTPUT[*]} -gt 0 ]; then log "PV $PV has $VG Volume Group" VG=${OUTPUT[0]} # Looking if Volume Group has Logical Volumes OUTPUT=( $(lvs --noheadings -o lv_name "$VG") ) if [ ${#OUTPUT[*]} -gt 0 ]; then log "$VG has Logical Volumes: ${OUTPUT[*]}" log "Removing Logical Volumes" lvremove -ff "$VG" if [ $? -ne 0 ]; then log "Error: Can not remove Logical Volumes" return 1 fi fi log "Removing Volume Group" vgremove -ff "$VG" if [ $? -ne 0 ]; then log "Error: Can not remove Volume Group" return 1 fi fi else log "Creating Physical Volume" pvcreate "$PV" if [ $? -ne 0 ]; then log "Error: Can not create Physical Volume" return 1 fi fi done log "Creating Volume Group" vgcreate "$VG_NAME" "${ARRAY_PV[*]}" if [ $? -ne 0 ]; then log "Error: Can not create Volume Group" return 1 fi log "Creating Logical Volume $LV_DATA" lvcreate ${LV_DATA_SIZE} -n ${LV_DATA} ${VG_NAME} if [ $? -ne 0 ]; then log "Error: Can not create Logical Volume" return 1 fi lvcreate ${LV_BACKUP_SIZE} -n ${LV_BACKUP} ${VG_NAME} if [ $? -ne 0 ]; then log "Error: Can not create Logical Volume" return 1 fi DEVICE="/dev/${VG_NAME}/${LV_BACKUP}" mkfs -t ext4 $DEVICE if [ $? -ne 0 ]; then log "Error: Can not format Logical Volume" return 1 fi DEVICE="/dev/${VG_NAME}/${LV_DATA}" mkfs -t ext4 $DEVICE if [ $? -ne 0 ]; then log "Error: Can not format Logical Volume" return 1 fi if ! grep -q "$DEVICE" /etc/fstab; then log "Automounting $DEVICE..." echo "$DEVICE /data2 ext4 defaults,noatime 0 0" >> /etc/fstab fi } main exit $?
Higor Aparecido Vieira Alves
2011-Jul-18 20:44 UTC
[Ovirt-devel] Hook script to preserve one partition untouched during install
New version of hook script to preserve one partition untouched during install. Changelog: - Can ignore multiple partitions (up to 9) ignore_vol=sda:2;3;4 - New boot parameter, data2_size to set Data2 Size (in MB) data2_size=15000 - Will handle Data2 Logical Volume only instead Data2 and Backup LVs - Set partition type do LVM (partitions used in Data2 LV) #!/bin/bash #VERSION: 0.13 LOG_FILE="/var/log/partition.log" RETURN="" CMDLINE="/proc/cmdline" VG_NAME="AppVG" LV_DATA2="Data2" # Write log messages in /var/log/partition # Parameters: # - MSG: Log message log() { local MSG=$1 echo "$MSG" >> $LOG_FILE } # Scan a hard disk to find all available partitions to create # AppVG Volume Group. # Parameter: # - DISK: hard disk to be analized (example, sdb) # - PARTITION: partition number to be preserved (example, 1) # Return: # - ARRAY_PV: array with partitions available disk_scan() { local DISK=$1 local PART=$2 local DM='' local DM_NAME='' local PATTERN='' local ARRAY='' local REGEX='' local DIR='' local DEVICE='' local NEW_DEVICE='' RETURN='' if [ -z "$DISK" -o -z "$PART" ]; then log "ERROR: $FUNCTION missing parameter" return 1 fi if [ ! -e "/dev/$DISK" ]; then log "ERROR: $DISK not found" return 1 fi DEVICE=$(echo "$PART" | sed 's/;//g') REGEX=".*[a-z][^$DEVICE]$" log "Change the partition type for LVM (8e) in AppVG partitions" PATTERN="$DISK?" DIR="/dev/" ARRAY=( $(find "$DIR" -type b -name "$PATTERN" -regex "$REGEX") ) for DEVICE in ${ARRAY[*]}; do if $(fdisk -l /dev/$DISK | grep -q ".*$DEVICE.*83.*"); then parted /dev/$DISK set ${DEVICE:8} lvm on sleep 10 fi done DM=$(ls /sys/block/$DISK/holders/) if [ -n "$DM" ]; then log "Found a device mapper assigned to $DISK" if grep -q "0QEMU" /sys/block/${DM[0]}/dm/name; then # Remove extra white spaces from device holder name and # change it for "_" log "Using QEMU disks" log "Removing white spaces from device mapper name" DM_NAME=$(cat /sys/block/${DM[0]}/dm/name | sed -e 's/[ ]\ +/ /g' -e 's/ /_/g') OLD_IFS="$IFS" IFS=" " # Create symbolic links whithout white spaces for QEMU disks log "Creating symbolic links without white speaces to QEMU disks" for DEVICE in $(ls /dev/mapper/0QEMU*); do NEW_DEVICE=$(echo $DEVICE | sed -e 's/[ ]\+/ /g' -e 's/ /_/g') ls -s "${DEVICE}" $NEW_DEVICE done IFS="$OLD_IFS" else DM_NAME=$(cat /sys/block/${DM[0]}/dm/name) fi PATTERN="*${DM_NAME}p*" DIR="/dev/disk/by-id/" RETURN=( $(find $DIR -type l -name "$PATTERN" -regex "$REGEX") ) if [ ${#RETURN[*]} -ne 0 ]; then return 0 fi log "Error: Can not find $DISK partitions in /dev/disk/by-id" log "Looking in /dev/mapper" DIR="/dev/mapper" RETURN=( $(find $DIR -type l -name "$PATTERN" -regex "$REGEX") ) if [ ${#RETURN[*]} -eq 0 ]; then log "Error: Can not identify partitions available for $DISK" return 1 fi else PATTERN="$DISK?" DIR="/dev/" RETURN=( $(find "$DIR" -type b -name "$PATTERN" -regex "$REGEX") ) if [ $? -ne 0 ]; then log "ERROR: Can not identify partitions available in $DISK/$DM_NAME" return 1 fi fi return 0 } main() { local DEVICE='' local IGNORE_VOL='' local VG='' local PV='' local ARRAY_PV='' local OUTPUT='' local DISK'' local PART='' local DATA2_SIZE='' local LV_DATA2_SIZE='' if grep -q "firstboot" $CMDLINE && grep -q "ignore_vol" $CMDLINE; then IGNORE_VOL=$(cat $CMDLINE | sed 's/^.*ignore_vol=//' | awk '{print $1}') else log "Parameters firstboot or ignore_vol not found in $CMDLINE. Aborting" return 1 fi DISK=`echo $IGNORE_VOL | sed -e 's/^\/dev\///' -e 's/:.*$//'\ -e 's/[[:digit:]].*$//'` PART=$(echo $IGNORE_VOL | sed -e 's/^.*://' -e 's/^.*[[:lower:]]//') if grep -q "data2_size" $CMDLINE; then DATA2_SIZE=$(cat $CMDLINE | sed 's/^.*data2_size=//' | awk '{print $1}') LV_DATA2_SIZE="-L ${DATA2_SIZE}M" else LV_DATA2_SIZE="-L 290000M" fi if ! disk_scan $DISK $PART; then log "ERROR: Can not scan $DISK" return 1 fi ARRAY_PV=${RETURN[*]} if [ ${#ARRAY_PV[*]} -eq 0 ]; then log "ERROR: Partitions not found, verify your disk." return 1 fi for PV in ${ARRAY_PV[*]}; do # Looking if partition has a PV pvs --noheadings "$PV" if [ $? -eq 0 ]; then log "Physical Volume found in $PV" # Looking if PV has a Volume Group OUTPUT=( $(pvs --noheadings -o vg_name "$PV") ) if [ ${#OUTPUT[*]} -gt 0 ]; then log "PV $PV has a Volume Group" VG=${OUTPUT[0]} # Looking if Volume Group has Logical Volumes OUTPUT=( $(lvs --noheadings -o lv_name "$VG") ) if [ ${#OUTPUT[*]} -gt 0 ]; then log "$VG has Logical Volumes: ${OUTPUT[*]}" log "Removing Logical Volumes" lvremove -ff "$VG" if [ $? -ne 0 ]; then log "Error: Can not remove Logical Volumes" return 1 fi fi log "Removing Volume Group $VG" vgremove -ff "$VG" if [ $? -ne 0 ]; then log "Error: Can not remove Volume Group" return 1 fi fi else log "Creating Physical Volume on $PV" pvcreate "$PV" if [ $? -ne 0 ]; then log "Error: Can not create Physical Volume" return 1 fi fi done log "Creating $VG Volume Group using ${ARRAY_PV[*]}" vgcreate "$VG_NAME" ${ARRAY_PV[*]} if [ $? -ne 0 ]; then log "Error: Can not create Volume Group" return 1 fi log "Creating Logical Volume $LV_DATA2" lvcreate ${LV_DATA2_SIZE} -n ${LV_DATA2} ${VG_NAME} if [ $? -ne 0 ]; then log "Error: Can not create Logical Volume" return 1 fi log "Formating Logical Volume $LV_DATA2" DEVICE="/dev/${VG_NAME}/${LV_DATA2}" mkfs -t ext4 $DEVICE if [ $? -ne 0 ]; then log "Error: Can not format Logical Volume" return 1 fi if ! grep -q "$DEVICE" /etc/fstab; then log "Automounting $DEVICE..." echo "$DEVICE /data2 ext4 defaults,noatime 0 0" >> /etc/fstab fi } main exit $?