[*] First commit
This commit is contained in:
		
							
								
								
									
										834
									
								
								scripts/functions
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										834
									
								
								scripts/functions
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,834 @@ | ||||
| #!/bin/bash | ||||
| # initscripts functions | ||||
| # | ||||
|  | ||||
| # sanitize PATH (will be overridden later when /etc/profile is sourced but is useful for udev) | ||||
| export PATH="/usr/local/bin:/usr/bin" | ||||
|  | ||||
| # clear the TZ envvar, so daemons always respect /etc/localtime | ||||
| unset TZ | ||||
|  | ||||
| RANDOM_SEED=/var/lib/misc/random-seed | ||||
|  | ||||
| [[ -z $LANG ]] && . /etc/profile.d/read_locale.sh | ||||
|  | ||||
| if [[ $1 == "start" ]]; then | ||||
| 	if [[ $PARENT_DAEMON ]]; then | ||||
| 		echo "NOTE: '${0##*/}' started as dependence of '$PARENT_DAEMON' but will be stopped first during shutdown" | ||||
| 	else | ||||
| 		export PARENT_DAEMON=${0##*/} | ||||
| 	fi | ||||
| fi | ||||
|  | ||||
| # width: | ||||
| calc_columns () { | ||||
| 	STAT_COL=80 | ||||
| 	if [[ ! -t 1 ]]; then | ||||
| 		USECOLOR="" | ||||
| 	elif [[ -t 0 ]]; then | ||||
| 		# stty will fail when stdin isn't a terminal | ||||
| 		STAT_COL=$(stty size) | ||||
| 		# stty gives "rows cols"; strip the rows number, we just want columns | ||||
| 		STAT_COL=${STAT_COL##* } | ||||
| 	elif tput cols &>/dev/null; then | ||||
| 		# is /usr/share/terminfo already mounted, and TERM recognized? | ||||
| 		STAT_COL=$(tput cols) | ||||
| 	fi | ||||
| 	if (( STAT_COL == 0 )); then | ||||
| 		# if output was 0 (serial console), set default width to 80 | ||||
| 		STAT_COL=80 | ||||
| 		USECOLOR="" | ||||
| 	fi | ||||
|  | ||||
| 	# we use 13 characters for our own stuff | ||||
| 	STAT_COL=$(( STAT_COL - 13 )) | ||||
|  | ||||
| 	if [[ -t 1 ]]; then | ||||
| 		SAVE_POSITION="\e[s" | ||||
| 		RESTORE_POSITION="\e[u" | ||||
| 		DEL_TEXT="\e[$(( STAT_COL + 4 ))G" | ||||
| 	else | ||||
| 		SAVE_POSITION="" | ||||
| 		RESTORE_POSITION="" | ||||
| 		DEL_TEXT="" | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| calc_columns | ||||
|  | ||||
| # disable colors on broken terminals | ||||
| TERM_COLORS=$(tput colors 2>/dev/null) | ||||
| if (( $? != 3 )); then | ||||
| 	case $TERM_COLORS in | ||||
| 		*[!0-9]*) USECOLOR="";; | ||||
| 		[0-7])    USECOLOR="";; | ||||
| 		'')       USECOLOR="";; | ||||
| 	esac | ||||
| fi | ||||
| unset TERM_COLORS | ||||
|  | ||||
| unquote() { | ||||
| 	local -r quotes=$'[\'"]' | ||||
|  | ||||
| 	if [[ ${1:0:1} = $quotes && ${1:(-1)} = "${1:0:1}" ]]; then | ||||
| 		printf '%s' "${1:1:(-1)}" | ||||
| 	else | ||||
| 		printf '%s' "$1" | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| parse_envfile() { | ||||
| 	local file=$1 validkeys=("${@:2}") ret=0 lineno=0 key= val= | ||||
| 	local -r comments=$'[;#]*' | ||||
|  | ||||
| 	if [[ -z $file ]]; then | ||||
| 		printf "error: no environment file specified\n" | ||||
| 		return 1 | ||||
| 	fi | ||||
|  | ||||
| 	if [[ ! -f $file ]]; then | ||||
| 		printf "error: cannot parse \`%s': No such file or directory\n" "$file" | ||||
| 		return 1 | ||||
| 	fi | ||||
|  | ||||
| 	if [[ ! -r $file ]]; then | ||||
| 		printf "error: cannot read \`%s': Permission denied\n" "$file" | ||||
| 		return 1 | ||||
| 	fi | ||||
|  | ||||
| 	while IFS='=' read -r key val; do | ||||
| 		(( ++lineno )) | ||||
|  | ||||
| 		# trim whitespace, avoiding usage of a tempfile | ||||
| 		key=$(echo "$key" | { read -r key; echo "$key"; }) | ||||
|  | ||||
| 		# key must exist and line must not be a comment | ||||
| 		[[ -z $key || ${key:0:1} = $comments ]] && continue | ||||
|  | ||||
| 		# trim whitespace, strip matching quotes | ||||
| 		val=$(echo "$val" | { read -r val; unquote "$val"; }) | ||||
|  | ||||
| 		if [[ -z $val ]]; then | ||||
| 			printf "error: found key \`%s' without value on line %s of %s\n" \ | ||||
| 					"$key" "$lineno" "$file" | ||||
| 			(( ++ret )) | ||||
| 			continue | ||||
| 		fi | ||||
|  | ||||
| 		# ignore invalid keys if we have a list of valid ones | ||||
| 		if (( ${#validkeys[*]} )) && ! in_array "$key" "${validkeys[@]}"; then | ||||
| 			continue | ||||
| 		fi | ||||
|  | ||||
| 		export "$key=$val" || (( ++ret )) | ||||
| 	done <"$file" | ||||
|  | ||||
| 	return $ret | ||||
| } | ||||
|  | ||||
| # functions: | ||||
|  | ||||
| deltext() { | ||||
| 	printf "${DEL_TEXT}" | ||||
| } | ||||
|  | ||||
| print_depr() { | ||||
| 	printf "${C_FAIL} ${1} is deprecated. See ${2} for details.${C_CLEAR} \n" | ||||
| } | ||||
|  | ||||
| printhl() { | ||||
| 	printf "${C_OTHER}${PREFIX_HL} ${C_H1}${1}${C_CLEAR} \n" | ||||
| } | ||||
|  | ||||
| printsep() { | ||||
| 	printf "\n${C_SEPARATOR}   ------------------------------\n" | ||||
| } | ||||
|  | ||||
| stat_bkgd() { | ||||
| 	printf "${C_OTHER}${PREFIX_REG} ${C_MAIN}${1}${C_CLEAR} " | ||||
| 	deltext | ||||
| 	printf "   ${C_OTHER}[${C_BKGD}BKGD${C_OTHER}]${C_CLEAR} \n" | ||||
| } | ||||
|  | ||||
| stat_busy() { | ||||
| 	printf "${C_OTHER}${PREFIX_REG} ${C_MAIN}${1}${C_CLEAR} " | ||||
| 	printf "${SAVE_POSITION}" | ||||
| 	deltext | ||||
| 	printf "   ${C_OTHER}[${C_BUSY}BUSY${C_OTHER}]${C_CLEAR} " | ||||
| } | ||||
|  | ||||
| stat_append() { | ||||
| 	printf "${RESTORE_POSITION}" | ||||
| 	printf -- "${C_MAIN}${1}${C_CLEAR}" | ||||
| 	printf "${SAVE_POSITION}" | ||||
| } | ||||
|  | ||||
| stat_done() { | ||||
| 	deltext | ||||
| 	printf "   ${C_OTHER}[${C_DONE}DONE${C_OTHER}]${C_CLEAR} \n" | ||||
| } | ||||
|  | ||||
| stat_fail() { | ||||
| 	deltext | ||||
| 	printf "   ${C_OTHER}[${C_FAIL}FAIL${C_OTHER}]${C_CLEAR} \n" | ||||
| } | ||||
|  | ||||
| stat_die() { | ||||
| 	stat_fail | ||||
| 	exit ${1:-1} | ||||
| } | ||||
|  | ||||
| status() { | ||||
| 	local quiet | ||||
| 	case $1 in | ||||
| 		-q) | ||||
| 			quiet=1 | ||||
| 			;;& | ||||
| 		-v) | ||||
| 			# NOOP: supported for backwards compat | ||||
| 			shift | ||||
| 			;; | ||||
| 	esac | ||||
| 	stat_busy "$1" | ||||
| 	shift | ||||
| 	if (( quiet )); then | ||||
| 		"$@" &>/dev/null | ||||
| 	else | ||||
| 		"$@" | ||||
| 	fi | ||||
| 	local ret=$? | ||||
| 	(( ret == 0 )) && stat_done || stat_fail | ||||
| 	return $ret | ||||
| } | ||||
|  | ||||
| #  usage : in_array( $needle, $haystack ) | ||||
| # return : 0 - found | ||||
| #          1 - not found | ||||
| in_array() { | ||||
| 	local needle=$1; shift | ||||
| 	local item | ||||
| 	for item; do | ||||
| 		[[ $item = "${needle}" ]] && return 0 | ||||
| 	done | ||||
| 	return 1 # Not Found | ||||
| } | ||||
|  | ||||
| # daemons: | ||||
|  | ||||
| add_daemon() { | ||||
| 	[[ -d /run/daemons ]] || mkdir -p /run/daemons | ||||
| 	>| /run/daemons/"$1" | ||||
| } | ||||
|  | ||||
| rm_daemon() { | ||||
| 	rm -f /run/daemons/"$1" | ||||
| } | ||||
|  | ||||
| ck_daemon() { | ||||
| 	[[ ! -f /run/daemons/$1 ]] | ||||
| } | ||||
|  | ||||
| # Check if $1 is a valid daemon name | ||||
| have_daemon() { | ||||
| 	if [[ ! -f /etc/rc.d/$1 || ! -x /etc/rc.d/$1 ]]; then | ||||
| 		printf "error: /etc/rc.d/$1 does not exist or is not executable\n" >&2 | ||||
| 		return 1 | ||||
| 	fi | ||||
| 	return 0 | ||||
| } | ||||
|  | ||||
| # Check if $1 is started at boot | ||||
| ck_autostart() { | ||||
| 	local daemon | ||||
| 	for daemon in "${DAEMONS[@]}"; do | ||||
| 		[[ $1 = "${daemon#@}" ]] && return 1 | ||||
| 	done | ||||
| 	return 0 | ||||
| } | ||||
|  | ||||
| start_daemon() { | ||||
| 	have_daemon "$1" && /etc/rc.d/"$1" start | ||||
| } | ||||
|  | ||||
| start_daemon_bkgd() { | ||||
| 	stat_bkgd "Starting $1" | ||||
| 	(start_daemon "$1") >/dev/null & | ||||
| } | ||||
|  | ||||
| stop_daemon() { | ||||
| 	have_daemon "$1" && /etc/rc.d/"$1" stop | ||||
| } | ||||
|  | ||||
| # Status functions | ||||
| status_started() { | ||||
| 	deltext | ||||
| 	echo -ne "$C_OTHER[${C_STRT}STARTED$C_OTHER]$C_CLEAR " | ||||
| } | ||||
|  | ||||
| status_stopped() { | ||||
| 	deltext | ||||
| 	echo -ne "$C_OTHER[${C_STRT}STOPPED$C_OTHER]$C_CLEAR " | ||||
| } | ||||
|  | ||||
| ck_status() { | ||||
| 	! ck_daemon "$1" && status_started || status_stopped | ||||
| } | ||||
|  | ||||
| # Return PID of $1 | ||||
| get_pid() { | ||||
| 	pidof -o %PPID $1 || return 1 | ||||
| } | ||||
|  | ||||
| # Check if PID-file $1 is still the active PID-file for command $2 | ||||
| ck_pidfile() { | ||||
| 	if [[ -f $1 ]]; then | ||||
| 		local fpid ppid | ||||
| 		read -r fpid <"$1" | ||||
| 		ppid=$(get_pid "$2") | ||||
| 		[[ $fpid = "${ppid}" ]] && return 0 | ||||
| 	fi | ||||
| 	return 1 | ||||
| } | ||||
|  | ||||
| # PIDs to be omitted by killall5 | ||||
| declare -a omit_pids | ||||
|  | ||||
| add_omit_pids() { | ||||
| 	omit_pids+=( $@ ) | ||||
| } | ||||
|  | ||||
| # Stop all daemons | ||||
| # This function should *never* ever perform any other actions beside calling stop_daemon()! | ||||
| # It might be used by a splash system etc. to get a list of daemons to be stopped. | ||||
| stop_all_daemons() { | ||||
| 	# Find daemons NOT in the DAEMONS array. Shut these down first | ||||
| 	local daemon | ||||
| 	for daemon in /run/daemons/*; do | ||||
| 		[[ -f $daemon ]] || continue | ||||
| 		daemon=${daemon##*/} | ||||
| 		ck_autostart "$daemon" && stop_daemon "$daemon" | ||||
| 	done | ||||
|  | ||||
| 	# Shutdown daemons in reverse order | ||||
| 	local i daemon | ||||
| 	for (( i=${#DAEMONS[@]}-1; i>=0; i-- )); do | ||||
| 		[[ ${DAEMONS[i]} = '!'* ]] && continue | ||||
| 		daemon=${DAEMONS[i]#@} | ||||
| 		ck_daemon "$daemon" || stop_daemon "$daemon" | ||||
| 	done | ||||
| } | ||||
|  | ||||
| # $1 - signal | ||||
| # $2 - iterations | ||||
| kill_all_wait() { | ||||
| 	# Send SIGTERM/SIGKILL all processes and wait until killall5 | ||||
| 	# reports all done or timeout. | ||||
| 	# Unfortunately killall5 does not support the 0 signal, so just | ||||
| 	# use SIGCONT for checking (which should be ignored). | ||||
|  | ||||
| 	local i | ||||
|  | ||||
| 	killall5 -${1} ${omit_pids[@]/#/-o } &>/dev/null | ||||
|  | ||||
| 	for (( i=0; i<${2}; i++ )); do | ||||
|  | ||||
| 		sleep .25 # 1/4 second | ||||
|  | ||||
| 		# sending SIGCONT to processes to check if they are there | ||||
| 		killall5 -18 ${omit_pids[@]/#/-o } &>/dev/null | ||||
|  | ||||
| 		if (( $? == 2 )); then | ||||
| 			return 0 | ||||
| 		fi | ||||
| 	done | ||||
|  | ||||
| 	return 1 | ||||
| } | ||||
|  | ||||
| kill_all() { | ||||
| 	stat_busy "Sending SIGTERM to processes" | ||||
| 		kill_all_wait 15 40 | ||||
| 		if (( $? == 0 )); then | ||||
| 			stat_done | ||||
| 		else | ||||
| 			stat_fail | ||||
| 			status "Sending SIGKILL to processes" kill_all_wait 9 60 | ||||
| 		fi | ||||
| } | ||||
|  | ||||
| print_welcome() { | ||||
| 	# see os-release(5) | ||||
| 	. /usr/lib/os-release | ||||
|  | ||||
| 	echo " " | ||||
| 	printhl "${PRETTY_NAME}\n" | ||||
| 	printhl "${C_H2}${HOME_URL}" | ||||
| 	printsep | ||||
| } | ||||
|  | ||||
| create_blacklist() { | ||||
| 	# $* = list of blacklisted modules | ||||
|  | ||||
| 	stat_busy "Creating UDev blacklist" | ||||
|  | ||||
| 	mkdir -p /run/modprobe.d | ||||
| 	echo "# Autogenerated from rc.conf at boot, do not edit" > /run/modprobe.d/modprobe-blacklist.conf | ||||
| 	(( ${#*} )) && printf 'blacklist %s\n' "${*}" >> /run/modprobe.d/modprobe-blacklist.conf | ||||
|  | ||||
| 	(( $? == 0 )) && stat_done || stat_fail | ||||
| } | ||||
|  | ||||
| # Start/trigger udev, load MODULES, and settle udev | ||||
| udevd_modprobe() { | ||||
| 	# $1 = where we are being called from. | ||||
| 	# This is used to determine which hooks to run. | ||||
|  | ||||
| 	# Modules prefixed with ! should be blacklisted | ||||
| 	local blacklist=(${MODULES[@]##[^!]*}) | ||||
| 	[[ $blacklist ]] && create_blacklist ${blacklist[@]/!/} | ||||
|  | ||||
| 	if [ -x /usr/lib/systemd/systemd-udevd ]; then | ||||
| 		UDEVD_COMMAND=/usr/lib/systemd/systemd-udevd | ||||
| 	elif [ -x /usr/bin/udevd ]; then | ||||
| 		# For future forks with merged /usr/bin | ||||
| 		UDEVD_COMMAND=/usr/bin/udevd | ||||
| 	else | ||||
| 		echo "Unable to find udevd binary" | ||||
| 		return 1 | ||||
| 	fi | ||||
|  | ||||
| 	status "Starting udev daemon" $UDEVD_COMMAND --daemon | ||||
|  | ||||
| 	run_hook "$1_udevlaunched" | ||||
|  | ||||
| 	stat_busy "Triggering udev uevents" | ||||
| 		udevadm trigger --action=add --type=subsystems | ||||
| 		udevadm trigger --action=add --type=devices | ||||
| 	stat_done | ||||
|  | ||||
| 	# Load modules from the MODULES array or modules-load.d | ||||
| 	stat_busy "Loading user-specified modules" | ||||
| 	if (( ${#MODULES[*]} )); then | ||||
| 		local -a modules=(${MODULES[@]/!*/}) | ||||
|  | ||||
| 		if [[ ${modules[@]} =~ [^\ ] ]]; then | ||||
| 			modprobe -ab "${modules[@]}" | ||||
| 		fi | ||||
| 	else | ||||
| 		/usr/lib/initscripts/arch-modules | ||||
| 	fi | ||||
| 	(( $? == 0 )) && stat_done || stat_fail | ||||
|  | ||||
| 	status "Waiting for udev uevents to be processed" \ | ||||
| 		udevadm settle | ||||
|  | ||||
| 	run_hook "$1_udevsettled" | ||||
|  | ||||
| 	# in case loading a module changed the display mode | ||||
| 	calc_columns | ||||
| } | ||||
|  | ||||
| set_consolefont() { | ||||
| 	#CONSOLEMAP in UTF-8 shouldn't be used | ||||
| 	[[ $CONSOLEMAP && ${LOCALE,,} =~ utf ]] && CONSOLEMAP="" | ||||
| 	local i | ||||
| 	for i in /dev/tty[0-9]*; do | ||||
| 	  setfont ${CONSOLEMAP:+-m "${CONSOLEMAP}"} \ | ||||
| 	    "$CONSOLEFONT" -C ${i} &>/dev/null | ||||
| 	done | ||||
| 	return $? | ||||
| } | ||||
|  | ||||
| activate_vgs() { | ||||
| 	[[ $USELVM = [yY][eE][sS] && -x $(type -P lvm) && -d /sys/block ]] || return 0 | ||||
| 	stat_busy "Activating LVM2 groups" | ||||
| 		vgchange --sysinit -a y >/dev/null | ||||
| 	(( $? == 0 )) && stat_done || stat_fail | ||||
| } | ||||
|  | ||||
| do_unlock_legacy() { | ||||
| 	# $1 = requested name | ||||
| 	# $2 = source device | ||||
| 	# $3 = password | ||||
| 	# $4 = options | ||||
| 	print_depr "The legacy crypttab format" "crypttab(5)" | ||||
| 	local open=create a=$1 b=$2 failed=0 | ||||
| 	# Ordering of options is different if you are using LUKS vs. not. | ||||
| 	# Use ugly swizzling to deal with it. | ||||
| 	# isLuks only gives an exit code but no output to stdout or stderr. | ||||
| 	if cryptsetup isLuks "$2" 2>/dev/null; then | ||||
| 		open=luksOpen | ||||
| 		a=$2 | ||||
| 		b=$1 | ||||
| 	fi | ||||
| 	case $3 in | ||||
| 		SWAP) | ||||
| 			local _overwriteokay=0 | ||||
| 			if [[ -b $2 && -r $2 ]]; then | ||||
| 				# This is DANGEROUS! If there is any known file system, | ||||
| 				# partition table, RAID, or LVM volume on the device, | ||||
| 				# we don't overwrite it. | ||||
| 				# | ||||
| 				# 'blkid' returns 2 if no valid signature has been found. | ||||
| 				# Only in this case should we allow overwriting the device. | ||||
| 				# | ||||
| 				# This sanity check _should_ be sufficient, but it might not. | ||||
| 				# This may cause data loss if it is not used carefully. | ||||
| 				blkid -p "$2" &>/dev/null | ||||
| 				(( $? == 2 )) && _overwriteokay=1 | ||||
| 			fi | ||||
| 			if (( _overwriteokay == 0 )); then | ||||
| 				false | ||||
| 			elif cryptsetup -d /dev/urandom $4 $open "$a" "$b" >/dev/null; then | ||||
| 				printf "creating swapspace..\n" | ||||
| 				mkswap -f -L $1 /dev/mapper/$1 >/dev/null | ||||
| 			fi;; | ||||
| 		ASK) | ||||
| 			printf "\nOpening '$1' volume:\n" | ||||
| 			cryptsetup $4 $open "$a" "$b" < /dev/console;; | ||||
| 		/dev*) | ||||
| 			local ckdev=${3%%:*} | ||||
| 			local cka=${3#*:} | ||||
| 			local ckb=${cka#*:} | ||||
| 			local cka=${cka%:*} | ||||
| 			local ckfile=/dev/ckfile | ||||
| 			local ckdir=/dev/ckdir | ||||
| 			case ${cka} in | ||||
| 				*[!0-9]*) | ||||
| 					# Use a file on the device | ||||
| 					# cka is not numeric: cka=filesystem, ckb=path | ||||
| 					mkdir ${ckdir} | ||||
| 					mount -r -t ${cka} ${ckdev} ${ckdir} | ||||
| 					dd if=${ckdir}/${ckb} of=${ckfile} >/dev/null 2>&1 | ||||
| 					umount ${ckdir} | ||||
| 					rmdir ${ckdir};; | ||||
| 				*) | ||||
| 					# Read raw data from the block device | ||||
| 					# cka is numeric: cka=offset, ckb=length | ||||
| 					dd if=${ckdev} of=${ckfile} bs=1 skip=${cka} count=${ckb} >/dev/null 2>&1;; | ||||
| 			esac | ||||
| 			cryptsetup -d ${ckfile} $4 $open "$a" "$b" >/dev/null | ||||
| 			dd if=/dev/urandom of=${ckfile} bs=1 count=$(stat -c %s ${ckfile}) conv=notrunc >/dev/null 2>&1 | ||||
| 			rm ${ckfile};; | ||||
| 		/*) | ||||
| 			cryptsetup -d "$3" $4 $open "$a" "$b" >/dev/null;; | ||||
| 		*) | ||||
| 			echo "$3" | cryptsetup $4 $open "$a" "$b" >/dev/null;; | ||||
| 	esac | ||||
| 	return $? | ||||
| } | ||||
|  | ||||
| do_unlock_systemd() { | ||||
| 	local name=$1 device=$2 password=$3 options=$4 failed=0 | ||||
|  | ||||
| 	if [ ! -x /usr/lib/systemd/systemd-cryptsetup ]; then | ||||
| 		echo "Unable to find systemd-cryptsetup binary" | ||||
| 		return 1 | ||||
| 	fi | ||||
|  | ||||
| 	# lazily convert tags to udev symlinks | ||||
| 	case $device in | ||||
| 		UUID=*) | ||||
| 			device=/dev/disk/by-uuid/$(unquote "${device#UUID=}") | ||||
| 			;; | ||||
| 		PARTUUID=*) | ||||
| 			device=/dev/disk/by-partuuid/$(unquote "${device#PARTUUID=}") | ||||
| 			;; | ||||
| 	esac | ||||
|  | ||||
| 	if ! /usr/lib/systemd/systemd-cryptsetup attach "$name" "$device" "$password" $options; then | ||||
| 		failed=1 | ||||
| 	else | ||||
| 		options=${options//,/ } | ||||
| 		if in_array swap ${options[@]}; then | ||||
| 			# create swap on the device only if no fs signature exists | ||||
| 			blkid -p "$2" &>/dev/null | ||||
| 			if (( $? != 2 )) || ! mkswap -f /dev/mapper/$name >/dev/null; then | ||||
| 				failed=1 | ||||
| 			fi | ||||
| 		elif in_array tmp ${options[@]}; then | ||||
| 			# create fs on the device only if no fs signature exists | ||||
| 			blkid -p "$2" &>/dev/null | ||||
| 			if (( $? != 2 )) || ! mke2fs /dev/mapper/$name >/dev/null; then | ||||
| 				failed=1 | ||||
| 			fi | ||||
| 		fi | ||||
| 	fi | ||||
| 	return $failed | ||||
| } | ||||
|  | ||||
| do_unlock() { | ||||
| 	local name=$1 device=$2 password=$3 options=$4 | ||||
|  | ||||
| 	printf "${C_MAIN}Unlocking $1${C_CLEAR}\n" | ||||
|  | ||||
| 	if [[ ${options:0:2} =~ -. ]]; then | ||||
| 		do_unlock_legacy "$name" "$device" "$password" "$options" | ||||
| 		return $? | ||||
| 	fi | ||||
|  | ||||
| 	case $password in | ||||
| 		ASK|SWAP) | ||||
| 			do_unlock_legacy "$name" "$device" "$password" "$options" | ||||
| 			;; | ||||
| 		/dev/*) | ||||
| 			if [[ ${password##*:} == $password ]]; then | ||||
| 				do_unlock_systemd "$name" "$device" "$password" "$options" | ||||
| 			else | ||||
| 				do_unlock_legacy "$name" "$device" "$password" "$options" | ||||
| 			fi | ||||
| 			;; | ||||
| 		/*|none|-|'') | ||||
| 			do_unlock_systemd "$name" "$device" "$password" "$options" | ||||
| 			;; | ||||
| 		*) | ||||
| 			do_unlock_legacy "$name" "$device" "$password" "$options" | ||||
| 			;; | ||||
| 	esac | ||||
| 	failed=$? | ||||
| 	if (( $failed )); then | ||||
| 		printf "${C_FAIL}Unlocking of $1 failed.${C_CLEAR}\n" | ||||
| 	fi | ||||
| 	return $? | ||||
| } | ||||
|  | ||||
| do_lock() { | ||||
| 	#status "Detaching encrypted device ${1}" /usr/lib/systemd/systemd-cryptsetup detach "$1" >/dev/null | ||||
| 	stat_busy "Detaching encrypted device ${1}" | ||||
| 	if [ -x /usr/lib/systemd/systemd-cryptsetup ]; then | ||||
| 		/usr/lib/systemd/systemd-cryptsetup detach "$1" >/dev/null | ||||
| 	else | ||||
| 		cryptsetup remove "$1" &>/dev/null | ||||
| 	fi | ||||
| 	(( $? == 0 )) && stat_done || stat_fail | ||||
| } | ||||
|  | ||||
| read_crypttab() { | ||||
| 	# $1 = function to call with the split out line from the crypttab | ||||
| 	local line nspo failed=0 | ||||
| 	while read line <&3; do | ||||
| 		[[ $line && $line != '#'* ]] || continue | ||||
| 		eval nspo=("${line%#*}") | ||||
| 		if $1 "${nspo[0]}" "${nspo[1]}" "${nspo[2]}" "${nspo[*]:3}"; then | ||||
| 			crypto_unlocked=1 | ||||
| 		else | ||||
| 			failed=1 | ||||
| 		fi | ||||
| 	done 3< /etc/crypttab | ||||
| 	return $failed | ||||
| } | ||||
|  | ||||
| set_timezone() { | ||||
| 	local tz=$1 zonefile=/usr/share/zoneinfo/$1 | ||||
|  | ||||
| 	[[ $tz ]] || return 1 | ||||
|  | ||||
| 	if [[ ! -e $zonefile ]]; then | ||||
| 		printf "error: \`%s' is not a valid time zone\n" "$tz" | ||||
| 		return 1 | ||||
| 	fi | ||||
|  | ||||
| 	if [[ -L /etc/localtime && /etc/localtime -ef $zonefile ]]; then | ||||
| 		return 0 | ||||
| 	else | ||||
| 		ln -sf "/usr/share/zoneinfo/$tz" /etc/localtime | ||||
| 	fi | ||||
| } | ||||
|  | ||||
| # Filesystem functions | ||||
| # These can be overridden/reused for customizations like shutdown/loop-fsck. | ||||
| NETFS="nfs,nfs4,smbfs,cifs,codafs,ncpfs,shfs,fuse,fuseblk,glusterfs,davfs,fuse.glusterfs" | ||||
|  | ||||
| # Check local filesystems | ||||
| fsck_all() { | ||||
| 	if [[ -f /forcefsck ]] || in_array forcefsck $(< /proc/cmdline); then | ||||
| 		FORCEFSCK="-f" | ||||
| 	elif [[ -f /fastboot ]] || in_array fastboot $(< /proc/cmdline); then | ||||
| 		return 0 | ||||
| 	elif findmnt / --options rw &>/dev/null; then | ||||
| 		IGNORE_MOUNTED="-M" | ||||
| 	fi | ||||
|  | ||||
| 	fsck -A -T -C${FSCK_FD} -a -t no${NETFS//,/,no},noopts=_netdev ${IGNORE_MOUNTED} -- ${FORCEFSCK} | ||||
| } | ||||
|  | ||||
| # Single-user login and/or automatic reboot after fsck (if needed) | ||||
| fsck_reboot() { | ||||
| 	# $1 = exit code returned by fsck | ||||
| 	# Ignore conditions 'FS errors corrected' and 'Cancelled by the user' | ||||
| 	(( ($1 | 33) == 33 )) && return 0 | ||||
| 	if (( $1 & 2 )); then | ||||
| 		echo | ||||
| 		echo "********************** REBOOT REQUIRED *********************" | ||||
| 		echo "*                                                          *" | ||||
| 		echo "* The system will be rebooted automatically in 15 seconds. *" | ||||
| 		echo "*                                                          *" | ||||
| 		echo "************************************************************" | ||||
| 		echo | ||||
| 		sleep 15 | ||||
| 	else | ||||
| 		echo | ||||
| 		echo "*****************  FILESYSTEM CHECK FAILED  ****************" | ||||
| 		echo "*                                                          *" | ||||
| 		echo "*  Please repair manually and reboot. Note that the root   *" | ||||
| 		echo "*  file system is currently mounted read-only. To remount  *" | ||||
| 		echo "*  it read-write, type: mount -o remount,rw /              *" | ||||
| 		echo "*  When you exit the maintenance shell, the system will    *" | ||||
| 		echo "*  reboot automatically.                                   *" | ||||
| 		echo "*                                                          *" | ||||
| 		echo "************************************************************" | ||||
| 		echo | ||||
| 		sulogin -p | ||||
| 	fi | ||||
| 	echo "Automatic reboot in progress..." | ||||
| 	umount -a | ||||
| 	mount -o remount,ro / | ||||
| 	reboot -f | ||||
| 	exit 0 | ||||
| } | ||||
|  | ||||
| mount_all() { | ||||
| 	mount -a -t "no${NETFS//,/,no}" -O no_netdev | ||||
| } | ||||
|  | ||||
| umount_all() { | ||||
| 	# $1: restrict to fstype | ||||
|  | ||||
| 	findmnt -mrunRo TARGET,FSTYPE,OPTIONS / | { | ||||
| 		while read -r target fstype options; do | ||||
| 			# match only targeted fstypes | ||||
| 			if [[ $1 && $1 != "$fstype" ]]; then | ||||
| 				continue | ||||
| 			fi | ||||
|  | ||||
| 			# do not unmount API filesystems | ||||
| 			if [[ $target = /@(proc|sys|run|dev|dev/pts) ]]; then | ||||
| 				continue | ||||
| 			fi | ||||
|  | ||||
| 			# avoid networked devices | ||||
| 			IFS=, read -ra opts <<< "$options" | ||||
| 			if in_array _netdev "${opts[@]}"; then | ||||
| 				continue | ||||
| 			fi | ||||
|  | ||||
| 			mounts=("$target" "${mounts[@]}") | ||||
| 		done | ||||
|  | ||||
| 		if (( ${#mounts[*]} )); then | ||||
| 			umount -r "${mounts[@]}" | ||||
| 		fi | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| remove_leftover() { | ||||
| 	status 'Removing leftover files' /usr/lib/initscripts/arch-tmpfiles --create --remove --clean --boot | ||||
| } | ||||
|  | ||||
| bootlogd_stop() { | ||||
| 	[[ -f /run/bootlogd.pid ]] || return 0 | ||||
| 	touch /var/log/boot | ||||
| 	kill $(< /run/bootlogd.pid) | ||||
| 	rm -f /run/bootlogd.pid | ||||
| } | ||||
|  | ||||
| ############################### | ||||
| # Custom hooks in initscripts # | ||||
| ############################### | ||||
| # Hooks can be used to include custom code in various places in the rc.* scripts | ||||
| # | ||||
| # To define a hook function, create a file with any name in functions.d containing: | ||||
| #  function_name() { | ||||
| #    ... | ||||
| #  } | ||||
| #  add_hook hook_name function_name | ||||
| # It is allowed to register several hook functions for the same hook | ||||
| # Is is also allowed to register the same hook function for several hooks | ||||
| # | ||||
| # Functions can be created for the following hooks: | ||||
| # sysinit_start: at the beginning of rc.sysinit | ||||
| # multi_start: at the beginning of rc.multi | ||||
| # single_start: at the beginning of rc.single | ||||
| # shutdown_start: at the beginning of rc.shutdown | ||||
| # sysinit_end: at the end of rc.sysinit | ||||
| # multi_end: at the end of rc.multi | ||||
| # single_end: at the end of rc.single | ||||
| # sysinit_udevlaunched: after udev has been launched in rc.sysinit (called from functions) | ||||
| # single_udevlaunched: after udev has been launched in rc.single (called from functions) | ||||
| # sysinit_udevsettled: after uevents have settled in rc.sysinit (called from functions) | ||||
| # single_udevsettled: after uevents have settled in rc.single (called from functions) | ||||
| # sysinit_prefsck: before local filesystems are checked in rc.sysinit | ||||
| # sysinit_postfsck: after local filesystems are checked in rc.sysinit | ||||
| # sysinit_premount: before local filesystems are mounted, but after root is mounted read-write in rc.sysinit | ||||
| # sysinit_postmount: after local filesystems are mounted in rc.sysinit | ||||
| # shutdown_prekillall: before all processes are being killed in rc.shutdown | ||||
| # single_prekillall: before all processes are being killed in rc.single | ||||
| # shutdown_postkillall: after all processes have been killed in rc.shutdown | ||||
| # single_postkillall: after all processes have been killed in rc.single | ||||
| # shutdown_preumount: after last filesystem write, but before filesystems are unmounted in rc.shutdown | ||||
| # shutdown_postumount: after filesystems are unmounted in rc.shutdown | ||||
| # shutdown_poweroff: directly before powering off in rc.shutdown | ||||
| # | ||||
| # Declare add_hook and run_hook as read-only to prevent overwriting them. | ||||
| # Too bad we cannot do the same thing with hook_funcs | ||||
|  | ||||
| if (( RC_FUNCTIONS_HOOK_FUNCS_DEFINED != 1 )); then | ||||
| 	declare -A hook_funcs | ||||
|  | ||||
| 	add_hook() { | ||||
| 		[[ $1 && $2 ]] || return 1 | ||||
| 		hook_funcs[$1]+=" $2" | ||||
| 	} | ||||
|  | ||||
| 	run_hook() { | ||||
| 		[[ $1 ]] || return 1 | ||||
| 		local func | ||||
| 		for func in ${hook_funcs["$1"]}; do | ||||
| 			"${func}" | ||||
| 		done | ||||
| 	} | ||||
|  | ||||
| 	declare -fr add_hook run_hook | ||||
| 	declare -r RC_FUNCTIONS_HOOK_FUNCS_DEFINED=1 | ||||
| fi | ||||
|  | ||||
| # set colors | ||||
| if [[ $USECOLOR != [nN][oO] ]]; then | ||||
| 	if tput setaf 0 &>/dev/null; then | ||||
| 		C_CLEAR=$(tput sgr0)                      # clear text | ||||
| 		C_MAIN=${C_CLEAR}$(tput bold)        # main text | ||||
| 		C_OTHER=${C_MAIN}$(tput setaf 4)     # prefix & brackets | ||||
| 		C_SEPARATOR=${C_MAIN}$(tput setaf 0) # separator | ||||
| 		C_BUSY=${C_CLEAR}$(tput setaf 6)     # busy | ||||
| 		C_FAIL=${C_MAIN}$(tput setaf 1)      # failed | ||||
| 		C_DONE=${C_MAIN}                          # completed | ||||
| 		C_BKGD=${C_MAIN}$(tput setaf 5)      # backgrounded | ||||
| 		C_H1=${C_MAIN}                            # highlight text 1 | ||||
| 		C_H2=${C_MAIN}$(tput setaf 6)        # highlight text 2 | ||||
| 	else | ||||
| 		C_CLEAR="\e[m"          # clear text | ||||
| 		C_MAIN="\e[;1m"         # main text | ||||
| 		C_OTHER="\e[1;34m"      # prefix & brackets | ||||
| 		C_SEPARATOR="\e[1;30m"  # separator | ||||
| 		C_BUSY="\e[;36m"        # busy | ||||
| 		C_FAIL="\e[1;31m"       # failed | ||||
| 		C_DONE=${C_MAIN}        # completed | ||||
| 		C_BKGD="\e[1;35m"       # backgrounded | ||||
| 		C_H1=${C_MAIN}          # highlight text 1 | ||||
| 		C_H2="\e[1;36m"         # highlight text 2 | ||||
| 	fi | ||||
| fi | ||||
|  | ||||
| # prefixes: | ||||
|  | ||||
| PREFIX_REG="::" | ||||
| PREFIX_HL=" >" | ||||
|  | ||||
| # Source additional functions at the end to allow overrides | ||||
| for f in /etc/rc.d/functions.d/*; do | ||||
| 	[[ -e $f ]] && . "$f" | ||||
| done | ||||
|  | ||||
| # End of file | ||||
| # vim: set ts=2 sw=2 noet: | ||||
							
								
								
									
										6
									
								
								scripts/rc.local
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										6
									
								
								scripts/rc.local
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| #!/bin/bash | ||||
| # | ||||
| # /etc/rc.local: Local multi-user start-up script. | ||||
| # | ||||
|  | ||||
|  | ||||
							
								
								
									
										5
									
								
								scripts/rc.local.shutdown
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										5
									
								
								scripts/rc.local.shutdown
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| #!/bin/bash | ||||
| # | ||||
| # /etc/rc.local.shutdown: Local shutdown script. | ||||
| # | ||||
|  | ||||
							
								
								
									
										34
									
								
								scripts/rc.multi
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										34
									
								
								scripts/rc.multi
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| #!/bin/bash | ||||
| # | ||||
| # /etc/rc.multi | ||||
| # | ||||
|  | ||||
| . /etc/rc.conf | ||||
| . /etc/rc.d/functions | ||||
|  | ||||
| run_hook multi_start | ||||
|  | ||||
| # Load sysctl config files | ||||
| status "Configuring kernel parameters" sysctl -q --system | ||||
|  | ||||
| # Load additional binary formats | ||||
| status "Configure additional binary formats" /usr/lib/initscripts/arch-binfmt | ||||
|  | ||||
| # Start daemons | ||||
| for daemon in "${DAEMONS[@]}"; do | ||||
| 	case ${daemon:0:1} in | ||||
| 		'!') continue;;     # Skip this daemon. | ||||
| 		'@') start_daemon_bkgd "${daemon#@}";; | ||||
| 		*)   start_daemon "$daemon";; | ||||
| 	esac | ||||
| done | ||||
|  | ||||
| [[ -x /etc/rc.local ]] && /etc/rc.local | ||||
|  | ||||
| run_hook multi_end | ||||
|  | ||||
| bootlogd_stop | ||||
|  | ||||
| rm -f /run/nologin | ||||
|  | ||||
| # vim: set ts=2 sw=2 noet: | ||||
							
								
								
									
										142
									
								
								scripts/rc.shutdown
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										142
									
								
								scripts/rc.shutdown
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,142 @@ | ||||
| #!/bin/bash | ||||
| # | ||||
| # /etc/rc.shutdown | ||||
| # | ||||
|  | ||||
| . /etc/rc.conf | ||||
| . /etc/rc.d/functions | ||||
|  | ||||
| # don't let all the systemd tools be too verbose | ||||
| export SYSTEMD_LOG_LEVEL="notice" | ||||
|  | ||||
| # avoid staircase effect | ||||
| stty onlcr | ||||
|  | ||||
| echo " " | ||||
| printhl "Initiating shutdown..." | ||||
| echo " " | ||||
|  | ||||
| run_hook shutdown_start | ||||
|  | ||||
| [[ -x /etc/rc.local.shutdown ]] && /etc/rc.local.shutdown | ||||
|  | ||||
| stop_all_daemons | ||||
|  | ||||
| #status 'Saving random seed' /usr/lib/systemd/systemd-random-seed save | ||||
| stat_busy "Saving Random Seed" | ||||
|         RANDOM_SEED=/var/lib/misc/random-seed | ||||
|         install -TDm 0600 /dev/null $RANDOM_SEED | ||||
|         POOL_FILE=/proc/sys/kernel/random/poolsize | ||||
|         if [[ -r $POOL_FILE ]]; then | ||||
|                 read POOL_SIZE < $POOL_FILE | ||||
|                 (( POOL_SIZE /= 8 )) | ||||
|         else | ||||
|                 POOL_SIZE=512 | ||||
|         fi | ||||
|         dd if=/dev/urandom of=$RANDOM_SEED count=1 bs=$POOL_SIZE &>/dev/null | ||||
| stat_done | ||||
|  | ||||
| [[ $TIMEZONE ]] && status "Configuring time zone" set_timezone "$TIMEZONE" | ||||
|  | ||||
| # Write to wtmp file before unmounting | ||||
| halt -w | ||||
|  | ||||
| # stop monitoring of LVM2 groups before unmounting filesystems | ||||
| [[ $USELVM = [Yy][Ee][Ss] && -x $(type -P lvm) ]] && | ||||
| 	status "Deactivating monitoring of LVM2 groups" vgchange --monitor n | ||||
|  | ||||
| # any future uevents can and should be ignored | ||||
| status "Shutting down udev" udevadm control --exit | ||||
|  | ||||
| run_hook shutdown_prekillall | ||||
|  | ||||
| kill_all | ||||
|  | ||||
| run_hook shutdown_postkillall | ||||
|  | ||||
| run_hook shutdown_preumount | ||||
|  | ||||
| # unmount any non-API partitions that are backed by swap; we don't want to | ||||
| # move their contents into memory (waste of time and might caues OOM). | ||||
| status "Unmounting swap-backed filesystems" umount_all "tmpfs" | ||||
|  | ||||
| # almost everything is dead now, so the swap should hopefully be relatively | ||||
| # empty, and quick to switch off | ||||
| status "Deactivating swap" swapoff -a | ||||
|  | ||||
| status "Unmounting non-API filesystems" umount_all | ||||
|  | ||||
| run_hook shutdown_postumount | ||||
|  | ||||
| # Kill non-root encrypted partition mappings | ||||
| if [[ -f /etc/crypttab ]] && type -p cryptsetup >/dev/null; then | ||||
| 	# Maybe someone has LVM on an encrypted block device | ||||
| 	# executing an extra vgchange is errorless | ||||
| 	[[ $USELVM = [Yy][Ee][Ss] ]] && vgchange --sysinit -a n &>/dev/null | ||||
| 	read_crypttab do_lock | ||||
| fi | ||||
|  | ||||
| [[ $USELVM = [Yy][Ee][Ss] && -x $(type -P lvm) ]] && | ||||
| 	status "Deactivating LVM2 groups" vgchange --sysinit -a n &>/dev/null | ||||
|  | ||||
| run_hook shutdown_poweroff | ||||
|  | ||||
| if [[ -x /run/initramfs/shutdown ]]; then | ||||
|  | ||||
| 	# decide what we want to do | ||||
| 	if [[ $RUNLEVEL = 0 ]]; then | ||||
| 		action="poweroff" | ||||
| 	else | ||||
| 		{ read kexec_loaded </sys/kernel/kexec_loaded; } 2>/dev/null | ||||
| 		if (( kexec_loaded )); then | ||||
| 			action="kexec" | ||||
| 		else | ||||
| 			action="reboot" | ||||
| 		fi | ||||
| 	fi | ||||
|  | ||||
| 	# make /run/initramfs a mount | ||||
| 	mount --bind /run/initramfs /run/initramfs | ||||
|  | ||||
| 	# in case someone has shared our mountpoints, unshare them | ||||
| 	mount --make-private /run/initramfs | ||||
| 	mount --make-private / | ||||
|  | ||||
| 	# bind all API mounts | ||||
| 	mkdir -p /run/initramfs/{sys,proc,dev,run,oldroot} | ||||
| 	mount --bind /sys /run/initramfs/sys | ||||
| 	mount --bind /proc /run/initramfs/proc | ||||
| 	mount --bind /dev /run/initramfs/dev | ||||
| 	mount --bind /run /run/initramfs/run | ||||
|  | ||||
| 	# enter shutdownramfs | ||||
| 	cd /run/initramfs | ||||
| 	pivot_root . oldroot | ||||
|  | ||||
| 	# reexec init | ||||
| 	/oldroot/usr/bin/init u | ||||
|  | ||||
| 	# run /shutdown in the new root | ||||
| 	exec chroot . /shutdown $action </dev/console >/dev/console 2>&1 | ||||
|  | ||||
| else | ||||
|  | ||||
| 	status "Remounting root filesystem read-only" \ | ||||
| 		mount -o remount,ro / | ||||
|  | ||||
| 	# Power off or reboot | ||||
| 	printsep | ||||
| 	if [[ $RUNLEVEL = 0 ]]; then | ||||
| 		printhl "${C_H2}POWER OFF" | ||||
| 		poweroff -d -f -h -i | ||||
| 	else | ||||
| 		printhl "${C_H2}REBOOTING" | ||||
| 		# if kexec is installed and a kernel is loaded, use it | ||||
| 		[[ -x $(type -P kexec) ]] && kexec -e &>/dev/null | ||||
| 		reboot -d -f -i | ||||
| 	fi | ||||
|  | ||||
| fi | ||||
|  | ||||
| # End of file | ||||
| # vim: set ts=2 sw=2 noet: | ||||
							
								
								
									
										41
									
								
								scripts/rc.single
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										41
									
								
								scripts/rc.single
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| #!/bin/bash | ||||
| # | ||||
| # /etc/rc.single: Single-user start-up script. | ||||
| # | ||||
|  | ||||
| . /etc/rc.conf | ||||
| . /etc/rc.d/functions | ||||
|  | ||||
| run_hook single_start | ||||
|  | ||||
| if [[ $PREVLEVEL != N ]]; then | ||||
|  | ||||
| 	stop_all_daemons | ||||
|  | ||||
| 	run_hook single_prekillall | ||||
|  | ||||
| 	kill_all | ||||
|  | ||||
| 	run_hook single_postkillall | ||||
|  | ||||
| 	# Start/trigger udev, load MODULES, and settle udev | ||||
| 	udevd_modprobe single | ||||
| 	 | ||||
| 	# Removing leftover files | ||||
| 	remove_leftover | ||||
| fi | ||||
|  | ||||
| run_hook single_end | ||||
|  | ||||
| bootlogd_stop | ||||
|  | ||||
| if [[ $RUNLEVEL = 1 ]]; then | ||||
| 	printsep | ||||
| 	printhl "Entering single-user mode..." | ||||
| 	# make sure /dev/initctl is in place | ||||
| 	kill -HUP 1 | ||||
| 	exec init -t1 S | ||||
| fi | ||||
|  | ||||
| # End of file | ||||
| # vim: set ts=2 sw=2 noet: | ||||
							
								
								
									
										195
									
								
								scripts/rc.sysinit
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										195
									
								
								scripts/rc.sysinit
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,195 @@ | ||||
| #!/bin/bash | ||||
| # | ||||
| # /etc/rc.sysinit | ||||
| # | ||||
|  | ||||
| unset HOSTNAME | ||||
|  | ||||
| . /etc/rc.conf | ||||
| . /etc/rc.d/functions | ||||
|  | ||||
| LOCALE="$LANG" | ||||
| LANG=C LC_ALL=C | ||||
|  | ||||
| if [[ -z $HOSTNAME && -s /etc/hostname ]]; then | ||||
| 	HOSTNAME=$(< /etc/hostname) | ||||
| fi | ||||
|  | ||||
| # don't let all the systemd tools be too verbose | ||||
| export SYSTEMD_LOG_LEVEL="notice" | ||||
|  | ||||
| # Prints distro name and URL | ||||
| print_welcome | ||||
|  | ||||
| # mount the API filesystems | ||||
| # /proc, /sys, /run, /dev, /run/lock, /dev/pts, /dev/shm | ||||
| mountpoint -q /proc    || mount -t proc proc /proc -o nosuid,noexec,nodev | ||||
| mountpoint -q /sys     || mount -t sysfs sys /sys -o nosuid,noexec,nodev | ||||
| mountpoint -q /run     || mount -t tmpfs run /run -o mode=0755,nosuid,nodev | ||||
| mountpoint -q /dev     || mount -t devtmpfs dev /dev -o mode=0755,nosuid | ||||
| mkdir -p /dev/{pts,shm} | ||||
| mountpoint -q /dev/pts || mount /dev/pts &>/dev/null || mount -t devpts devpts /dev/pts -o mode=0620,gid=5,nosuid,noexec | ||||
| mountpoint -q /dev/shm || mount /dev/shm &>/dev/null || mount -t tmpfs shm /dev/shm -o mode=1777,nosuid,nodev | ||||
|  | ||||
| # log all console messages | ||||
| bootlogd -p /run/bootlogd.pid | ||||
|  | ||||
| run_hook sysinit_start | ||||
|  | ||||
| if [[ $HOSTNAME ]]; then | ||||
| 	stat_busy "Setting hostname: $HOSTNAME" | ||||
| 	echo "$HOSTNAME" >| /proc/sys/kernel/hostname && stat_done || stat_fail | ||||
| fi | ||||
|  | ||||
| HWCLOCK_PARAMS="--systz" | ||||
|  | ||||
| if [[ $HARDWARECLOCK ]]; then | ||||
|  | ||||
| 	[[ -f /etc/adjtime ]] && { read ; read ; read ADJTIME; } < /etc/adjtime | ||||
|  | ||||
| 	if [[ $ADJTIME == 'LOCAL' ]]; then | ||||
| 		if	[[ $HARDWARECLOCK == 'UTC' ]]; then | ||||
| 			printf "${C_FAIL}/etc/rc.conf says the RTC is in UTC, but /etc/adjtime says it is in localtime.\n${C_OTHER}." | ||||
| 		fi | ||||
| 	else | ||||
| 		if [[ $HARDWARECLOCK == 'LOCALTIME' ]]; then | ||||
| 			printf "${C_FAIL}/etc/rc.conf says the RTC is in localtime, but hwclock (/etc/adjtime) thinks it is in UTC.\n${C_OTHER}." | ||||
| 		fi | ||||
| 	fi | ||||
|  | ||||
| 	case $HARDWARECLOCK in | ||||
| 		UTC) HWCLOCK_PARAMS+=" --utc --noadjfile";; | ||||
| 		localtime) HWCLOCK_PARAMS+=" --localtime --noadjfile";; | ||||
| 		*) HWCLOCK_PARAMS="";; | ||||
| 	esac | ||||
| fi | ||||
|  | ||||
| if [[ $HWCLOCK_PARAMS ]]; then | ||||
| 	stat_busy "Adjusting system time and setting kernel time zone" | ||||
|  | ||||
| 	# Adjust the system time for time zone offset if rtc is not in UTC, as | ||||
| 	# filesystem checks can depend on system time. This also sets the kernel | ||||
| 	# time zone, used by e.g. vfat. | ||||
|  | ||||
| 	if [[ $TIMEZONE ]]; then | ||||
| 		export TZ=$TIMEZONE | ||||
| 	fi | ||||
|  | ||||
| 	hwclock $HWCLOCK_PARAMS && stat_done || stat_fail | ||||
|  | ||||
| 	unset TZ | ||||
| fi | ||||
|  | ||||
| # Start/trigger udev, load MODULES, and settle udev | ||||
| udevd_modprobe sysinit | ||||
|  | ||||
| # this must be done after udev has loaded the KMS modules | ||||
| #status 'Configuring virtual consoles' /usr/lib/systemd/systemd-vconsole-setup | ||||
| if [[ ${LOCALE,,} =~ utf || $LOCALE == C ]]; then | ||||
|         stat_busy "Setting Consoles to UTF-8 mode" | ||||
|                 # UTF-8 consoles are default since 2.6.24 kernel | ||||
|                 # this code is needed not only for older kernels, | ||||
|                 # but also when user has set vt.default_utf8=0 but LOCALE is *.UTF-8. | ||||
|                 for i in /dev/tty[0-9]*; do | ||||
|                         kbd_mode -u -C ${i} | ||||
|                         printf "\e%%G" > ${i} | ||||
|                 done | ||||
|                 echo 1 >| /sys/module/vt/parameters/default_utf8 | ||||
|         stat_done | ||||
| else | ||||
|         stat_busy "Setting Consoles to legacy mode" | ||||
|                 # make non-UTF-8 consoles work on 2.6.24 and newer kernels | ||||
|                 for i in /dev/tty[0-9]*; do | ||||
|                         kbd_mode -a -C ${i} | ||||
|                         printf "\e%%@" > ${i} | ||||
|                 done | ||||
|                 echo 0 >| /sys/module/vt/parameters/default_utf8 | ||||
|         stat_done | ||||
| fi | ||||
|  | ||||
| if [[ -z $CONSOLEFONT && -z $CONSOLEMAP && -s /etc/vconsole.conf ]]; then | ||||
|         parse_envfile /etc/vconsole.conf "${vconsolevars[@]}" | ||||
|         [[ $FONT ]] && CONSOLEFONT=$FONT | ||||
|         [[ $FONT_MAP ]] && CONSOLEMAP=$FONT_MAP | ||||
| fi | ||||
|  | ||||
| # Set console font and keymap if required | ||||
| [[ $CONSOLEFONT ]] && | ||||
|         status "Loading Console Font: $CONSOLEFONT" set_consolefont | ||||
| [[ $KEYMAP ]] && | ||||
|         status "Loading Keyboard Map: $KEYMAP" loadkeys -q $KEYMAP | ||||
|  | ||||
| # bring up the loopback interface | ||||
| [[ -d /sys/class/net/lo ]] && | ||||
| 	status "Bringing up loopback interface" ip link set up dev lo | ||||
|  | ||||
| # FakeRAID devices detection | ||||
| [[ $USEDMRAID = [Yy][Ee][Ss] && -x $(type -P dmraid) ]] && | ||||
| 	status "Activating FakeRAID arrays" dmraid -i -ay | ||||
|  | ||||
| # Activate LVM2 groups, if any | ||||
| activate_vgs | ||||
|  | ||||
| # Set up non-root encrypted partition mappings | ||||
| if [[ -f /etc/crypttab ]] && type -p cryptsetup >/dev/null; then | ||||
| 	read_crypttab do_unlock | ||||
| 	# Maybe someone has LVM on an encrypted block device | ||||
| 	activate_vgs | ||||
| fi | ||||
|  | ||||
| # Check filesystems | ||||
| run_hook sysinit_prefsck | ||||
| if [[ -x $(type -P fsck) ]]; then | ||||
| 	stat_busy "Checking filesystems" | ||||
| 		fsck_all >|"${FSCK_OUT:-/dev/stdout}" 2>|"${FSCK_ERR:-/dev/stdout}" | ||||
| 	declare -r fsckret=$? | ||||
| 	(( fsckret <= 1 )) && stat_done || stat_fail | ||||
| else | ||||
| 	declare -r fsckret=0 | ||||
| fi | ||||
| run_hook sysinit_postfsck | ||||
|  | ||||
| # Single-user login and/or automatic reboot if needed | ||||
| fsck_reboot $fsckret | ||||
|  | ||||
| #status "Remounting root and API filesystems" \ | ||||
| #	/usr/lib/systemd/systemd-remount-fs | ||||
| status "Remounting Root" \ | ||||
|        mount -o remount / | ||||
|  | ||||
| # Now mount all the local filesystems | ||||
| run_hook sysinit_premount | ||||
| status "Mounting local filesystems" \ | ||||
| 	mount_all | ||||
| run_hook sysinit_postmount | ||||
|  | ||||
| # Enable monitoring of LVM2 groups, now that the filesystems are mounted rw | ||||
| [[ $USELVM = [Yy][Ee][Ss] && -x $(type -P lvm) && -d /sys/block ]] && | ||||
| 	status "Activating monitoring of LVM2 groups" \ | ||||
| 		vgchange --monitor y >/dev/null | ||||
|  | ||||
| status "Activating swap" swapon -a | ||||
|  | ||||
| [[ $TIMEZONE ]] && status "Configuring time zone" set_timezone "$TIMEZONE" | ||||
|  | ||||
| #status 'Initializing random seed' /usr/lib/systemd/systemd-random-seed load | ||||
| [[ -f $RANDOM_SEED ]] && | ||||
|         status "Initializing Random Seed" \ | ||||
|                 cp $RANDOM_SEED /dev/urandom | ||||
|  | ||||
| # Remove leftover files | ||||
| remove_leftover | ||||
|  | ||||
| stat_busy "Saving dmesg log" | ||||
| 	if [[ -e /proc/sys/kernel/dmesg_restrict ]] && | ||||
| 		(( $(< /proc/sys/kernel/dmesg_restrict) == 1 )); then | ||||
| 		install -Tm 0600 <( dmesg ) /var/log/dmesg.log | ||||
| 	else | ||||
| 		install -Tm 0644 <( dmesg ) /var/log/dmesg.log | ||||
| 	fi | ||||
| (( $? == 0 )) && stat_done || stat_fail | ||||
|  | ||||
| run_hook sysinit_end | ||||
|  | ||||
| # End of file | ||||
| # vim: set ts=2 sw=2 noet: | ||||
		Reference in New Issue
	
	Block a user