|
|
#!/bin/bash
###############################################################################
# GLOBALS
#
# flag file containing pids of running instances for concurrency checks
declare -rg OPENSLX_DISK_FLAG="/tmp/openslx.disk"
# file that will contain the name of the device used for the /tmp partition
# - label 'OPENSLX_TMP' in GPT / type '0x44' in MBR
declare -rg OPENSLX_TMP_MARKER="/tmp/openslx.disk.tmp"
# file that will contain the name of the device used for storing qcow2
# - label 'OPENSLX_SYS' in GPT / type '0x46' in MBR
declare -rg OPENSLX_SYS_MARKER="/tmp/openslx.disk.sys"
# mount point for system partition
declare -rg OPENSLX_SYS_MOUNT="/opt/openslx/system"
#
# END GLOBALS
###############################################################################
###############################################################################
# FUNCTION DEFINITIONS
#
# helper to mount the OPENSLX_SYS partition to /opt/openslx/system
# Usage: mount_sys_part <path_to_sys_partition>
mount_sys_part() {
if [ ! -b "$1" ]; then
warn "($$) Refusing to mount '$1' as its not a block device!"
return 1
fi
local OPENSLX_SYS_DEVICE="$1"
mkdir -p ${OPENSLX_SYS_MOUNT}
if ! mount -t auto "${OPENSLX_SYS_DEVICE}" "${OPENSLX_SYS_MOUNT}"; then
warn "($$) Mounting '${OPENSLX_SYS_DEVICE}' to '${OPENSLX_SYS_MOUNT}' failed."
return 1
fi
return 0
}
#
# generic helper to format the given partition with the given filesystem or
# from the prefdefined list of xfs, ext4, ...
# Usage: format_disk <dev> <fs>
# e.g. format_disk /dev/sda1 xfs
format_disk () {
local TARGET_DEVICE="$1"
local fslist="xfs ext4"
# if we have a second arguments, its the filesystem of choice
local fs
[ $# -ge 2 ] && fslist="$2"
for fs in $fslist ; do
unset found
local MKFS="$(busybox which mkfs.$fs)"
if [ -n $MKFS ]; then
found=yes
case "mkfs.$fs" in
mkfs.xfs) fopt="-fq" ;;
mkfs.ext4) fopt="-Fq" ;;
esac
info "($$) Formatting $TARGET_DEVICE as $fs"
return $(${MKFS} ${fopt} "${TARGET_DEVICE}")
fi
[ -n "$found" ] && break
done
# still here? then we didn't find a proper formatter...
warn "($$) Could not format $PART_DEV as $fs."
return 1
}
#
# END FUNCTION DEFINITIONS
###############################################################################
###############################################################################
# MAIN CODE
#
command -v warn >/dev/null || . /lib/dracut-lib.sh
# let check the arguments
if [ "$#" -ne 2 ]; then
warn "($$) '$0' need 2 arguments: '$0 [OPENSLX_SYS|OPENSLX_TMP] <dev_path>'"
exit 1
fi
# $1 sane?
if [ "x$1" != "xOPENSLX_SYS" ] && [ "x$1" != "xOPENSLX_TMP" ]; then
warn "($$) First arg needs to be either 'OPENSLX_SYS' or 'OPENSLX_TMP', given: $1"
exit 1
fi
# $2 sane?
if [ ! -b "/dev/$2" ]; then
warn "($$) Second arg appears not to be a block device!"
exit 1
fi
# ok all seems well, set the arguments
PART_TYPE="$1"
PART_DEV="/dev/$2"
unset OPENSLX_TMP_DEVICE
unset OPENSLX_SYS_DEVICE
# lets check if we are already running
INSTANCES="$(grep "$PART_TYPE" "$OPENSLX_DISK_FLAG" | busybox wc -l)"
if [ "$INSTANCES" -ge 1 ]; then
# uhoh we are not alone! Need to check
# if the other instance actually did its job
warn "($$) '$0' already running for $PART_TYPE on $PART_DEV... checking state."
# here two/three cases depending on which PART_TYPE we are
# currently processing.
for timeout in 1 1 2; do
# always give the other instance time to finish
# but only check 3 times overall
sleep $timeout
case "$PART_TYPE" in
OPENSLX_TMP)
# was the tmp partition marker created with a device?
if [ ! -f "${OPENSLX_TMP_MARKER}" ]; then
info "($$) Invalid state: no marker for $PART_TYPE"
continue
fi
# it was, is it a valid block device?
OPENSLX_TMP_DEVICE="$(cat ${OPENSLX_TMP_MARKER})"
if [ -z $OPENSLX_TMP_DEVICE -o ! -b $OPENSLX_TMP_DEVICE ]; then
info "($$) Invalid state: no for device $OPENSLX_TMP_DEVICE"
continue
fi
# its detected, its a block device and as mounting is
# done later, we can not check for more at this point
info "($$) Valid state for $OPENSLX_TMP_DEVICE as $PART_TYPE"
exit 0
;;
OPENSLX_SYS)
# was the system partition marker created with a device?
if [ ! -f "${OPENSLX_SYS_MARKER}" ]; then
info "($$) Invalid state: no marker for $PART_TYPE"
continue
fi
# it was, is it a valid block device?
OPENSLX_SYS_DEVICE="$(cat ${OPENSLX_SYS_MARKER})"
if [ -z $OPENSLX_SYS_DEVICE -o ! -b $OPENSLX_SYS_DEVICE ]; then
info "($$) Invalid state: no for device $OPENSLX_SYS_DEVICE"
continue
fi
# its detected, its a block device, is it mounted?
if mount | grep -qE "^$OPENSLX_SYS_DEVICE\ on $OPENSLX_SYS_MOUNT"; then
info "($$) Valid state for $OPENSLX_SYS_DEVICE as $PART_TYPE"
exit 0
fi
# if its not mounted, we want to keep on, so no exit!
;;
*)
# weird case which should never happen
warn "($$) If you see this, then $0 was called with a bad PART_TYPE: $@"
continue
;;
esac
done
warn "($$) Timeout reached!"
warn "($$) '$PART_TYPE' was found but not device was associated to it!"
fi
# We write our pid to $OPENSLX_DISK_FLAG in order to make sure
# we are the only instance of this script running.
info "($$) Processing: $PART_TYPE -> $PART_DEV ($$)"
echo "$PART_TYPE.$$" >> "$OPENSLX_DISK_FLAG"
# if we are still here, then we can go on and process the partition
if [ "$PART_TYPE" = "OPENSLX_TMP" ]; then
# always format /tmp partition
if ! format_disk "${PART_DEV}" xfs; then
# error while formatting, cleanup
warn "($$) Error formatting $PART_DEV ... removing $$"
sed -i "/^${PART_TYPE}\.$$/d" "${OPENSLX_DISK_FLAG}"
exit 1
fi
info "($$) Using '$PART_DEV' as '$PART_TYPE'"
# mark it for later: in pre-pivot we will check this file
# and mount it as $NEWROOT/tmp
echo "$PART_DEV" > "$OPENSLX_TMP_MARKER"
# remove our pid from OPENSLX_DISK_FLAG
sed -i "/^${PART_TYPE}\.$$/d" "${OPENSLX_DISK_FLAG}"
exit 0
fi
if [ "$PART_TYPE" = "OPENSLX_SYS" ]; then
# TODO make the formatting of the system partition configurable
if ! format_disk "${PART_DEV}" xfs; then
# error while formatting, cleanup
warn "($$) Error formatting $PART_DEV ... removing $$"
sed -i "/^${PART_TYPE}\.$$/d" "${OPENSLX_DISK_FLAG}"
exit 1
fi
# mark it
# mount it now, since qemu-nbd needs it asap!
if mount_sys_part "$PART_DEV"; then
# mount worked, mark it as done
info "($$) Using '$PART_DEV' as '$PART_TYPE'"
echo "$PART_DEV" > "$OPENSLX_SYS_MARKER"
sed -i "/^${PART_TYPE}\.$$/d" "${OPENSLX_DISK_FLAG}"
exit 0
else
warn "($$) 'mount_sys_part' failed in $0"
sed -i "/^${PART_TYPE}\.$$/d" "${OPENSLX_DISK_FLAG}"
exit 1
fi
fi
#
# END MAIN CODE
###############################################################################
|