On Thu, Dec 15, 2022 at 07:06:34PM -0800, Andrew Hewus Fresh wrote: > On Thu, Dec 15, 2022 at 06:31:40AM +0000, Klemens Nanni wrote: > > More context for this diff: > > 138 if [[ $_if == ??:??:??:??:??:?? ]]; then > > 139 if ! _line=$( ifconfig -M $_if ); then > > 140 print -u2 "${0##*/}: $_if is not unique." > > 141 return > > 142 fi > > > > > @@ -144,11 +144,14 @@ ifstart() { > > > [[ -z $_line ]] && return > > > > _line is the interface name "em0", please call it _ifname or _if_name. > > Just anything obviously descriptive. > > Will do. I ended up just adding _lladdr and moving things around > appropriately. I think it worked out very well.
This reads fine, _if is the name/unit style string and _lladdr the MAC. > > > > > _if=$_line > > > _line= > > > > So the MAC in _if is overwritten with the interface name in _line which > > is being zeroed, i.e. we looked up the interface via lladdr and proceed > > as if the user had placed an .em0 file instead. > > > > With s/_inline/_ifname/ that would be much easier to follow. > > > > > - > > > - if [[ -e /etc/hostname.$_if ]]; then > > > - print -u2 "${0##*/}: $_hn: /etc/hostname.$_if overrides" > > > + else > > > + _line=$(ifconfig $_if | sed -n > > > 's/^[[:space:]]*lladdr[[:space:]]//p') > > > > This will print "_if: no such interface" for nonexistent interfaces and > > must be silenced. > > Ahh, yes. fixed. > > > > > > + if [[ -n $_line && -n $(ifconfig -M $_line) \ > > > > Pretty sure the -M call needs "$_line" since you can hit existent > > interfaces without lladdr, so _line is empty and `ifconfig -M' would > > print usage while `ifconfig -M ""' is silent as expected. > > Wouldn't $_line be blank then and this would short-circuit at "-n $line" > instead of trying to run ifconfig -M with no arguments? Oh of course, in that case the quotes don't matter. They aren't needed but also don't here, your call. > > $ x=; [[ -n $x && -n $( print -u2 $x!; ifconfig -M $x ) ]] && echo oops > $ > > I will wrap it in quotes to be less surprising. > > > > > > + && -e /etc/hostname.$_line ]]; then > > > > The same sanity check further below uses -f. Not sure if existence is > > enough here or whether we should only switch files if there is an actual > > file... > > We should be consistent in ignoring things that aren't files. Fine with me. > > > > > > > + print -u2 "${0##*/}: $_hn: /etc/hostname.$_line: > > > overrides" > > > return > > > fi > > > + _line= > > > fi > > > > Otherwise the else block logic makes sense, but now you're using _if as > > an interface name before the input validation, which follows immediately > > afterwards. > > > > Just merge the two like this: > > if [[ $_if == ??:??:??:??:??:?? ]]; then > > ... > > else if [[ $_if == +([[:alpha:]])+([[:digit:]]) ]]; then > > ... > > else > > return > > > > Diff below to make things clear. > > Maybe it'd be better to clean up things a bit and then do the prio swap > > separately? > > I tried just adding a variable and doing a bit of tidying first, but it > didn't seem worthwhile. > > After seeing your suggestion to combine the logic into an elif, a > lightbulb went on and I reversed the order of the checks so the more > common (name/unit) would be handled first. Overall I think it feels > much nicer. Thanks! > > I used many of your suggestions, but I kept sed instead of switching to > awk to keep that the same with install.sub. It is still in a helper > function in install.sub, since I believe we are going to reuse that > logic later when we allow that answer to the question in the installer. Staying in sync with the installer makes sense, I used awk because it reads much clearer (simpler to hack down in a show-case diffe like this). > > I also added the alpha+digit check in install.sub for consistency. > > > > If that looks right, we can adapt the insaller bits accordingly. > > I did not go over them now. > > Here's the full diff, including the man page rebased onto jmc@'s rework. OK kn functionality wise, but I'd appreaciate sticking to our usual ksh style, see inline. No need to resend the diff with those nits fixed. > > > Index: etc/netstart > =================================================================== > RCS file: /cvs/src/etc/netstart,v > retrieving revision 1.230 > diff -u -p -r1.230 netstart > --- etc/netstart 5 Dec 2022 20:12:00 -0000 1.230 > +++ etc/netstart 16 Dec 2022 02:54:28 -0000 > @@ -132,28 +132,35 @@ vifscreate() { > # Start a single interface. > # Usage: ifstart if1 > ifstart() { > - local _if=$1 _hn=/etc/hostname.$1 _cmds _i=0 _line _stat > + local _if=$1 _lladdr _hn=/etc/hostname.$1 _cmds _i=0 _line _stat > set -A _cmds > > - if [[ $_if == ??:??:??:??:??:?? ]]; then > - if ! _line=$( ifconfig -M $_if ); then > - print -u2 "${0##*/}: $_if is not unique." > + # Interface names must be alphanumeric only. We check to avoid > + # configuring backup or temp files, and to catch the "*" case. > + if [[ $_if = +([[:alpha:]])+([[:digit:]]) ]]; then Please use == for comparison. > + _lladdr=$(ifconfig $_if 2>/dev/null | > + sed -n 's/^[[:space:]]*lladdr[[:space:]]//p') > + if [[ -n $_lladdr \ > + && -f /etc/hostname.$_lladdr \ > + && -n $(ifconfig -M "$_lladdr") \ Yes, -n/-f now align nicely, but line breaks look ugly and we have the logic operator at the end everywhere (C and sh code), so I really prefer if [[ -n $_lladdr && -n f /etc/hostname.$_lladdr && -n $(ifconfig -M $_lladdr) ]]; then or if [[ -n $_lladdr && -n f /etc/hostname.$_lladdr && -n $(ifconfig -M $_lladdr) ]]; then > + ]]; then > + print -u2 "${0##*/}: $_hn: /etc/hostname.$_lladdr > overrides" > return > fi > > - [[ -z $_line ]] && return > - _if=$_line > - _line= > - > - if [[ -e /etc/hostname.$_if ]]; then > - print -u2 "${0##*/}: $_hn: /etc/hostname.$_if overrides" > + # We also support hostname.lladdr, but it must resolve to be valid > + elif [[ $_if == ??:??:??:??:??:?? ]]; then > + _lladdr=$_if > + _if=$(ifconfig -M $_lladdr) > + if (($? != 0)); then > + print -u2 "${0##*/}: $_lladdr is not unique." > return > fi > - fi > > - # Interface names must be alphanumeric only. We check to avoid > - # configuring backup or temp files, and to catch the "*" case. > - [[ $_if != +([[:alpha:]])+([[:digit:]]) ]] && return > + [[ -z $_if ]] && return > + else > + return > + fi > > if [[ ! -f $_hn ]]; then > print -u2 "${0##*/}: $_hn: No such file or directory." > Index: distrib/miniroot/install.sub > =================================================================== > RCS file: /cvs/src/distrib/miniroot/install.sub,v > retrieving revision 1.1215 > diff -u -p -r1.1215 install.sub > --- distrib/miniroot/install.sub 5 Dec 2022 20:12:00 -0000 1.1215 > +++ distrib/miniroot/install.sub 16 Dec 2022 02:54:28 -0000 > @@ -356,6 +356,15 @@ get_ifs() { > done > } > > +# Maps an interface name to lladdr, > > +# filtered by whether it's valid for use by ifconfig -M Comments usually go in imperative tense. You could also say what ifconfig -M does so this becomes clearer and simpler, e.g. # Map an interface to its MAC address if it is unique. > +if_name_to_lladdr() { > + local _lladdr Please add an empty line here. > + _lladdr=$(ifconfig $1 2>/dev/null | > + sed -n 's/^[[:space:]]*lladdr[[:space:]]//p') > + [[ -n $_lladdr && -n $(ifconfig -M "$_lladdr") ]] && echo $_lladdr > +} > > + > # Return the device name of the disk device $1, which may be a disklabel UID. > get_dkdev_name() { > local _dev=${1#/dev/} _d > @@ -2428,13 +2437,18 @@ parse_hn_line() { > # Start interface using the on-disk hostname.if file passed as argument $1. > # Much of this is gratuitously stolen from /etc/netstart. > ifstart() { > - local _if=$1 _hn=/mnt/etc/hostname.$1 _cmds _i=0 _line > + local _if=$1 _lladdr _hn=/mnt/etc/hostname.$1 _cmds _i=0 _line > set -A _cmds > > - if [[ $_if == ??:??:??:??:??:?? ]]; then > - _if=$(ifconfig -M $_if) > - [[ -z $_if ]] && return # invalid interface > - [[ -e /mnt/etc/hostname.$_if ]] && return # duplicate config > + if [[ $_if = +([[:alpha:]])+([[:digit:]]) ]]; then Please use == for comparsion. > + _lladdr=$(if_name_to_lladdr $_if) > + [[ -n $_lladdr && -f /mnt/etc/hostname.$_lladdr ]] && return > + elif [[ $_if == ??:??:??:??:??:?? ]]; then > + _lladdr=$_if > + _if=$(ifconfig -M $_lladdr) > + [[ -z $_if ]] && return > + else > + return > fi > > # Create interface if it does not yet exist. > Index: share/man/man5/hostname.if.5 > =================================================================== > RCS file: /cvs/src/share/man/man5/hostname.if.5,v > retrieving revision 1.81 > diff -u -p -r1.81 hostname.if.5 > --- share/man/man5/hostname.if.5 15 Dec 2022 06:39:05 -0000 1.81 > +++ share/man/man5/hostname.if.5 16 Dec 2022 02:54:28 -0000 > @@ -49,7 +49,7 @@ so interfaces can alternatively be refer > their link layer address (lladdr), > such as > .Dq hostname.00:00:5e:00:53:af . > -Priority is given to configuration by interface name/unit over lladdr. > +Priority is given to configuration by interface lladdr over name/unit. > A configuration file is not needed for lo0. > .Pp > The configuration information is expressed in a line-by-line packed format >