mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 03:12:30 +00:00 
			
		
		
		
	support firmware update for p8LE
This commit is contained in:
		
							
								
								
									
										29
									
								
								xCAT-genesis-scripts/bin/pseries_platform
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										29
									
								
								xCAT-genesis-scripts/bin/pseries_platform
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| #!/bin/sh | ||||
|  | ||||
| SOURCE_FILE="pseries_platform" | ||||
| PLATFORM_FILE=/proc/cpuinfo | ||||
| export PLATFORM_UNKNOWN=0 | ||||
| export PLATFORM_POWERKVM_HOST=1 | ||||
| export PLATFORM_POWERKVM_GUEST=2 | ||||
| export PLATFORM_PSERIES_LPAR=3 | ||||
|  | ||||
| export platform_name="Unknown" | ||||
| export platform=$PLATFORM_UNKNOWN | ||||
|  | ||||
| if grep -q "PowerNV" $PLATFORM_FILE; then | ||||
| 	platform_name="PowerKVM Host" | ||||
| 	platform=$PLATFORM_POWERKVM_HOST | ||||
| elif grep -q "IBM pSeries (emulated by qemu)" $PLATFORM_FILE; then | ||||
| 	platform_name="PowerKVM pSeries Guest" | ||||
| 	platform=$PLATFORM_POWERKVM_GUEST | ||||
| elif  grep -q "pSeries" $PLATFORM_FILE; then | ||||
| 	platform_name="PowerVM pSeries LPAR" | ||||
| 	platform=$PLATFORM_PSERIES_LPAR | ||||
| fi | ||||
| PARAM=$0 | ||||
| BASENAME=`basename $0` | ||||
| echo "basename:$BASENAME, param:$PARAM" | ||||
|  | ||||
| if [ $SOURCE_FILE = `basename $0` ]; then | ||||
| 	echo $platform_name | ||||
| fi | ||||
							
								
								
									
										457
									
								
								xCAT-genesis-scripts/bin/update_flash
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										457
									
								
								xCAT-genesis-scripts/bin/update_flash
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,457 @@ | ||||
| #!/bin/sh | ||||
| # Copyright (c) 2003, 2004, 2008 International Business Machines | ||||
| # Common Public License Version 1.0 (see COPYRIGHT) | ||||
| # | ||||
| # Authors: John Rose <johnrose@us.ibm.com> | ||||
| #          Mike Strosaker <strosake@austin.ibm.com> | ||||
|  | ||||
| # Simple script to update flash.  The kernel module rtas_flash does | ||||
| # the real work at reboot time. | ||||
| # This script has minimal dependencies so it can operate in a rescue | ||||
| # environment.  This is probably overkill since it is easy enough to | ||||
| # flash without this script. | ||||
|  | ||||
| #set -x | ||||
|  | ||||
| # For now firmware can only handle 4k pages.  At some point in the | ||||
| # future they will be able to handle large pages.  When that (hopefully) | ||||
| # happens we will need to use getconf to retrieve the systems page size. | ||||
| PAGE_SIZE=4096 | ||||
|  | ||||
| # Error Codes | ||||
| E_SUCCESS=0     # Success | ||||
| E_UNSUPPORTED=1	# Flash update is not supported on this system | ||||
| E_USAGE=3	# Usage error | ||||
| E_PERM=4	# Permission error | ||||
| E_IMAGE=5	# Image file error | ||||
| E_PROC_FS=6	# Proc file either doesn't exist, or behaves unexpectedly | ||||
| E_MODULE=7	# Error loading module | ||||
| E_RTAS=8	# RTAS call failed | ||||
| E_USER=9	# User aborted operation | ||||
| E_OVERWRITE=10	# Auto overwrite permanent side image | ||||
| E_WRNTY=15	# Update Access Key Expired | ||||
|  | ||||
| # Script Constants | ||||
| PATH=/sbin:/usr/sbin:/bin:/usr/bin:$PATH | ||||
| PROCFLASH=/proc/ppc64/rtas/firmware_update | ||||
| PROCMANAGE=/proc/ppc64/rtas/manage_flash | ||||
| PROCVALIDATE=/proc/ppc64/rtas/validate_flash | ||||
| OLDPROCFLASH=/proc/ppc64/rtas/firmware_flash | ||||
| PSERIES_PLATFORM=$(dirname $0)/pseries_platform | ||||
|  | ||||
| # firmware_update Status Values | ||||
| FLASH_AUTH=-9002		# RTAS Not Service Authority Partition | ||||
| FLASH_NO_OP=-1099		# No operation initiated by user | ||||
| FLASH_IMG_SHORT=-1005 		# Flash image shorter than expected | ||||
| FLASH_IMG_BAD_LEN=-1004 	# Bad length value in flash list block | ||||
| FLASH_IMG_NULL_DATA=-1003 	# Bad data value in flash list block | ||||
| FLASH_IMG_READY=0     		# Firmware img ready for flash on reboot | ||||
|  | ||||
| # manage_flash Status Values | ||||
| MANAGE_AUTH=-9002 		# RTAS Not Service Authority Partition  | ||||
| MANAGE_ACTIVE_ERR=-9001 	# RTAS Cannot Overwrite Active Img  | ||||
| MANAGE_NO_OP=-1099 		# No operation initiated by user  | ||||
| MANAGE_PARAM_ERR=-3    		# RTAS Parameter Error  | ||||
| MANAGE_HW_ERR=-1    		# RTAS Hardware Error  | ||||
| MANAGE_SUCCESS=0		# Operation Successful | ||||
|  | ||||
| # validate_flash Status Values | ||||
| VALIDATE_AUTH=-9002 		# RTAS Not Service Authority Partition | ||||
| VALIDATE_INCOMPLETE=-1002 	# User copied < VALIDATE_BUF_SIZE | ||||
| VALIDATE_READY=-1001 		# Firmware image ready for validation | ||||
| VALIDATE_PARAM_ERR=-3    	# RTAS Parameter Error | ||||
| VALIDATE_HW_ERR=-1    		# RTAS Hardware Error | ||||
| VALIDATE_TMP_UPDATE=0     	# RPA Section 7.3, Table 63 | ||||
| VALIDATE_FLASH_AUTH=1     	# RPA Section 7.3, Table 63 | ||||
| VALIDATE_INVALID_IMG=2     	# RPA Section 7.3, Table 63 | ||||
| VALIDATE_CUR_UNKNOWN=3     	# RPA Section 7.3, Table 63 | ||||
| VALIDATE_TMP_COMMIT_DL=4     	# RPA Section 7.3, Table 63 | ||||
| VALIDATE_TMP_COMMIT=5     	# RPA Section 7.3, Table 63 | ||||
| VALIDATE_TMP_UPDATE_DL=6     	# RPA Section 7.3, Table 63 | ||||
| VALIDATE_OUT_OF_WRNTY=7     	# RPA Section 7.3, Table 63 | ||||
|  | ||||
| error() { | ||||
| 	local exit_code=$1 | ||||
|  | ||||
| 	if [ $# -lt 1 ]; then | ||||
| 		echo "error(): usage" >&2 | ||||
| 		return $E_USAGE | ||||
| 	fi | ||||
| 	 | ||||
| 	shift; | ||||
| 	echo update_flash: $* >&2 | ||||
| 	exit $exit_code | ||||
| } | ||||
|  | ||||
| usage() { | ||||
| 	local exit_code; | ||||
|  | ||||
| 	if [ "$1" == $E_SUCCESS ]; then | ||||
| 		exit_code=$E_SUCCESS | ||||
| 	else | ||||
| 		exit_code=$E_USAGE | ||||
| 	fi | ||||
|  | ||||
| 	echo "USAGE:  update_flash {-h | -s | -r | -c | [-v|-n] -f <image filename>}" >&2 | ||||
| 	echo "		-h		Print this message." >&2 | ||||
| 	echo "		-s		Determine if partition has access to" >&2 | ||||
| 	echo "				perform flash image management." >&2 | ||||
| 	echo "		-r 		Reject temporary image." >&2 | ||||
| 	echo "		-c		Commit temporary image." >&2 | ||||
| 	echo "		-v		Validate ONLY with given image file." >&2 | ||||
| 	echo "		-n		Do not overwrite Permanent side" >&2 | ||||
| 	echo "				image automatically." >&2 | ||||
| 	echo "		-f <filename>	Update with given image file.  If possible," >&2 | ||||
| 	echo "				the image is automatically validated prior" >&2  | ||||
| 	echo "				to update." >&2 | ||||
| 	echo "" >&2 | ||||
| 	exit $exit_code | ||||
| } | ||||
|  | ||||
| query_support() { | ||||
| 	local exit_status=$E_UNSUPPORTED | ||||
|  | ||||
| 	if [ ! -r "$PROCVALIDATE" ]; then  | ||||
| 		modprobe rtas_flash || error $E_MODULE "could not load rtas_flash kernel module" | ||||
| 	fi | ||||
|  | ||||
| 	if [ -e "/proc/device-tree/rtas/ibm,manage-flash-image" ]; then | ||||
| 		grep \\"$VALIDATE_AUTH" "$PROCVALIDATE" > /dev/null | ||||
| 		if [ $? -ne 0 ]; then | ||||
| 			# validate-flash did not return "not authorized" | ||||
| 			head --bytes=4k /dev/zero > $PROCVALIDATE 2>/dev/null | ||||
| 			grep 1 "$PROCVALIDATE" > /dev/null | ||||
| 			if [ $? -ne 0 ]; then | ||||
| 				# validate-flash did not return "not authorized" | ||||
| 				exit_status=0 | ||||
| 			fi | ||||
| 		fi | ||||
| 	else | ||||
| 		if [ -e "/proc/device-tree/rtas/ibm,update-flash-64-and-reboot" ] || [ -e "/proc/device-tree/rtas/udpate-flash-and-reboot" ]; then | ||||
| 			exit_status=0 | ||||
| 		fi | ||||
| 	fi | ||||
|  | ||||
| 	if [ $exit_status -ne 0 ]; then | ||||
| 		echo update_flash: flash image cannot be managed from this partition | ||||
| 	else | ||||
| 		echo update_flash: flash image management is supported | ||||
| 	fi | ||||
|  | ||||
| 	exit $exit_status; | ||||
| } | ||||
|  | ||||
| echo_validate_rtas_buf() { | ||||
| 	local output="$1" | ||||
| 	local cur_t_name=$(echo "$output" | grep "^MI" | head -n 1 | awk ' { print $2 } ') | ||||
| 	local cur_p_name=$(echo "$output" | grep "^MI" | head -n 1 | awk ' { print $3 } ') | ||||
| 	local new_t_name=$(echo "$output" | grep "^MI" | tail -n 1 | awk ' { print $2 } ') | ||||
| 	local new_p_name=$(echo "$output" | grep "^MI" | tail -n 1 | awk ' { print $3 } ') | ||||
|  | ||||
| 	echo "Projected Flash Update Results:" | ||||
| 	echo "Current T Image: $cur_t_name" | ||||
| 	echo "Current P Image: $cur_p_name" | ||||
| 	echo "New T Image:     $new_t_name" | ||||
| 	echo "New P Image:     $new_p_name" | ||||
| } | ||||
|  | ||||
| echo_entitlement_expiry_date() { | ||||
| 	local build_date=`cat $PROCVALIDATE | grep "^MG" | tail -n 1 | cut -d " " -f2` | ||||
| 	local entl_date=`cat $PROCVALIDATE | grep "^ME" | cut -d " " -f2` | ||||
|  | ||||
| 	echo "The selected firmware image cannot be applied." | ||||
| 	echo "" | ||||
| 	echo -n "The Build Date of the firmware image selected is " | ||||
| 	if [ "$build_date" != "" ]; then | ||||
| 		echo "$(date --date=$build_date +"%B %d, %Y")." | ||||
| 	else | ||||
| 		echo "UNKNOWN." | ||||
| 	fi | ||||
|  | ||||
| 	echo -n "The System's Update Access Key Expiration Date is " | ||||
| 	if [ "$entl_date" != "" ]; then | ||||
| 		echo "$(date --date=$entl_date +"%B %d, %Y")." | ||||
| 	else | ||||
| 		echo "UNKNOWN." | ||||
| 	fi | ||||
| 	echo "" | ||||
| 	echo "Please go to http://www.ibm.com/servers/eserver/ess to obtain " | ||||
| 	echo "a replacement update access key." | ||||
| } | ||||
|  | ||||
| echo_validate_return_status() { | ||||
| 	local output="$1" | ||||
| 	local rc=$(echo "$output" | head -n 1) | ||||
| 	local rtas_buf=$(echo "$output" | tail -n +2) | ||||
|  | ||||
| 	[ $# -eq 1 ] || error $E_USAGE "echo_validate_return_status(): usage"  | ||||
|  | ||||
| 	case "$rc" in | ||||
| 	$VALIDATE_PARAM_ERR)	 | ||||
| 		error $E_RTAS "RTAS: validate() Parameter Error";; | ||||
| 	$VALIDATE_HW_ERR) 	 | ||||
| 		error $E_RTAS "RTAS: validate() Hardware Error";; | ||||
| 	$VALIDATE_FLASH_AUTH)	 | ||||
| 		error $E_RTAS "RTAS: validate() Partition does not have authority";; | ||||
| 	$VALIDATE_AUTH) | ||||
| 		error $E_RTAS "RTAS: validate() Partition does not have authority";; | ||||
| 	$VALIDATE_INVALID_IMG)	 | ||||
| 		error $E_RTAS "RTAS: validate() Invalid candidate image for this platform";; | ||||
| 	$VALIDATE_TMP_UPDATE)	 | ||||
| 		echo "info: Temporary side will be updated with a newer or" | ||||
| 		echo "identical image";; | ||||
| 	$VALIDATE_CUR_UNKNOWN)	 | ||||
| 		echo "info: Current fixpack level is unknown";; | ||||
| 	$VALIDATE_TMP_COMMIT_DL)	 | ||||
| 		echo "info: Current Temporary image will be committed to" | ||||
| 		echo "Permanent side before being replaced with new image, and" | ||||
| 		echo "the new image is downlevel from current image";; | ||||
| 	$VALIDATE_TMP_COMMIT)	 | ||||
| 		echo "info: Current Temporary side will be committed to" | ||||
| 		echo "Permanent side before being replaced with the new image";; | ||||
| 	$VALIDATE_TMP_UPDATE_DL) 	 | ||||
| 		echo "info: Temporary side will be updated with a downlevel" | ||||
| 		echo "image";; | ||||
| 	$VALIDATE_OUT_OF_WRNTY) | ||||
| 		echo_entitlement_expiry_date | ||||
| 		error $E_WRNTY "Please contact your service support structure.";; | ||||
| 	*) 	error $E_RTAS "RTAS: Unknown validate-flash-image Return Status" | ||||
| 	esac | ||||
|  | ||||
| 	echo | ||||
| 	echo_validate_rtas_buf "$rtas_buf" | ||||
|  | ||||
| 	# Do not commit T side image to P side | ||||
| 	if [ $no_overwrite_opt -eq 1 ]; then | ||||
| 		if [ $rc -eq $VALIDATE_TMP_COMMIT_DL ] || [ $rc -eq $VALIDATE_TMP_COMMIT ]; then | ||||
| 			echo "" | ||||
| 			echo "update_flash: Run without -n option to flash new image" | ||||
| 			exit $E_OVERWRITE | ||||
| 		fi | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| validate_flash() { | ||||
| 	local img_file=$1 | ||||
| 	local output="" | ||||
|  | ||||
| 	[ $# -eq 1 ] || error $E_USAGE "validate_flash(): usage" | ||||
|  | ||||
| 	[ -r $PROCVALIDATE ] || return $E_PROC_FS | ||||
|  | ||||
| 	grep \\"$VALIDATE_AUTH" "$PROCVALIDATE" > /dev/null | ||||
| 	if [ $? -eq 0 ]; then	# validate-flash returned "not authorized" | ||||
| 		return $E_RTAS | ||||
| 	fi | ||||
|  | ||||
| 	# Copy image file to proc file | ||||
| 	cp "$img_file" "$PROCVALIDATE" || error $E_PROC_FS "error copying flash image to rtas_flash validate module" | ||||
|  | ||||
| 	# Display appropriate message, exiting if necessary | ||||
| 	output="$(cat $PROCVALIDATE)" | ||||
| 	echo_validate_return_status "$output" | ||||
|  | ||||
| 	return 0 | ||||
| } | ||||
|  | ||||
| validate_flash_from_file() { | ||||
| 	local img_file=$1 | ||||
|  | ||||
| 	[ $# -eq 1 ] || error $E_USAGE "validate_flash_from_file(): usage"  | ||||
|  | ||||
| 	if [ ! -r "$PROCVALIDATE" ]; then  | ||||
| 		modprobe rtas_flash || error $E_MODULE "could not load rtas_flash kernel module" | ||||
| 		[ -r "$PROCVALIDATE" ] || error $E_PROC_FS "rtas_flash kernel module did not create $PROCVALIDATE" | ||||
| 	fi | ||||
|  | ||||
| 	if validate_flash $img_file; then | ||||
| 		return 0; | ||||
| 	else | ||||
| 		case "$?" in  | ||||
| 		$E_PROC_FS) error $E_PROC_FS "validate: $PROCVALIDATE does not exist";; | ||||
| 		$E_RTAS) error $E_RTAS "validate: firmware validation not supported on this system";; | ||||
| 		esac | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| echo_update_status() { | ||||
| 	local rc="$1" | ||||
| 	 | ||||
| 	[ $# -eq 1 ] || error $E_USAGE "echo_update_status(): usage"  | ||||
|  | ||||
| 	case "$rc" in | ||||
| 	$FLASH_AUTH)  | ||||
| 		error $E_RTAS "RTAS: Partition does not have authority";; | ||||
| 	$FLASH_IMG_SHORT)  | ||||
| 		error $E_IMAGE "Flash image shorter than expected";; | ||||
| 	$FLASH_IMG_BAD_LEN)  | ||||
| 		error $E_PROC_FS "Bad length value in flash list block";; | ||||
| 	$FLASH_IMG_NULL_DATA)  | ||||
| 		error $E_PROC_FS "Bad data value in flash list block";; | ||||
| 	$FLASH_IMG_READY) | ||||
| 		echo "Flash image ready...rebooting the system...";; | ||||
| 	*)     	error $E_PROC_FS "RTAS: Unknown update flash status" | ||||
| 	esac | ||||
| } | ||||
|  | ||||
| update_flash_from_file() { | ||||
| 	local img_file=$1 | ||||
| 	local output="" | ||||
| 	local oldkernel=0 | ||||
|  | ||||
| 	[ $# -eq 1 ] || error $E_USAGE "update_flash_from_file(): usage"  | ||||
|  | ||||
| 	[ -r "$img_file" ] || error $E_IMAGE "cannot read $img_file" | ||||
|  | ||||
| 	flashfile=$PROCFLASH | ||||
| 	if [ ! -r "$PROCFLASH" ]; then  | ||||
| 		modprobe rtas_flash  | ||||
| 		if [ ! -r "$PROCFLASH" ]; then | ||||
| 			if [ -r "$OLDPROCFLASH" ]; then | ||||
| 				oldkernel=1 | ||||
| 			else | ||||
| 				error $E_PROC_FS "rtas_flash kernel module did not create $PROCFLASH" | ||||
| 			fi | ||||
| 		fi | ||||
| 	fi | ||||
|  | ||||
| 	if [ -r "$PROCVALIDATE" ]; then | ||||
| 		validate_flash "$img_file" | ||||
| 	fi | ||||
| 	 | ||||
| 	if [ $oldkernel -eq 0 ]; then | ||||
| 		dd if="$img_file" of="$PROCFLASH" bs=$PAGE_SIZE 2>/dev/null || error $E_PROC_FS "error copying flash image to rtas_flash kernel module" | ||||
|  | ||||
| 		output="$(cat $PROCFLASH)" | ||||
| 		echo_update_status "$output" | ||||
| 	else | ||||
| 		dd if="$img_file" of="$OLDPROCFLASH" bs=PAGE_SIZE 2>/dev/null || error $E_PROC_FS "error copying flash image to rtas_flash kernel module" | ||||
| 		cat "$OLDPROCFLASH" | ||||
| 	fi | ||||
|  | ||||
| 	#XXX | ||||
| 	reboot | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| echo_manage_return_status() { | ||||
| 	local is_commit=$1 | ||||
| 	local output=$2 | ||||
| 	local rc=$(echo $output) | ||||
|  | ||||
| 	[ $# -eq 2 ] || error $E_USAGE "echo_manage_return_status(): usage"  | ||||
| 	 | ||||
| 	case "$rc" in | ||||
| 	$MANAGE_AUTH) | ||||
| 		error $E_RTAS "RTAS: manage() Partition does not have authority";; | ||||
| 	$MANAGE_ACTIVE_ERR)   | ||||
| 		error $E_RTAS "RTAS: manage() Cannot Overwrite the Active Firmware Image";; | ||||
| 	$MANAGE_PARAM_ERR)	 | ||||
| 		error $E_RTAS "RTAS: manage() Parameter Error";; | ||||
| 	$MANAGE_HW_ERR) 	 | ||||
| 		error $E_RTAS "RTAS: manage() Hardware Error";; | ||||
| 	$MANAGE_SUCCESS)	 | ||||
| 		if [ $is_commit -eq 0 ]; then | ||||
| 			echo "success: Rejected temporary firmware image" | ||||
| 		else | ||||
| 			echo "success: Committed temporary firmware image" | ||||
| 		fi | ||||
| 		;; | ||||
| 	*) 	error $E_RTAS "Unknown manage-flash-image Return Status" | ||||
| 	esac | ||||
| } | ||||
|  | ||||
| manage_flash() { | ||||
| 	local is_commit=$1 | ||||
| 	local commit_str="1" | ||||
| 	local reject_str="0" | ||||
| 	local output="" | ||||
| 	 | ||||
| 	[ $# -eq 1 ] || error $E_USAGE "manage_flash(): usage"  | ||||
| 	 | ||||
| 	if [ ! -r "$PROCMANAGE" ]; then  | ||||
| 		modprobe rtas_flash || error $E_MODULE "could not load rtas_flash kernel module" | ||||
| 		[ -r "$PROCMANAGE" ] || error $E_PROC_FS "rtas_flash kernel module did not create $PROCMANAGE" | ||||
| 	fi | ||||
|  | ||||
| 	if [ $is_commit -eq 1 ]; then | ||||
| 		echo $commit_str > $PROCMANAGE | ||||
| 	else | ||||
| 		echo $reject_str > $PROCMANAGE | ||||
| 	fi | ||||
| 	 | ||||
| 	output=$(cat $PROCMANAGE) | ||||
| 	 | ||||
| 	echo_manage_return_status $is_commit "$output" | ||||
|  | ||||
| 	if echo $output | grep "^success" > /dev/null; then | ||||
| 		return 0 | ||||
| 	else | ||||
| 		return $E_RTAS | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| file="" | ||||
| check_opt=0 | ||||
| commit_opt=0 | ||||
| reject_opt=0 | ||||
| validate_opt=0 | ||||
| no_overwrite_opt=0 | ||||
| file_opt=0 | ||||
|  | ||||
| [ -d /proc/device-tree ] || error $E_PROC_FS "iSeries or /proc not mounted" | ||||
| #XXX | ||||
| #[ "`whoami`" = "root" ] || error $E_PERM "must be root to execute this command" | ||||
|  | ||||
| # Check for platform and if PowerNV call update_flash_nv | ||||
|  | ||||
| # PowerNV update_flash tool | ||||
| UPDATE_FLASH_NV=$(dirname $0)/update_flash_nv | ||||
|  | ||||
| . $PSERIES_PLATFORM | ||||
| case "$platform" in | ||||
|     $PLATFORM_UNKNOWN | $PLATFORM_POWERKVM_GUEST) | ||||
| 	echo "update_flash: is not supported on the $platform_name platform" | ||||
| 	exit 1;; | ||||
|     $PLATFORM_POWERKVM_HOST) | ||||
| 	if [ ! -r "$UPDATE_FLASH_NV" ]; then | ||||
| 		error $E_PERM "Couldn't find $UPDATE_FLASH_NV file." | ||||
| 	fi | ||||
| 	/bin/sh $UPDATE_FLASH_NV $@ | ||||
| 	exit $? | ||||
| esac | ||||
|  | ||||
| while [ -n "$1" ]; do | ||||
| 	arg="$1" | ||||
| 	shift | ||||
| 	case "$arg" in | ||||
| 	  -q|-l|-D|-S) error $E_USAGE "the $arg option is not implemented";; | ||||
| 	  -h) usage $E_SUCCESS;; | ||||
| 	  -s) check_opt=1;; | ||||
| 	  -c) commit_opt=1;; | ||||
| 	  -r) reject_opt=1;; | ||||
| 	  -v) validate_opt=1;; | ||||
| 	  -n) no_overwrite_opt=1;; | ||||
| 	  -f) file_opt=1; file="$1"; shift;; | ||||
| 	  *) error $E_USAGE "unknown option $arg" | ||||
| 	esac | ||||
| done | ||||
|  | ||||
| if [ -n "$file" ]; then | ||||
| 	if [ $commit_opt -eq 1 ] || [ $reject_opt -eq 1 ] || | ||||
| 						[ $check_opt -eq 1 ]; then | ||||
| 		usage | ||||
| 	elif [ $validate_opt -eq 1 ] && [ $no_overwrite_opt -eq 1 ]; then | ||||
| 		usage | ||||
| 	elif [ $validate_opt -eq 1 ]; then | ||||
| 		validate_flash_from_file $file | ||||
| 	else | ||||
| 		update_flash_from_file $file | ||||
| 	fi | ||||
| else | ||||
| 	[ $check_opt -eq 1 ] && query_support | ||||
| 	[ $commit_opt -eq 0 ] && [ $reject_opt -eq 0 ] && usage | ||||
| 	[ $commit_opt -eq 1 ] && [ $reject_opt -eq 1 ] && usage | ||||
| 	manage_flash $commit_opt | ||||
| fi | ||||
							
								
								
									
										416
									
								
								xCAT-genesis-scripts/bin/update_flash_nv
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										416
									
								
								xCAT-genesis-scripts/bin/update_flash_nv
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,416 @@ | ||||
| #!/bin/sh | ||||
| # Copyright (c) 2013 International Business Machines | ||||
| # Common Public License Version 1.0 (see COPYRIGHT) | ||||
| # | ||||
| # Authors: Vasant Hegde <hegdevasant@linux.vnet.ibm.com> | ||||
| # | ||||
| # Simple script for code update on "KVM on Power" machines. This | ||||
| # is a simple wrapper script to pass the image. The Linux kernel | ||||
| # and FW does the real work during system reboot. | ||||
| # | ||||
| # This script has minimal dependencies so it can operate in a | ||||
| # rescue environment. | ||||
|  | ||||
| #set -x | ||||
|  | ||||
| # Error codes | ||||
| E_SUCCESS=0	# Success | ||||
| E_UNSUPPORTED=1	# Firmware update is not supported | ||||
| E_USAGE=3	# Usage error | ||||
| E_PERM=4	# Permission error | ||||
| E_IMAGE=5	# Image file error | ||||
| E_SYS_FS=6	# Firmware update related sysfs file doesn't exist | ||||
| E_MODULE=7	# Error loading module | ||||
| E_OPAL=8	# OPAL call failed | ||||
| E_USER=9	# User aborted operation | ||||
| E_OVERWRITE=10	# Auto overwrite permanent side image | ||||
| E_WRNTY=15	# Update Access Key Expired | ||||
|  | ||||
| # Firmware update related files | ||||
| SYS_IMAGE_FILE=/sys/firmware/opal/image | ||||
| SYS_VALIDATE_FLASH=/sys/firmware/opal/validate_flash | ||||
| SYS_MANAGE_FLASH=/sys/firmware/opal/manage_flash | ||||
| SYS_UPDATE_FLASH=/sys/firmware/opal/update_flash | ||||
|  | ||||
| # Code update status values | ||||
| FLASH_SUCCESS=0			# Success | ||||
| FLASH_PARAM_ERR=-1		# Parameter error | ||||
| FLASH_BUSY=-2			# OPAL busy | ||||
| FLASH_HW_ERR=-6			# Hardware error | ||||
| FLASH_INTERNAL_ERR=-11		# Internal error | ||||
| FLASH_NO_OP=-1099		# No operation initiated by user | ||||
| FLASH_NO_AUTH=-9002		# Inband firmware update is not allowed | ||||
|  | ||||
| # Validate image status values | ||||
| FLASH_IMG_READY=-1001		# Image ready for validation | ||||
| FLASH_IMG_INCOMPLETE=-1002	# User copied < VALIDATE_BUF_SIZE | ||||
|  | ||||
| # Manage image status values | ||||
| FLASH_ACTIVE_ERR=-9001		# Cannot overwrite active img | ||||
|  | ||||
| # Flash image status values | ||||
| FLASH_IMG_READY=0		# Image ready for flash on reboot | ||||
| FLASH_INVALID_IMG=-1003		# Flash image shorter than expected | ||||
| FLASH_IMG_NULL_DATA=-1004	# Bad data | ||||
| FLASH_IMG_BAD_LEN=-1005		# Bad length | ||||
|  | ||||
| # Validate image update result tokens | ||||
| # | ||||
| # T side will be updated | ||||
| VALIDATE_TMP_UPDATE=0 | ||||
| # | ||||
| # Partition does not have authority | ||||
| VALIDATE_FLASH_AUTH=1 | ||||
| # | ||||
| # Candidate image is not valid for this platform | ||||
| VALIDATE_INVALID_IMG=2 | ||||
| # | ||||
| # Current fixpack level is unknown | ||||
| VALIDATE_CUR_UNKNOWN=3 | ||||
| # | ||||
| # Current T side will be committed to P side before being replace | ||||
| # with new image, and the new image is downlevel from current image | ||||
| VALIDATE_TMP_COMMIT_DL=4 | ||||
| # | ||||
| # Current T side will be committed to P side before being replaced | ||||
| # with new image | ||||
| VALIDATE_TMP_COMMIT=5 | ||||
| # | ||||
| # T side will be updated with a downlevel image | ||||
| VALIDATE_TMP_UPDATE_DL=6 | ||||
| # | ||||
| # The candidate image's release date is later than the system's Update | ||||
| # Access Key Expiration date - service warranty period has expired | ||||
| VALIDATE_OUT_OF_WRNTY=7 | ||||
|  | ||||
| error() { | ||||
| 	local exit_code=$1 | ||||
|  | ||||
| 	if [ $# -lt 1 ]; then | ||||
| 		echo "error(): usage." >&2 | ||||
| 		return $E_USAGE | ||||
| 	fi | ||||
|  | ||||
| 	shift; | ||||
| 	echo update_flash: $* >&2 | ||||
| 	exit $exit_code | ||||
| } | ||||
|  | ||||
| usage() { | ||||
| 	local exit_code; | ||||
|  | ||||
| 	if [ "$1" == $E_SUCCESS ]; then | ||||
| 		exit_code=$E_SUCCESS | ||||
| 	else | ||||
| 		exit_code=$E_USAGE | ||||
| 	fi | ||||
|  | ||||
| 	echo "USAGE: update_flash {-h | -s | -r | -c | [-v|-n] -f <image filename>}" >&2 | ||||
| 	echo "	-h		Print this message." >&2 | ||||
| 	echo "	-s		Determine if partition has access to" >&2 | ||||
| 	echo "			perform flash image management." >&2 | ||||
| 	echo "	-r		Reject temporary image." >&2 | ||||
| 	echo "	-c		Commit temporary image." >&2 | ||||
| 	echo "	-v		Validate the given image file." >&2 | ||||
| 	echo "	-n		Do not overwrite Permanent side" >&2 | ||||
| 	echo "			image automatically." >&2 | ||||
| 	echo "	-f <filename>	Update with given image file. If possible," >&2 | ||||
| 	echo "			the image is automatically validated prior" >&2 | ||||
| 	echo "			to update." >&2 | ||||
| 	echo "" >&2 | ||||
| 	exit $exit_code | ||||
| } | ||||
|  | ||||
| # Validate sysfs interface | ||||
| validate_sysfs_file() { | ||||
| 	local file="$1" | ||||
| 	if [ -r "$file" ]; then | ||||
| 		return $E_SUCCESS | ||||
| 	fi | ||||
|  | ||||
| 	error $E_SYS_FS "sysfs interface for firmware update does not exists." | ||||
| } | ||||
|  | ||||
| # Copy image to sysfs file | ||||
| copy_candidate_image() { | ||||
| 	local img_file=$1 | ||||
|  | ||||
| 	[ $# -eq 1 ] || error $E_USAGE "copy_candidate_image(): usage." | ||||
|  | ||||
| 	[ -r "$img_file" ] || error $E_IMAGE "Cannot read ${img_file}." | ||||
|  | ||||
| 	# Copy candidate image | ||||
| 	dd if=$img_file of=$SYS_IMAGE_FILE 2>/dev/null | ||||
| 	if [ $? -ne 0 ]; then | ||||
| 		echo "update_flash: Error copying firmware image." | ||||
| 		error $E_IMAGE "Please retry with valid firmware image." | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| echo_opal_return_status() { | ||||
| 	case "$1" in | ||||
| 	$FLASH_PARAM_ERR) | ||||
| 		error $E_OPAL "Parameter Error.";; | ||||
| 	$FLASH_BUSY) | ||||
| 		error $E_OPAL "OPAL Busy.";; | ||||
| 	$FLASH_HW_ERR) | ||||
| 		error $E_OPAL "Hardware error.";; | ||||
| 	$FLASH_INTERNAL_ERR) | ||||
| 		error $E_OPAL "OPAL internal error.";; | ||||
| 	$FLASH_NO_AUTH) | ||||
| 		error $E_PERM "System does not have authority to perform firmware update.";; | ||||
| 	$FLASH_IMG_INCOMPLETE) | ||||
| 		error $E_IMAGE "Invalid candidate image.";; | ||||
| 	$FLASH_ACTIVE_ERR) | ||||
| 		error $E_OVERWRITE "Cannot Overwrite the Active Firmware Image.";; | ||||
| 	$FLASH_INVALID_IMG) | ||||
| 		error $E_IMAGE "Invalid candidate image.";; | ||||
| 	$FLASH_IMG_NULL_DATA) | ||||
| 		error $E_IMAGE "Bad data value in flash list block.";; | ||||
| 	$FLASH_IMG_BAD_LEN) | ||||
| 		error $E_IMAGE "Bad length value in flash list block.";; | ||||
| 	*)	error $E_OPAL "Unknown return status.";; | ||||
| 	esac | ||||
| } | ||||
|  | ||||
| # Determine if partition has access to perform flash image management | ||||
| query_flash_support() { | ||||
| 	# Validate sysfs interface | ||||
| 	validate_sysfs_file $SYS_IMAGE_FILE | ||||
|  | ||||
| 	# By default KVM on Power host is allowed to do firmware management | ||||
| 	echo "update_flash: Firmware image management is supported." | ||||
|  | ||||
| 	exit $E_SUCCESS | ||||
| } | ||||
|  | ||||
| echo_validate_buf() { | ||||
| 	local output="$1" | ||||
| 	local cur_t=$(echo "$output" | grep "^MI" | head -n 1 | awk ' { print $2 } ') | ||||
| 	local cur_p=$(echo "$output" | grep "^MI" | head -n 1 | awk ' { print $3 } ') | ||||
| 	local new_t=$(echo "$output" | grep "^MI" | tail -n 1 | awk ' { print $2 } ') | ||||
| 	local new_p=$(echo "$output" | grep "^MI" | tail -n 1 | awk ' { print $3 } ') | ||||
|  | ||||
| 	echo "Projected Flash Update Results:" | ||||
| 	echo "Current T Image: $cur_t" | ||||
| 	echo "Current P Image: $cur_p" | ||||
| 	echo "New T Image:     $new_t" | ||||
| 	echo "New P Image:     $new_p" | ||||
| } | ||||
|  | ||||
| echo_validate_return_status() { | ||||
| 	local output="$1" | ||||
| 	local rc=$(echo "$output" | head -n 1) | ||||
| 	local opal_buf=$(echo "$output" | tail -n +2) | ||||
|  | ||||
| 	[ $# -eq 1 ] || error $E_USAGE "echo_validate_return_status(): usage." | ||||
|  | ||||
| 	if [ $rc -lt 0 ]; then | ||||
| 		echo_opal_return_status $rc | ||||
| 	fi | ||||
|  | ||||
| 	# Validation result | ||||
| 	case "$rc" in | ||||
| 	$VALIDATE_TMP_UPDATE) | ||||
| 		echo -n "info: Temporary side will be updated with a newer or" | ||||
| 		echo " identical image.";; | ||||
| 	$VALIDATE_FLASH_AUTH) | ||||
| 		error $E_OPAL "System does not have authority.";; | ||||
| 	$VALIDATE_INVALID_IMG) | ||||
| 		error $E_OPAL "Invalid candidate image for this platform.";; | ||||
| 	$VALIDATE_CUR_UNKNOWN) | ||||
| 		echo "info: Current fixpack level is unknown.";; | ||||
| 	$VALIDATE_TMP_COMMIT_DL) | ||||
| 		echo "info: Current Temporary image will be committed to" | ||||
| 		echo "Permanent side before being replaced with new image," | ||||
| 		echo "and the new image is downlevel from current image.";; | ||||
| 	$VALIDATE_TMP_COMMIT) | ||||
| 		echo "info: Current Temporary side will be committed to" | ||||
| 		echo "Permanent side before being replaced with the new" | ||||
| 		echo "image.";; | ||||
| 	$VALIDATE_TMP_UPDATE_DL) | ||||
| 		echo "info: Temporary side will be updated with a downlevel image.";; | ||||
| 	*)	error $E_OPAL "Unknown return status." | ||||
| 	esac | ||||
|  | ||||
| 	echo | ||||
| 	echo_validate_buf "$opal_buf" | ||||
|  | ||||
| 	# Do not commit T side image to P side | ||||
| 	if [ $no_overwrite_opt -eq 1 ]; then | ||||
| 		if [ $rc -eq $VALIDATE_TMP_COMMIT_DL ] || | ||||
| 			[ $rc -eq $VALIDATE_TMP_COMMIT ]; then | ||||
| 			echo "" | ||||
| 			echo "update_flash: Run without -n option to flash new image." | ||||
| 			exit $E_OVERWRITE | ||||
| 		fi | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| validate_flash() { | ||||
| 	local output="" | ||||
|  | ||||
| 	# Validate candidate image | ||||
| 	echo 1 > $SYS_VALIDATE_FLASH 2>/dev/null | ||||
|  | ||||
| 	# Display appropriate message, exiting if necessary | ||||
| 	output="$(cat $SYS_VALIDATE_FLASH)" | ||||
| 	echo_validate_return_status "$output" | ||||
| } | ||||
|  | ||||
| validate_flash_from_file() { | ||||
| 	local img_file=$1 | ||||
|  | ||||
| 	[ $# -eq 1 ] || error $E_USAGE "validate_flash_from_file(): usage." | ||||
|  | ||||
| 	# Validate sysfs interface | ||||
| 	validate_sysfs_file $SYS_VALIDATE_FLASH | ||||
|  | ||||
| 	# Copy candiadate image | ||||
| 	copy_candidate_image $img_file | ||||
|  | ||||
| 	# Validate candidate image | ||||
| 	validate_flash | ||||
|  | ||||
| 	exit $E_SUCCESS | ||||
| } | ||||
|  | ||||
| echo_update_return_status() { | ||||
| 	local rc="$1" | ||||
|  | ||||
| 	[ $# -eq 1 ] || error $E_USAGE "echo_update_return_status(): usage." | ||||
|  | ||||
| 	if [ $rc -lt 0 ]; then | ||||
| 		echo_opal_return_status $rc | ||||
| 	elif [ $rc -eq $FLASH_IMG_READY ]; then | ||||
| 		echo | ||||
| 		echo "FLASH: Image ready...rebooting the system..." | ||||
| 		echo "FLASH: This will take several minutes." | ||||
| 		echo "FLASH: Do not power off!" | ||||
| 	else | ||||
| 		error $E_SYS_FS "Unknown return status." | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| update_flash_from_file() { | ||||
| 	local img_file=$1 | ||||
| 	local output="" | ||||
|  | ||||
| 	[ $# -eq 1 ] || error $E_USAGE "update_flash_from_file(): usage." | ||||
|  | ||||
| 	# Validate sysfs interface | ||||
| 	validate_sysfs_file $SYS_UPDATE_FLASH | ||||
|  | ||||
| 	# Copy candidate image | ||||
| 	copy_candidate_image $img_file | ||||
|  | ||||
| 	# Validate candidate image | ||||
| 	validate_flash | ||||
|  | ||||
| 	# Update image | ||||
| 	echo 1 > $SYS_UPDATE_FLASH 2>/dev/null | ||||
| 	output="$(cat $SYS_UPDATE_FLASH)" | ||||
| 	echo_update_return_status "$output" | ||||
|  | ||||
| 	# Reboot system, so that we can flash new image | ||||
| 	reboot -f | ||||
|  | ||||
| 	exit $E_SUCCESS | ||||
| } | ||||
|  | ||||
| echo_manage_return_status() { | ||||
| 	local is_commit=$1 | ||||
| 	local output=$2 | ||||
| 	local rc=$(echo $output) | ||||
|  | ||||
| 	[ $# -eq 2 ] || error $E_USAGE "echo_manage_return_status(): usage." | ||||
|  | ||||
| 	if [ $rc -lt 0 ]; then | ||||
| 		echo_opal_return_status $rc | ||||
| 	elif [ $rc -eq $FLASH_SUCCESS ]; then | ||||
| 		if [ $is_commit -eq 0 ]; then | ||||
| 			echo "Success: Rejected temporary firmware image." | ||||
| 		else | ||||
| 			echo "Success: Committed temporary firmware image." | ||||
| 		fi | ||||
| 	else | ||||
| 		error $E_OPAL "Unknown return status." | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| manage_flash() { | ||||
| 	local is_commit=$1 | ||||
| 	local commit_str="1" | ||||
| 	local reject_str="0" | ||||
| 	local output="" | ||||
|  | ||||
| 	[ $# -eq 1 ] || error $E_USAGE "manage_flash(): usage." | ||||
|  | ||||
| 	# Validate sysfs interface | ||||
| 	validate_sysfs_file $SYS_MANAGE_FLASH | ||||
|  | ||||
| 	# Commit operation | ||||
| 	if [ $is_commit -eq 1 ]; then | ||||
| 		echo $commit_str > $SYS_MANAGE_FLASH | ||||
| 	else | ||||
| 		echo $reject_str > $SYS_MANAGE_FLASH | ||||
| 	fi | ||||
|  | ||||
| 	# Result | ||||
| 	output=$(cat $SYS_MANAGE_FLASH) | ||||
| 	echo_manage_return_status $is_commit "$output" | ||||
|  | ||||
| 	exit $E_SUCCESS | ||||
| } | ||||
|  | ||||
| file="" | ||||
| check_opt=0 | ||||
| commit_opt=0 | ||||
| reject_opt=0 | ||||
| validate_opt=0 | ||||
| no_overwrite_opt=0 | ||||
| file_opt=0 | ||||
|  | ||||
| # Only root user can perform firmware update | ||||
| [ "`whoami`" == "root" ] || error $E_PERM "Must be root to execute this command." | ||||
|  | ||||
| # Parse command line options | ||||
| while [ -n "$1" ]; do | ||||
| 	arg="$1" | ||||
| 	shift | ||||
| 	case "$arg" in | ||||
| 	  -q|-l|-D|-S) error $E_USAGE "The $arg option is not implemented.";; | ||||
| 	  -h) usage $E_SUCCESS;; | ||||
| 	  -s) check_opt=1;; | ||||
| 	  -c) commit_opt=1;; | ||||
| 	  -r) reject_opt=1;; | ||||
| 	  -v) validate_opt=1;; | ||||
| 	  -n) no_overwrite_opt=1;; | ||||
| 	  -f) file_opt=1; file="$1"; shift;; | ||||
| 	  *) error $E_USAGE "Unknown option ${arg}." | ||||
| 	esac | ||||
| done | ||||
|  | ||||
| if [ -n "$file" ]; then | ||||
| 	if [ $commit_opt -eq 1 ] || [ $reject_opt -eq 1 ] || | ||||
| 						[ $check_opt -eq 1 ]; then | ||||
| 		usage | ||||
| 	elif [ $validate_opt -eq 1 ] && [ $no_overwrite_opt -eq 1 ]; then | ||||
| 		usage | ||||
| 	elif [ $validate_opt -eq 1 ]; then | ||||
| 		validate_flash_from_file $file | ||||
| 	else | ||||
| 		update_flash_from_file $file | ||||
| 	fi | ||||
| else | ||||
| 	if [ $check_opt -eq 1 ]; then | ||||
| 		if [ $commit_opt -eq 1 ] || [ $reject_opt -eq 1 ]; then | ||||
| 			usage | ||||
| 		else | ||||
| 			query_flash_support | ||||
| 		fi | ||||
| 	fi | ||||
| 	[ $commit_opt -eq 0 ] && [ $reject_opt -eq 0 ] && usage | ||||
| 	[ $commit_opt -eq 1 ] && [ $reject_opt -eq 1 ] && usage | ||||
| 	manage_flash $commit_opt | ||||
| fi | ||||
		Reference in New Issue
	
	Block a user