Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 11 Jun 2014 11:25:13 +0400 (MSK)
From:      Maxim Konovalov <maxim.konovalov@gmail.com>
To:        Devin Teske <dteske@FreeBSD.org>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org, KOT@MATPOCKuH.Ru
Subject:   Re: svn commit: r264243 - in head/etc: . rc.d
Message-ID:  <alpine.BSF.2.00.1406111122060.80618@mp2.macomnet.net>
In-Reply-To: <201404072240.s37MeTqo085123@svn.freebsd.org>
References:  <201404072240.s37MeTqo085123@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
Hi Davin,

It looks like this change has some issues with the aliases startup
configuration, see the following report for more details:

https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=190880

Would you mind if I assign this ticket to you?

On Mon, 7 Apr 2014, 22:40-0000, Devin Teske wrote:

> Author: dteske
> Date: Mon Apr  7 22:40:29 2014
> New Revision: 264243
> URL: http://svnweb.freebsd.org/changeset/base/264243
>
> Log:
>   Loosen the processing of *_IF_aliasN vars to be less strict. Previously,
>   the first alias had to be _alias0 and processing stopped at the first non-
>   defined variable (preventing gaps). Allowing gaps gives the administrator
>   the ability to group aliases in an adhoc manner and also lifts the
>   requirement to renumber aliases simply to comment-out an existing one.
>   Aliases are processed in numerical ascending order.
>
>   Discussed on:	-rc
>   MFC after:	1 week
>
> Modified:
>   head/etc/network.subr
>   head/etc/rc.d/mdconfig
>   head/etc/rc.d/mdconfig2
>   head/etc/rc.subr
>
> Modified: head/etc/network.subr
> ==============================================================================
> --- head/etc/network.subr	Mon Apr  7 22:37:13 2014	(r264242)
> +++ head/etc/network.subr	Mon Apr  7 22:40:29 2014	(r264243)
> @@ -283,10 +283,8 @@ get_if_var()
>  	fi
>
>  	_if=$1
> -	_punct=". - / +"
> -	for _punct_c in $_punct; do
> -		_if=`ltr ${_if} ${_punct_c} '_'`
> -	done
> +	_punct=".-/+"
> +	ltr ${_if} "${_punct}" '_' _if
>  	_var=$2
>  	_default=$3
>
> @@ -1076,6 +1074,7 @@ ifalias_af_common_handler()
>  ifalias_af_common()
>  {
>  	local _ret _if _af _action alias ifconfig_args _aliasn _c _tmpargs _iaf
> +	local _punct=".-/+"
>
>  	_ret=1
>  	_aliasn=
> @@ -1083,10 +1082,14 @@ ifalias_af_common()
>  	_af=$2
>  	_action=$3
>
> +	# Normalize $_if before using it in a pattern to list_vars()
> +	ltr "$_if" "$_punct" "_" _if
> +
>  	# ifconfig_IF_aliasN which starts with $_af
> -	alias=0
> -	while : ; do
> -		ifconfig_args=`get_if_var $_if ifconfig_IF_alias${alias}`
> +	for alias in `list_vars ifconfig_${_if}_alias[0-9]\* |
> +		sort_lite -nk1.$((9+${#_if}+7))`
> +	do
> +		eval ifconfig_args=\"\$$alias\"
>  		_iaf=
>  		case $ifconfig_args in
>  		inet\ *)	_iaf=inet ;;
> @@ -1107,15 +1110,15 @@ ifalias_af_common()
>  			warn "\$ifconfig_${_if}_alias${alias} needs " \
>  			    "\"inet\" keyword for an IPv4 address."
>  		esac
> -		alias=$(($alias + 1))
>  	done
>
>  	# backward compatibility: ipv6_ifconfig_IF_aliasN.
>  	case $_af in
>  	inet6)
> -		alias=0
> -		while : ; do
> -			ifconfig_args=`get_if_var $_if ipv6_ifconfig_IF_alias${alias}`
> +		for alias in `list_vars ipv6_ifconfig_${_if}_alias[0-9]\* |
> +			sort_lite -nk1.$((14+${#_if}+7))`
> +		do
> +			eval ifconfig_args=\"\$$alias\"
>  			case ${_action}:"${ifconfig_args}" in
>  			*:"")
>  				break
> @@ -1127,7 +1130,6 @@ ifalias_af_common()
>  				    "instead."
>  			;;
>  			esac
> -			alias=$(($alias + 1))
>  		done
>  	esac
>
>
> Modified: head/etc/rc.d/mdconfig
> ==============================================================================
> --- head/etc/rc.d/mdconfig	Mon Apr  7 22:37:13 2014	(r264242)
> +++ head/etc/rc.d/mdconfig	Mon Apr  7 22:40:29 2014	(r264243)
> @@ -181,17 +181,14 @@ fi
>
>  load_rc_config $name
>
> -_mdconfig_unit=0
>  if [ -z "${_mdconfig_list}" ]; then
> -	while :; do
> -		eval _mdconfig_config=\$mdconfig_md${_mdconfig_unit}
> -		if [ -z "${_mdconfig_config}" ]; then
> -			break
> -		else
> -			_mdconfig_list="${_mdconfig_list}${_mdconfig_list:+ }md${_mdconfig_unit}"
> -			_mdconfig_unit=$((${_mdconfig_unit} + 1))
> -		fi
> +	for _mdconfig_config in `list_vars mdconfig_md[0-9]\* |
> +		sort_lite -nk1.12`
> +	do
> +		_mdconfig_unit=${_mdconfig_config#mdconfig_md}
> +		_mdconfig_list="$_mdconfig_list md$_mdconfig_unit"
>  	done
> +	_mdconfig_list="${_mdconfig_list# }"
>  fi
>
>  run_rc_command "${_mdconfig_cmd}"
>
> Modified: head/etc/rc.d/mdconfig2
> ==============================================================================
> --- head/etc/rc.d/mdconfig2	Mon Apr  7 22:37:13 2014	(r264242)
> +++ head/etc/rc.d/mdconfig2	Mon Apr  7 22:40:29 2014	(r264243)
> @@ -211,17 +211,14 @@ fi
>
>  load_rc_config $name
>
> -_mdconfig2_unit=0
>  if [ -z "${_mdconfig2_list}" ]; then
> -	while :; do
> -		eval _mdconfig2_config=\$mdconfig_md${_mdconfig2_unit}
> -		if [ -z "${_mdconfig2_config}" ]; then
> -			break
> -		else
> -			_mdconfig2_list="${_mdconfig2_list}${_mdconfig2_list:+ }md${_mdconfig2_unit}"
> -			_mdconfig2_unit=$((${_mdconfig2_unit} + 1))
> -		fi
> +	for _mdconfig2_config in `list_vars mdconfig_md[0-9]\* |
> +		sort_lite -nk1.12`
> +	do
> +		_mdconfig2_unit=${_mdconfig2_config#mdconfig_md}
> +		_mdconfig2_list="$_mdconfig2_list md$_mdconfig2_unit"
>  	done
> +	_mdconfig2_list="${_mdconfig2_list# }"
>  fi
>
>  run_rc_command "${_mdconfig2_cmd}"
>
> Modified: head/etc/rc.subr
> ==============================================================================
> --- head/etc/rc.subr	Mon Apr  7 22:37:13 2014	(r264242)
> +++ head/etc/rc.subr	Mon Apr  7 22:40:29 2014	(r264243)
> @@ -54,6 +54,20 @@ JID=`$PS -p $$ -o jid=`
>  #	functions
>  #	---------
>
> +# list_vars pattern
> +#	List vars matching pattern.
> +#
> +list_vars()
> +{
> +	set | { while read LINE; do
> +		var="${LINE%%=*}"
> +		case "$var" in
> +		"$LINE"|*[!a-zA-Z0-9_]*) continue ;;
> +		$1) echo $var
> +		esac
> +	done; }
> +}
> +
>  # set_rcvar_obsolete oldvar [newvar] [msg]
>  #	Define obsolete variable.
>  #	Global variable $rcvars_obsolete is used.
> @@ -314,6 +328,246 @@ _find_processes()
>  	eval $_proccheck
>  }
>
> +# sort_lite [-b] [-n] [-k POS] [-t SEP]
> +#	A lite version of sort(1) (supporting a few options) that can be used
> +#	before the real sort(1) is available (e.g., in scripts that run prior
> +#	to mountcritremote). Requires only shell built-in functionality.
> +#
> +sort_lite()
> +{
> +	local funcname=sort_lite
> +	local sort_sep="$IFS" sort_ignore_leading_space=
> +	local sort_field=0 sort_strict_fields= sort_numeric=
> +	local nitems=0 skip_leading=0 trim=
> +
> +	local OPTIND flag
> +	while getopts bnk:t: flag; do
> +		case "$flag" in
> +		b) sort_ignore_leading_space=1 ;;
> +		n) sort_numeric=1 sort_ignore_leading_space=1 ;;
> +		k) sort_field="${OPTARG%%,*}" ;; # only up to first comma
> +			# NB: Unlike sort(1) only one POS allowed
> +		t) sort_sep="$OPTARG"
> +		   if [ ${#sort_sep} -gt 1 ]; then
> +		   	echo "$funcname: multi-character tab \`$sort_sep'" >&2
> +		   	return 1
> +		   fi
> +		   sort_strict_fields=1
> +		   ;;
> +		\?) return 1 ;;
> +		esac
> +	done
> +	shift $(( $OPTIND - 1 ))
> +
> +	# Create transformation pattern to trim leading text if desired
> +	case "$sort_field" in
> +	""|[!0-9]*|*[!0-9.]*)
> +		echo "$funcname: invalid sort field \`$sort_field'" >&2
> +		return 1
> +		;;
> +	*.*)
> +		skip_leading=${sort_field#*.} sort_field=${sort_field%%.*}
> +		while [ ${skip_leading:-0} -gt 1 ] 2> /dev/null; do
> +			trim="$trim?" skip_leading=$(( $skip_leading - 1 ))
> +		done
> +	esac
> +
> +	# Copy input to series of local numbered variables
> +	# NB: IFS of NULL preserves leading whitespace
> +	local LINE
> +	while IFS= read -r LINE || [ "$LINE" ]; do
> +		nitems=$(( $nitems + 1 ))
> +		local src_$nitems="$LINE"
> +	done
> +
> +	#
> +	# Sort numbered locals using insertion sort
> +	#
> +	local curitem curitem_orig curitem_mod curitem_haskey
> +	local dest dest_orig dest_mod dest_haskey
> +	local d gt n
> +	local i=1
> +	while [ $i -le $nitems ]; do
> +		curitem_haskey=1 # Assume sort field (-k POS) exists
> +		eval curitem=\"\$src_$i\"
> +		curitem_mod="$curitem" # for modified comparison
> +		curitem_orig="$curitem" # for original comparison
> +
> +		# Trim leading whitespace if desired
> +		if [ "$sort_ignore_leading_space" ]; then
> +			while case "$curitem_orig" in
> +				[$IFS]*) : ;; *) false; esac
> +			do
> +				curitem_orig="${curitem_orig#?}"
> +			done
> +			curitem_mod="$curitem_orig"
> +		fi
> +
> +		# Shift modified comparison value if sort field (-k POS) is > 1
> +		n=$sort_field
> +		while [ $n -gt 1 ]; do
> +			case "$curitem_mod" in
> +			*[$sort_sep]*)
> +				# Cut text up-to (and incl.) first separator
> +				curitem_mod="${curitem_mod#*[$sort_sep]}"
> +
> +				# Skip NULLs unless strict field splitting
> +				[ "$sort_strict_fields" ] ||
> +					[ "${curitem_mod%%[$sort_sep]*}" ] ||
> +					[ $n -eq 2 ] ||
> +					continue
> +				;;
> +			*)
> +				# Asked for a field that doesn't exist
> +				curitem_haskey= break
> +			esac
> +			n=$(( $n - 1 ))
> +		done
> +
> +		# Trim trailing words if sort field >= 1
> +		[ $sort_field -ge 1 -a "$sort_numeric" ] &&
> +			curitem_mod="${curitem_mod%%[$sort_sep]*}"
> +
> +		# Apply optional trim (-k POS.TRIM) to cut leading characters
> +		curitem_mod="${curitem_mod#$trim}"
> +
> +		# Determine the type of modified comparison to use initially
> +		# NB: Prefer numerical if requested but fallback to standard
> +		case "$curitem_mod" in
> +		""|[!0-9]*) # NULL or begins with non-number
> +			gt=">"
> +			[ "$sort_numeric" ] && curitem_mod=0
> +			;;
> +		*)
> +			if [ "$sort_numeric" ]; then
> +				gt="-gt"
> +				curitem_mod="${curitem_mod%%[!0-9]*}"
> +					# NB: trailing non-digits removed
> +					# otherwise numeric comparison fails
> +			else
> +				gt=">"
> +			fi
> +		esac
> +
> +		# If first time through, short-circuit below position-search
> +		if [ $i -le 1 ]; then
> +			d=0
> +		else
> +			d=1
> +		fi
> +
> +		#
> +		# Find appropriate element position
> +		#
> +		while [ $d -gt 0 ]
> +		do
> +			dest_haskey=$curitem_haskey
> +			eval dest=\"\$dest_$d\"
> +			dest_mod="$dest" # for modified comparison
> +			dest_orig="$dest" # for original comparison
> +
> +			# Trim leading whitespace if desired
> +			if [ "$sort_ignore_leading_space" ]; then
> +				while case "$dest_orig" in
> +					[$IFS]*) : ;; *) false; esac
> +				do
> +					dest_orig="${dest_orig#?}"
> +				done
> +				dest_mod="$dest_orig"
> +			fi
> +
> +			# Shift modified value if sort field (-k POS) is > 1
> +			n=$sort_field
> +			while [ $n -gt 1 ]; do
> +				case "$dest_mod" in
> +				*[$sort_sep]*)
> +					# Cut text up-to (and incl.) 1st sep
> +					dest_mod="${dest_mod#*[$sort_sep]}"
> +
> +					# Skip NULLs unless strict fields
> +					[ "$sort_strict_fields" ] ||
> +					    [ "${dest_mod%%[$sort_sep]*}" ] ||
> +					    [ $n -eq 2 ] ||
> +					    continue
> +					;;
> +				*)
> +					# Asked for a field that doesn't exist
> +					dest_haskey= break
> +				esac
> +				n=$(( $n - 1 ))
> +			done
> +
> +			# Trim trailing words if sort field >= 1
> +			[ $sort_field -ge 1 -a "$sort_numeric" ] &&
> +				dest_mod="${dest_mod%%[$sort_sep]*}"
> +
> +			# Apply optional trim (-k POS.TRIM), cut leading chars
> +			dest_mod="${dest_mod#$trim}"
> +
> +			# Determine type of modified comparison to use
> +			# NB: Prefer numerical if requested, fallback to std
> +			case "$dest_mod" in
> +			""|[!0-9]*) # NULL or begins with non-number
> +				gt=">"
> +				[ "$sort_numeric" ] && dest_mod=0
> +				;;
> +			*)
> +				if [ "$sort_numeric" ]; then
> +					gt="-gt"
> +					dest_mod="${dest_mod%%[!0-9]*}"
> +						# NB: kill trailing non-digits
> +						# for numeric comparison safety
> +				else
> +					gt=">"
> +				fi
> +			esac
> +
> +			# Break if we've found the proper element position
> +			if [ "$curitem_haskey" -a "$dest_haskey" ]; then
> +				if [ "$dest_mod" = "$curitem_mod" ]; then
> +					[ "$dest_orig" ">" "$curitem_orig" ] &&
> +						break
> +				elif [ "$dest_mod" $gt "$curitem_mod" ] \
> +					2> /dev/null
> +				then
> +					break
> +				fi
> +			else
> +				[ "$dest_orig" ">" "$curitem_orig" ] && break
> +			fi
> +
> +			# Break if we've hit the end
> +			[ $d -ge $i ] && break
> +
> +			d=$(( $d + 1 ))
> +		done
> +
> +		# Shift remaining positions forward, making room for new item
> +		n=$i
> +		while [ $n -ge $d ]; do
> +			# Shift destination item forward one placement
> +			eval dest_$(( $n + 1 ))=\"\$dest_$n\"
> +			n=$(( $n - 1 ))
> +		done
> +
> +		# Place the element
> +		if [ $i -eq 1 ]; then
> +			local dest_1="$curitem"
> +		else
> +			local dest_$d="$curitem"
> +		fi
> +
> +		i=$(( $i + 1 ))
> +	done
> +
> +	# Print sorted results
> +	d=1
> +	while [ $d -le $nitems ]; do
> +		eval echo \"\$dest_$d\"
> +		d=$(( $d + 1 ))
> +	done
> +}
> +
>  #
>  # wait_for_pids pid [pid ...]
>  #	spins until none of the pids exist
> @@ -1524,19 +1778,20 @@ load_kld()
>  	return 0
>  }
>
> -# ltr str src dst
> +# ltr str src dst [var]
>  #	Change every $src in $str to $dst.
>  #	Useful when /usr is not yet mounted and we cannot use tr(1), sed(1) nor
> -#	awk(1).
> +#	awk(1). If var is non-NULL, set it to the result.
>  ltr()
>  {
> -	local _str _src _dst _out _com
> -	_str=$1
> -	_src=$2
> -	_dst=$3
> +	local _str _src _dst _out _com _var
> +	_str="$1"
> +	_src="$2"
> +	_dst="$3"
> +	_var="$4"
>  	_out=""
>
> -	IFS=${_src}
> +	local IFS="${_src}"
>  	for _com in ${_str}; do
>  		if [ -z "${_out}" ]; then
>  			_out="${_com}"
> @@ -1544,7 +1799,11 @@ ltr()
>  			_out="${_out}${_dst}${_com}"
>  		fi
>  	done
> -	echo "${_out}"
> +	if [ -n "${_var}" ]; then
> +		setvar "${_var}" "${_out}"
> +	else
> +		echo "${_out}"
> +	fi
>  }
>
>  # Creates a list of providers for GELI encryption.
>

-- 
Maxim Konovalov



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?alpine.BSF.2.00.1406111122060.80618>