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 $?