Date: Thu, 13 Aug 2009 02:35:42 +0200 From: Marko Zec <zec@freebsd.org> To: Julian Elischer <julian@elischer.org> Cc: Perforce Change Reviews <perforce@freebsd.org>, Robert Watson <rwatson@freebsd.org> Subject: Re: PERFORCE change 167260 for review Message-ID: <200908130235.43161.zec@freebsd.org> In-Reply-To: <4A835CBE.4060903@elischer.org> References: <200908122108.n7CL8uhJ058398@repoman.freebsd.org> <200908130052.11423.zec@freebsd.org> <4A835CBE.4060903@elischer.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Thursday 13 August 2009 02:22:22 Julian Elischer wrote: > Marko Zec wrote: > > On Thursday 13 August 2009 00:44:49 Julian Elischer wrote: > >> Marko Zec wrote: > >>> On Wednesday 12 August 2009 23:58:46 Julian Elischer wrote: > >>>> Marko Zec wrote: > >>> > >>> ... > >>> > >>>>> @@ -710,22 +715,36 @@ > >>>>> .pr_input = div_input, > >>>>> .pr_ctlinput = div_ctlinput, > >>>>> .pr_ctloutput = ip_ctloutput, > >>>>> - .pr_init = NULL, > >>>>> + .pr_init = div_init, > >>>>> .pr_usrreqs = &div_usrreqs > >>>> > >>>> If you are going to make pr_init() called for every vnet then > >>>> pr_destroy should be as well. But in fact that is not really safe. > >>>> (either of them) > >>>> > >>>> The trouble is that we can not guarantee that other protocols can > >>>> handle being called multiple times in their init and destroy methods. > >>>> Especially 3rd party protocols. > >>>> > >>>> We need to ensure only protocols that have been converted to run > >>>> with multiple vnets are ever called with multiple vnets. > >>>> > >>>> for this reason the only safe way to do this is via the VNET_SYSINIT > >>>> and VNET_SYSUNINIT calls. > >>> > >>> That would mean you would have to convert most if not all of the > >>> existing things that hang off of protosw-s in netinet, netinet6 etc. to > >>> use VNET_SYSINT / VNET_SYSUNIT instead of protosw->pr_init(). So the > >>> short answer is no. > >> > >> robert has done just that. > > > > hmm: > > > > tpx32% pwd > > /u/marko/svn/head/sys > > > > tpx32% fgrep -R .pr_init netinet netinet6 netipsec|fgrep -v .svn > > netinet/ip_divert.c: .pr_init = div_init, > > netinet/in_proto.c: .pr_init = ip_init, > > netinet/in_proto.c: .pr_init = udp_init, > > netinet/in_proto.c: .pr_init = tcp_init, > > netinet/in_proto.c: .pr_init = sctp_init, > > netinet/in_proto.c: .pr_init = icmp_init, > > netinet/in_proto.c: .pr_init = encap_init, > > netinet/in_proto.c: .pr_init = encap_init, > > netinet/in_proto.c: .pr_init = encap_init, > > netinet/in_proto.c: .pr_init = encap_init, > > netinet/in_proto.c: .pr_init = encap_init, > > netinet/in_proto.c: .pr_init = rip_init, > > netinet6/in6_proto.c: .pr_init = ip6_init, > > netinet6/in6_proto.c: .pr_init = tcp_init, > > netinet6/in6_proto.c: .pr_init = icmp6_init, > > netinet6/in6_proto.c: .pr_init = encap_init, > > netinet6/in6_proto.c: .pr_init = encap_init, > > netinet6/ip6_mroute.c: .pr_init = pim6_init, > > netipsec/keysock.c: .pr_init = raw_init, > > AND for example: > in ./netinet/in_proto.c > VNET_DOMAIN_SET(inet); > includes > VNET_SYSINIT ##### --> called for every vnet as created #### > calls > vnet_domain_init() > calls > domain_init() > calls > protosw_init() > which includes > if (pr->pr_init) > (*pr->pr_init)(); > > so, robert is calling the init routine from each protocol > not the modevent. Right. But when we kldload ipdivert and register its protosw via pf_proto_register(), VNET_DOMAIN_SET() will not call ipdivert's pr_init() routine for each existing vnet, hence pf_proto_register() will have to do this. For subsequently created vnets, i.e. after ipdivert has been kldloaded, pr_init() will indeed be called via VNET_DOMAIN_SET() mechanism on each vnet instantiation. But at that point in time pf_proto_register() will not be called. So, in both cases pr_init() will be called exactly once per vnet, but via different mechanisms. Marko
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908130235.43161.zec>