Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Nov 2013 13:54:03 -0500
From:      John Baldwin <jhb@freebsd.org>
To:        Hiroki Sato <hrs@freebsd.org>
Cc:        clutton@zoho.com, freebsd-wireless@freebsd.org, freebsd-arch@freebsd.org
Subject:   Re: service netif restart [iface] runs a wpa_supplicant twice
Message-ID:  <201311121354.03923.jhb@freebsd.org>
In-Reply-To: <20131112.134742.1669584178551946391.hrs@allbsd.org>
References:  <1383419596.3253.42.camel@eva02.mbsd> <201311051154.18872.jhb@freebsd.org> <20131112.134742.1669584178551946391.hrs@allbsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Monday, November 11, 2013 11:47:42 pm Hiroki Sato wrote:
> John Baldwin <jhb@freebsd.org> wrote
>   in <201311051154.18872.jhb@freebsd.org>:
> 
> jh> I also tested vlans created via vlans_<if> and they should use the same fix as
> jh> well.  Note that this model is more consistent with how cloned_interfaces
> jh> works where ifn_start is not explicitly run when each interface is created.
> jh> Instead, we rely on devd kicking off pccard_ether for those as well.
> 
>  No, for cloned_interfaces, the ifn_start will be kicked even when
>  devd is unavailable because rc.d/netif calls clone_up() and then
>  ifn_start() sequentially.  Since an IFNET ATTACH event is generated
>  upon clone_up(), so actually the ifn_start() runs twice on every boot
>  time (or rc.d/netif restart ifn).

Yes, I missed this earlier.

>  Since childif_*() is invoked at the end of ifn_*(), configuration of
>  the child interfaces does not happen.  This is the reason why there
>  was ifn_start() in childif_create().

Well, the child interfaces are not listed in list_network_interfaces.
That explicitly adds cloned_interfaces to the list.

>  It is not efficient and it is reasonable to leave ifn_start() to devd
>  if available, but it is difficult to detect it correctly because the
>  IFNET ATTACH handler may be disabled in devd.conf.  "pgrep devd" is
>  not reliable enough.

Agreed that it is not perfect, and I don't really like it.  However, I
assumed that people who leave devd enabled but disable the IFNET ATTACH
handler must already know enough about what they are doing to fix this
on their own. :)  I think there are two common use cases that we should
make work out of the box:

1) People who use devd with a stock devd.conf.

2) People who don't use devd at all.

I'm not sure we need to support the case of people hacking up a custom
devd.conf directly in the base system.

>  As pointed out, this duplication can be a problem when configuration
>  is performed by a program because multiple instances of the program
>  are invoked.  In the other cases, there is no problem because
>  ifn_start() is idempotent, though.

Yes.  One thought I had was to just fix /etc/rc.d/wpa_supplicant so that
it was idempotent.  If wpa_supplicant is the only one that really needs
fixing I would favor that fix as the simplest one.

>  For inconsistency childif_*(), what do you think about integrating
>  vlans_IF and wlans_IF into cloned_interfaces and removing the
>  childif_*() stage in ifn_*()?  We can keep vlans_IF and wlans_IF as
>  well as introduce a new syntax into cloned_interfaces like
> 
>   cloned_interfaces="em0.100 em0.110 em0.myvlan ath0.wlan0"
> 
>  which is equivalent to
> 
>   vlans_em0="100 110 myvlan"
>   wlans_ath0="wlan0"
> 
>  The rc.d/netif does clone_up() for the child interfaces first and
>  then does ifn_start() for them, so
> 
>  # service netif restart wlan0
> 
>  works as expected (tear down, recreate, and reconfigure the
>  interface).

cloned_interfaces already supports vlans (em0.100, etc.).  The problems
I had when we used that were:

1) if_vlan was not implicitly loaded, so we always cloned a vlan999 dummy
   device to load it

2) If we stopped an interface (typically on kldunload of the base driver),
   the vlan interfaces were orphaned.  They stayed around, but with no
   parent.  If a newer version of the driver was loaded via kldload, the
   vlan interfaces were not recreated.  With vlans_IF, the right thing
   happens if you do 'stop foo0' and 'start foo0'.  In particular if you
   do a 'stop foo0' before you kldunload foo, then all of foo0's
   subinterfaces are created and configured when you kldload foo.

>  Of course, this does not solve the duplicate invocation of the netif
>  script.  To solve it, I think we need a knob to disable IFNET events
>  in a per-interface basis temporarily.

Eh, I thought about doing some hackish thing to do that, but it seemed
even more fragile and gross than the 'pgrep devd' hack.  In particular,
you could do this in /etc/rc.d/devd:

devd_precmd()
{
	touch /tmp/disable_netif
}

devd_postcmd()
{
	rm /tmp/disable_netif
}

rc.conf:
devd_flags="-n"

And have /etc/pccard_ether bail if /tmp/disable_netif exists.  This would
let devd drain through all the queued up events at boot ignoring any
IFNET ATTACH events by having pccard_ether bail.

-- 
John Baldwin



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