Skip to content

Commit

Permalink
s390x: add support for zFCP SCSI devices on zVM and LPAR
Browse files Browse the repository at this point in the history
Significant changes include :

- zFCP SCSI devices cannot be dd directly from qemu raw image, but dd
each partition. Thus we have to extract the image, read and apply
partition table accordingly, then dd partitions. Also remount tmpfs
according to the size of decompressed image. Another good approach is
using `sgdisk -R` which copies the whole GPT disk.

- dracut-cmdline-ask.service is required on s390x, adding it at boot
time (via generator) rather than hardcode in .target file affecting
other arches.

- write_bootloader(): chreipl to target disk at the end of the
installation so in the next reboot, that disk will be in first priority.
  • Loading branch information
tuan-hoang1 committed Sep 25, 2019
1 parent 1f51ca6 commit 49eb2de
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 17 deletions.
111 changes: 94 additions & 17 deletions coreos-installer
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ ZskQ/mDUv6F4w6N8Vk9R/nJTfpI36vWTcH7xxLNoNRlL2b/7ra6dB8YPsOdLy158
-----END PGP PUBLIC KEY BLOCK-----
"

arch=$(uname -m)
imagefile="/mnt/dl/imagefile"
imagefile_compressed="/mnt/dl/imagefile.compressed"
imagefile_compressed_sig="/mnt/dl/imagefile.compressed.sig"
Expand Down Expand Up @@ -574,8 +575,13 @@ get_ignition_url() {
#########################################################
mount_tmpfs() {
log "Mounting tmpfs"
if [ -n "$1" ]; then
options="remount,size=${1}m"
else
options="size=${TMPFS_MBSIZE}m"
fi
mkdir -p /mnt/dl
mount -t tmpfs -o size=${TMPFS_MBSIZE}m tmpfs /mnt/dl
mount -t tmpfs -o "$options" tmpfs /mnt/dl
}

#########################################################
Expand Down Expand Up @@ -603,6 +609,18 @@ download_image() {
log "Image download failed"
exit 1
fi

# Check for gzip and xz correspondingly
if [ "$(dd count=2 bs=1 if=${imagefile_compressed} status=none)" = "$(printf '\x1f\x8b')" ]
then
DECOMPRESSION_TOOL='zcat'
elif [ "$(dd count=5 bs=1 if=${imagefile_compressed} status=none)" = "$(printf '\xfd\x37\x7a\x58\x5a')" ]
then
DECOMPRESSION_TOOL='xzcat'
else
log "Compressed file format is not supported. Supported formats: '.xz', '.gz'"
exit 1
fi
}

#########################################################
Expand Down Expand Up @@ -664,31 +682,87 @@ log() {
echo "$1" >&2
}

#########################################################
#Update bootloader if needed
#########################################################
write_bootloader() {
if [[ "$arch" == "s390x" ]]; then
log "Updating zipl"
mkdir -p /mnt/boot_partition
mount_boot_partition /mnt/boot_partition
trap 'umount /mnt/boot_partition; trap - RETURN' RETURN

blsfile=$(ls /mnt/boot_partition/loader/entries/*.conf)
echo "$(grep options $blsfile | cut -d' ' -f2-) $(cat /tmp/s390x_opts) ignition.firstboot rd.neednet=1 ip=dhcp" > /tmp/zipl_prm
zipl --verbose -p /tmp/zipl_prm -i $(ls /mnt/boot_partition/ostree/*/*vmlinuz*) -r $(ls /mnt/boot_partition/ostree/*/*initramfs*) --target /mnt/boot_partition
if [[ $? -ne 0 ]]; then
log "failed updating bootloder"
exit 1
fi
# this allows a reboot into new installed disk
chreipl "${DEST_DEV}"
fi
}
#########################################################
#Handle s390x zFCP SCSI devices
#########################################################
write_image_to_zfcp_disk() {
log "Extracting disk image"
mount_tmpfs $(( $($DECOMPRESSION_TOOL ${imagefile_compressed} | wc --bytes) / 1024 / 1024 + ${TMPFS_MBSIZE} ))
$DECOMPRESSION_TOOL ${imagefile_compressed} > ${imagefile}

(while IFS='' read -r line || [ -n "$line" ]
do
if [[ $line =~ "start=" ]]
then
# we save the start= and size= here, then dd the partitions later
printf "%s:%s\n" \
"$(echo $line | cut -d: -f 2 | cut -d, -f 1 | tr -d ' ')" \
"$(echo $line | cut -d: -f 2 | cut -d, -f 2 | tr -d ' ')" \
>> /tmp/sfdisk_info
elif ! [[ $line =~ "label:" || $line =~ "label-id:" || $line =~ "unit:" ]]
then
continue
fi
echo $line
done <<< $(sfdisk -d ${imagefile})
) | sfdisk "${DEST_DEV}"

while IFS='' read -r line || [ -n "$line" ]
do
eval ${line%%:*} ${line##*:}
dd if=${imagefile} bs=512 iflag=fullblock \
of="${DEST_DEV}" status=progress skip=$start seek=$start count=$size
if [[ $? -ne 0 ]]; then
log "failed to write image to zFCP SCSI disk"
exit 1
fi
done < /tmp/sfdisk_info
}
#########################################################
#And Write the image to disk
#########################################################
write_image_to_disk() {
log "Writing disk image"

set -o pipefail
# Check for gzip and xz correspondingly
if [ "$(dd count=2 bs=1 if=${imagefile_compressed} status=none)" = "$(printf '\x1f\x8b')" ]
if [[ "$arch" == "aarch64" || "$arch" == "ppc64le" || "$arch" == "x86_64" ]]
then
DECOMPRESSION_TOOL='zcat'
elif [ "$(dd count=5 bs=1 if=${imagefile_compressed} status=none)" = "$(printf '\xfd\x37\x7a\x58\x5a')" ]
$DECOMPRESSION_TOOL ${imagefile_compressed} |\
dd bs=1M iflag=fullblock oflag=direct conv=sparse of="${DEST_DEV}" status=none
RETCODE=$?
if [[ $RETCODE -ne 0 ]]; then
log "failed to write image to disk"
exit 1
fi
elif [[ "$arch" == "s390x" ]]
then
DECOMPRESSION_TOOL='xzcat'
else
log "Compressed file format is not supported. Supported formats: '.xz', '.gz'"
exit 1
fi

$DECOMPRESSION_TOOL ${imagefile_compressed} |\
dd bs=1M iflag=fullblock oflag=direct conv=sparse of="${DEST_DEV}" status=none
RETCODE=$?
if [[ $RETCODE -ne 0 ]]; then
log "failed to write image to disk"
exit 1
case $(systemd-detect-virt) in
none|zvm) # 'none' means LPAR
write_image_to_zfcp_disk
;;
qemu) log "Use qcow images for KVM s390x installation instead"; exit 1 ;;
esac
fi
set +o pipefail

Expand Down Expand Up @@ -790,6 +864,9 @@ main() {
# If ignition platform id is provided, overwrite ignition.platform.id in BLS
write_platform_id

# If updating bootloader records is required
write_bootloader

log "Install complete"
}

Expand Down
5 changes: 5 additions & 0 deletions dracut/30coreos-installer/coreos-installer-generator
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ cmdline_arg() {
echo "${value}"
}

# allow adding boot parameters at boot time
if [[ $(uname -m) == "s390x" ]]; then
echo -e '\nRequires=dracut-cmdline-ask.service\nAfter=dracut-cmdline-ask.service' >> /usr/lib/systemd/system/coreos-installer.target
fi

if [[ $(cmdline_arg coreos.inst) == "yes" ]]; then
ln -sf "/usr/lib/systemd/system/coreos-installer.target" \
"${UNIT_DIR}/default.target"
Expand Down
9 changes: 9 additions & 0 deletions dracut/30coreos-installer/module-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ install() {
inst_multiple /usr/sbin/blockdev
inst_multiple /usr/sbin/wipefs

if [ "$arch" = "s390x" ]; then
inst_multiple -o /usr/bin/wc
inst_multiple -o /usr/sbin/zipl
inst_multiple -o /usr/sbin/chreipl
inst_multiple -o /usr/sbin/chzdev
inst_multiple -o /usr/sbin/sfdisk
inst_multiple -o /lib/s390-tools/stage3.bin
fi

inst_simple /usr/libexec/coreos-installer

inst_simple "$moddir/coreos-installer-generator" \
Expand Down
18 changes: 18 additions & 0 deletions dracut/30coreos-installer/parse-coreos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,24 @@ then
echo "${NETWORKING_ARGS}" >> /tmp/networking_opts
fi

# Preserve s390x-specific user-provided parameters for zipl
local S390X_ALL_ARGS=
declare -a DRACUT_S390X_ARGS=("rd.dasd=" "rd.zfcp=" "rd.znet=" "zfcp.allow_lun_scan=" "cio_ignore=")
for S390X_ARG in "${DRACUT_S390X_ARGS[@]}"
do
S390X_OPT=$(getarg $S390X_ARG)
if [ ! -z "$S390X_OPT" ]
then
echo "persist $S390X_ARG to $S390X_OPT" >> /tmp/debug
S390X_ALL_ARGS+=" ${S390X_ARG}${S390X_OPT}"
fi
done
if [ -n "${S390X_ALL_ARGS}" ]
then
echo "persisting s390x options: ${S390X_ALL_ARGS}" >> /tmp/debug
echo "${S390X_ALL_ARGS}" >> /tmp/s390x_opts
fi

if getargbool 0 coreos.inst.skip_media_check
then
echo "Asserting skip of media check" >> /tmp/debug
Expand Down

0 comments on commit 49eb2de

Please sign in to comment.