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>