-
Notifications
You must be signed in to change notification settings - Fork 99
s390x: add support for zFCP SCSI and ECKD DASD devices on zVM and LPAR #61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
e95ed0e
coreos-installer: add failure check for lsblk
tuan-hoang1 ae92aa1
coreos-installer: use variables instead of hardcoding
tuan-hoang1 b54b89c
add support for zFCP SCSI devices on zVM and LPAR
tuan-hoang1 6e11265
add support for ECKD DASD devices on zVM and LPAR
tuan-hoang1 669c8e6
s390x: adapt the partition layout for both fcos and rhcos-4.2
tuan-hoang1 f8d142c
s390x: write s390x opts to BLS file, respect networking opts
tuan-hoang1 bb9bc4b
s390x: parse multiple instances of the same cmdline parameters
tuan-hoang1 85269b8
coreos-installer: allow install bare metal raw image on KVM
tuan-hoang1 868e38d
coreos-installer: dd status=none
tuan-hoang1 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -294,6 +294,12 @@ ZskQ/mDUv6F4w6N8Vk9R/nJTfpI36vWTcH7xxLNoNRlL2b/7ra6dB8YPsOdLy158 | |
| -----END PGP PUBLIC KEY BLOCK----- | ||
| " | ||
|
|
||
| arch=$(uname -m) | ||
| boot_partition="/mnt/boot_partition" | ||
| tmpfs_mountpoint="/mnt/dl" | ||
| imagefile="$tmpfs_mountpoint/imagefile" | ||
| imagefile_compressed="$tmpfs_mountpoint/imagefile.compressed" | ||
| imagefile_compressed_sig="$tmpfs_mountpoint/imagefile.compressed.sig" | ||
|
|
||
| ############################################################ | ||
| # Helper to mount the boot partition from the device | ||
|
|
@@ -313,16 +319,14 @@ mount_boot_partition() { | |
| # The first command will find the partition with the boot label | ||
| # and the eval command will set the $UUID variable that we use later. | ||
| set -o pipefail | ||
| output=$(lsblk "${DEST_DEV}" --output NAME,LABEL,UUID --pairs | grep 'LABEL="boot"') | ||
| eval $(echo $output | tr ' ' '\n' | tail -n 1) | ||
| set +o pipefail | ||
|
|
||
| let retry=0 | ||
| while true | ||
| do | ||
| mount "/dev/disk/by-uuid/${UUID}" /mnt/boot_partition | ||
| output=$(lsblk "${DEST_DEV}" --output NAME,LABEL,UUID --pairs | grep 'LABEL="boot"') | ||
| eval $(echo $output | tr ' ' '\n' | tail -n 1) | ||
| mount "/dev/disk/by-uuid/${UUID}" "$boot_partition" | ||
| RETCODE=$? | ||
| if [[ $RETCODE -ne 0 ]]; then | ||
| if [[ -z "$output" ]] || [[ $RETCODE -ne 0 ]]; then | ||
| if [[ $retry -lt 30 ]]; then | ||
| # retry and sleep to allow udevd to populate /dev/disk/by-uuid | ||
| sleep 1 | ||
|
|
@@ -334,6 +338,7 @@ mount_boot_partition() { | |
| fi | ||
| break; | ||
| done | ||
| set +o pipefail | ||
| } | ||
|
|
||
| ############################################################ | ||
|
|
@@ -347,12 +352,12 @@ write_ignition_file() { | |
|
|
||
| log "Embedding provided Ignition config" | ||
| # mount the boot partition | ||
| mkdir -p /mnt/boot_partition | ||
| mount_boot_partition /mnt/boot_partition | ||
| trap 'umount /mnt/boot_partition; trap - RETURN' RETURN | ||
| mkdir -p "$boot_partition" | ||
| mount_boot_partition "$boot_partition" | ||
| trap 'umount $boot_partition; trap - RETURN' RETURN | ||
|
|
||
| mkdir -p /mnt/boot_partition/ignition | ||
| cp /tmp/ignition.ign /mnt/boot_partition/ignition/config.ign | ||
| mkdir -p "${boot_partition}/ignition" | ||
| cp /tmp/ignition.ign "${boot_partition}/ignition/config.ign" | ||
| RETCODE=$? | ||
| if [[ $RETCODE -ne 0 ]]; then | ||
| log "failed writing ignition config" | ||
|
|
@@ -371,11 +376,11 @@ write_networking_opts() { | |
|
|
||
| log "Embedding provided networking options" | ||
| # check for the boot partition | ||
| mkdir -p /mnt/boot_partition | ||
| mount_boot_partition /mnt/boot_partition | ||
| trap 'umount /mnt/boot_partition; trap - RETURN' RETURN | ||
| mkdir -p "$boot_partition" | ||
| mount_boot_partition "$boot_partition" | ||
| trap 'umount $boot_partition; trap - RETURN' RETURN | ||
|
|
||
| echo "set ignition_network_kcmdline=\"$(cat /tmp/networking_opts)\"" >> /mnt/boot_partition/ignition.firstboot | ||
| echo "set ignition_network_kcmdline=\"$(cat /tmp/networking_opts)\"" >> "${boot_partition}/ignition.firstboot" | ||
| } | ||
|
|
||
| ######################################################### | ||
|
|
@@ -394,10 +399,10 @@ write_platform_id() { | |
|
|
||
| log "Overwriting ignition platform id" | ||
| # check for the boot partition | ||
| mkdir -p /mnt/boot_partition | ||
| mount_boot_partition /mnt/boot_partition | ||
| trap 'umount /mnt/boot_partition; trap - RETURN' RETURN | ||
| local conf_files=$(ls /mnt/boot_partition/loader/entries/*conf) | ||
| mkdir -p "$boot_partition" | ||
| mount_boot_partition "$boot_partition" | ||
| trap 'umount $boot_partition; trap - RETURN' RETURN | ||
| local conf_files=$(ls ${boot_partition}/loader/entries/*conf) | ||
|
|
||
| for f in $conf_files | ||
| do | ||
|
|
@@ -425,11 +430,11 @@ write_additional_opts() { | |
|
|
||
| log "Embedding provided additional options" | ||
| # check for the boot partition | ||
| mkdir -p /mnt/boot_partition | ||
| mount_boot_partition /mnt/boot_partition | ||
| trap 'umount /mnt/boot_partition; trap - RETURN' RETURN | ||
| mkdir -p "$boot_partition" | ||
| mount_boot_partition "$boot_partition" | ||
| trap 'umount $boot_partition; trap - RETURN' RETURN | ||
|
|
||
| echo "set ignition_extra_kcmdline=\"$(cat /tmp/additional_opts)\"" >> /mnt/boot_partition/ignition.firstboot | ||
| echo "set ignition_extra_kcmdline=\"$(cat /tmp/additional_opts)\"" >> "${boot_partition}/ignition.firstboot" | ||
| } | ||
|
|
||
| ############################################################ | ||
|
|
@@ -572,24 +577,29 @@ get_ignition_url() { | |
| ######################################################### | ||
| mount_tmpfs() { | ||
| log "Mounting tmpfs" | ||
| mkdir -p /mnt/dl | ||
| mount -t tmpfs -o size=${TMPFS_MBSIZE}m tmpfs /mnt/dl | ||
| if [ -n "$1" ]; then | ||
| options="remount,size=${1}m" | ||
| else | ||
| options="size=${TMPFS_MBSIZE}m" | ||
| fi | ||
| mkdir -p "$tmpfs_mountpoint" | ||
| mount -t tmpfs -o "$options" tmpfs "$tmpfs_mountpoint" | ||
| } | ||
|
|
||
| ######################################################### | ||
| #And Get the Image | ||
| ######################################################### | ||
| download_image() { | ||
| log "Downloading install image" | ||
| (curl -L -s -o /mnt/dl/imagefile.compressed $IMAGE_URL; echo $? > /tmp/curl-rc) & | ||
| (curl -L -s -o ${imagefile_compressed} $IMAGE_URL; echo $? > /tmp/curl-rc) & | ||
|
|
||
| while [ ! -f /tmp/curl-rc ]; do | ||
| # If the image hasn't show up yet then wait a sec and loop | ||
| if [ ! -f /mnt/dl/imagefile.compressed ]; then | ||
| if [ ! -f ${imagefile_compressed} ]; then | ||
| sleep 1 | ||
| continue | ||
| fi | ||
| PART_FILE_SIZE=$(ls -l /mnt/dl/imagefile.compressed | awk '{print $5}') 2>/dev/null | ||
| PART_FILE_SIZE=$(ls -l ${imagefile_compressed} | awk '{print $5}') 2>/dev/null | ||
| PCT=$(dc -e"2 k $PART_FILE_SIZE $IMAGE_SIZE / 100 * p" | sed -e"s/\..*$//" 2>/dev/null) | ||
| echo "${PCT}%" >&2 | ||
| sleep 1 | ||
|
|
@@ -601,14 +611,26 @@ 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 | ||
| } | ||
|
|
||
| ######################################################### | ||
| #Get the corresponding signaure file | ||
| ######################################################### | ||
| download_sig() { | ||
| log "Getting signature" | ||
| curl -L -s -o /mnt/dl/imagefile.compressed.sig $SIG_URL | ||
| curl -L -s -o ${imagefile_compressed_sig} $SIG_URL | ||
| if [ $? -ne 0 ] | ||
| then | ||
| log "Unable to download sig file." | ||
|
|
@@ -625,16 +647,17 @@ validate_image() { | |
| then | ||
| if [ "$SIG_TYPE" == "gpg" ] | ||
| then | ||
| gpg2 --trusted-key "${GPG_LONG_ID}" --verify /mnt/dl/imagefile.compressed.sig >/dev/null 2>&1 | ||
| gpg2 --trusted-key "${GPG_LONG_ID}" --verify ${imagefile_compressed_sig} >/dev/null 2>&1 | ||
| if [ $? -ne 0 ] | ||
| then | ||
| log "Install Image is corrupted." | ||
| exit 1 | ||
| fi | ||
| elif [ "$SIG_TYPE" == "sha" ] | ||
| then | ||
| sed -i -e"s/$/\ \/mnt\/dl\/imagefile\.gz/" /mnt/dl/imagefile.compressed.sig | ||
| sha256sum -c /mnt/dl/imagefile.compressed.sig | ||
| # sed original file path with current path in signature file | ||
| sed -i -e "s@/.*/@$tmpfs_mountpoint/@g" ${imagefile_compressed_sig} | ||
| sha256sum -c ${imagefile_compressed_sig} | ||
| if [ $? -ne 0 ] | ||
| then | ||
| log "Install Image is corrupted." | ||
|
|
@@ -662,30 +685,148 @@ log() { | |
| echo "$1" >&2 | ||
| } | ||
|
|
||
| ######################################################### | ||
| #Update bootloader if needed | ||
| ######################################################### | ||
| write_zipl_bootloader() { | ||
| if [[ "$arch" == "s390x" ]]; then | ||
| log "Updating zipl" | ||
| mkdir -p "$boot_partition" | ||
| mount_boot_partition "$boot_partition" | ||
| trap 'umount $boot_partition; trap - RETURN' RETURN | ||
|
|
||
|
|
||
| blsfile=$(ls ${boot_partition}/loader/entries/*.conf) | ||
| # We need to propagate s390x parameter to later boots via BLS files | ||
| # More details : https://github.com/coreos/fedora-coreos-tracker/issues/305 | ||
| options="$(grep options $blsfile | cut -d' ' -f2-) $(cat /tmp/s390x_opts)" | ||
| sed -i -e "s@^options.*@options $options@g" $blsfile | ||
| # And also keep networking parameters for first boot | ||
| echo "$options $(cat /tmp/networking_opts) ignition.firstboot" > /tmp/zipl_prm | ||
| zipl --verbose -p /tmp/zipl_prm -i $(ls ${boot_partition}/ostree/*/*vmlinuz*) -r $(ls ${boot_partition}/ostree/*/*initramfs*) --target "$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 | ||
| } | ||
|
|
||
| ######################################################### | ||
tuan-hoang1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| #Handle s390x ECKD DASD devices | ||
| ######################################################### | ||
| write_image_to_dasd() { | ||
| log "Extracting disk image" | ||
| mount_tmpfs $(( $($DECOMPRESSION_TOOL ${imagefile_compressed} | wc --bytes) / 1024 / 1024 + ${TMPFS_MBSIZE} + 100 )) | ||
| $DECOMPRESSION_TOOL ${imagefile_compressed} > ${imagefile} | ||
|
|
||
| # low-level format the ECKD DASD using dasdfmt, if needed | ||
| DEST_DEV_BUS=$(lszdev --by-node ${DEST_DEV} | tail -n 1 | awk '{print $2}') | ||
| if [ "$(< /sys/bus/ccw/devices/${DEST_DEV_BUS}/status)" = "unformatted" ]; then | ||
| dasdfmt --blocksize 4096 --disk_layout cdl --mode full -ypv "${DEST_DEV}" | ||
| fi | ||
| block_per_tracks=$(fdasd -p ${DEST_DEV} | grep blocks\ per\ track | awk '{print $5}') | ||
|
|
||
| # the first 2 tracks of the ECKD DASD are reserved | ||
| first_track=2 | ||
| # in RHCOS4.2 using anaconda, we have root partition at index 2 while in FCOS it's 4 | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is a good thing to do when RHCOS 4.3 goes out - which matches FCOS. But for the time being, I don't have time/other way to do it. |
||
| BOOTPN=1 | ||
| ROOTPN=2 | ||
| if [[ -n $(grep -i fedora /usr/lib/initrd-release) ]]; then | ||
| ROOTPN=4 | ||
| fi | ||
| boot_partition=($(fdisk -b 4096 -o DEVICE,START,SECTORS -l ${imagefile} | grep "${imagefile}${BOOTPN}" | awk '{print $2,$3}')) | ||
| root_partition=($(fdisk -b 4096 -o DEVICE,START,SECTORS -l ${imagefile} | grep "${imagefile}${ROOTPN}" | awk '{print $2,$3}')) | ||
| boot_partition+=( $first_track $(dc -e "${boot_partition[1]} $block_per_tracks 1 - + $block_per_tracks / p") ) | ||
| root_partition+=($(( ${boot_partition[2]} + ${boot_partition[3]} )) "last") | ||
| cat > "/tmp/fdasd_conf" <<- EOF | ||
| [$first_track,$(( ${root_partition[2]} - 1 )),native] | ||
| [${root_partition[2]},${root_partition[3]},native] | ||
| EOF | ||
|
|
||
| # format the ECKD DASD using fdasd program | ||
| fdasd --silent --config /tmp/fdasd_conf "${DEST_DEV}" | ||
|
|
||
| # copy the content of each partition | ||
| set -- ${boot_partition[@]} ${root_partition[@]} | ||
| while [ $# -gt 0 ]; do | ||
| dd bs=4096 if="${imagefile}" iflag=fullblock of="${DEST_DEV}" \ | ||
| status=none \ | ||
| skip="$1" \ | ||
| count="$2" \ | ||
| seek="$(( $3 * $block_per_tracks ))" | ||
| if [[ $? -ne 0 ]]; then | ||
| log "failed to write image to ECKD DASD device" | ||
| exit 1 | ||
| fi | ||
| shift 4 | ||
| done | ||
| } | ||
|
|
||
| ######################################################### | ||
tuan-hoang1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| #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} + 100 )) | ||
| $DECOMPRESSION_TOOL ${imagefile_compressed} > ${imagefile} | ||
|
|
||
| # we have to store the strings to a file because any change in this | ||
| # while-do block would not take effect outside | ||
| (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" \ | ||
tuan-hoang1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| "$(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 | ||
ashcrow marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| 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=none 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 | ||
| } | ||
tuan-hoang1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ######################################################### | ||
| #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=/mnt/dl/imagefile.compressed status=none)" = "$(printf '\x1f\x8b')" ] | ||
| if [[ "${arch}" =~ (aarch64|ppc64le|x86_64) ]] | ||
| then | ||
| DECOMPRESSION_TOOL='zcat' | ||
| elif [ "$(dd count=5 bs=1 if=/mnt/dl/imagefile.compressed status=none)" = "$(printf '\xfd\x37\x7a\x58\x5a')" ] | ||
| $DECOMPRESSION_TOOL ${imagefile_compressed} |\ | ||
| dd bs=1M iflag=fullblock oflag=direct 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' | ||
| if [[ "${DEST_DEV}" =~ "dasd" ]]; then | ||
| write_image_to_dasd | ||
| else | ||
| write_image_to_zfcp_disk | ||
| fi | ||
| else | ||
| log "Compressed file format is not supported. Supported formats: '.xz', '.gz'" | ||
| exit 1 | ||
| fi | ||
|
|
||
| $DECOMPRESSION_TOOL /mnt/dl/imagefile.compressed |\ | ||
| dd bs=1M iflag=fullblock oflag=direct of="${DEST_DEV}" status=none | ||
| RETCODE=$? | ||
| if [[ $RETCODE -ne 0 ]]; then | ||
| log "failed to write image to disk" | ||
| log "Unsupported architecture" | ||
| exit 1 | ||
| fi | ||
| set +o pipefail | ||
|
|
@@ -788,6 +929,9 @@ main() { | |
| # If ignition platform id is provided, overwrite ignition.platform.id in BLS | ||
| write_platform_id | ||
|
|
||
| # If platform is s390x, update bootloader records | ||
| write_zipl_bootloader | ||
|
|
||
| log "Install complete" | ||
| } | ||
|
|
||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.