|
Description
|
Due to a limitation with the netinfo framework, it is necessary to call net_kstat_delete() from the shutdown callback rather than the fini/destroy callback.
At present, ipfilter fails to do a mapping of the netid_t to a netstackid_t when called from ipf_stack_fini because neti_stack_fini has removed the corresponding neti_stack_t from the list which is used to translate the numbers.
Although this list isn't currently needed as there is a 1:1 relationship between netid_t and netstackid_t, just casting/copying the number across gives the impression that an id number is valid in a particular number space when in fact it isn't.
The current behaviour leads to ipfilter never deleting the kstats for a zone when an exclusive ip zone shuts down. Thus after 8192 exclusive ip zones have been created, warning messages appear on the console about kstat_create() failing.
The problem as per dtrace:
24 38772 net_kstat_create:entry (235,ipf,0,inbound)
24 38773 net_kstat_create:return =3335938703360
24 38772 net_kstat_create:entry (235,ipf,0,outbound)
24 38773 net_kstat_create:return =3336516116480
24 60470 ipf_kstat_fini:entry 235,308b5710000/308d7dba000
ipf`ipf_stack_destroy+0x7c
neti`neti_stack_apply_destroy+0x180
neti`neti_apply_all_instances+0x40
neti`neti_stack_fini+0xbc
genunix`netstack_apply_destroy+0x108
genunix`apply_all_modules_reverse+0x24
genunix`netstack_stack_inactive+0x160
genunix`netstack_rele+0x60
genunix`zsd_apply_destroy+0x174
genunix`zsd_apply_all_keys+0x30
genunix`zone_destroy+0xb0
genunix`zone+0x160
unix`syscall_trap32+0x1e4
24 38801 net_getnetstackidbynetid:return 235 => -1
24 38775 net_kstat_delete:return (235,308b5710000) = 235
24 38801 net_getnetstackidbynetid:return 235 => -1
24 38775 net_kstat_delete:return (235,308d7dba000) = 235
Thus net_kstat_delete() never calls kstat_delete_netstack():
void
net_kstat_delete(netid_t netid, kstat_t *ks)
{
netstackid_t stackid = net_getnetstackidbynetid(netid);
if (stackid != -1)
kstat_delete_netstack(ks, stackid);
}
When fixed:
12 39720 net_kstat_create:entry (249,ipf,0,inbound)
12 39721 net_kstat_create:return =3299213606912
12 39720 net_kstat_create:entry (249,ipf,0,outbound)
12 39721 net_kstat_create:return =3299213608432
17 1599 ipf_kstat_fini:entry 249,30028748000/300287485f0
neti`neti_stack_apply_shutdown+0x200
neti`neti_apply_all_instances+0x40
neti`neti_stack_shutdown+0xbc
genunix`netstack_apply_shutdown+0x108
genunix`apply_all_modules_reverse+0x24
genunix`netstack_zone_shutdown+0x154
genunix`zsd_apply_shutdown+0x174
genunix`zsd_apply_all_keys+0x30
genunix`zone_zsd_callbacks+0x140
genunix`zone_shutdown+0x1a4
genunix`zone+0x1c0
unix`syscall_trap32+0x1e4
17 39749 net_getnetstackidbynetid:return 249 => 249
17 39723 net_kstat_delete:return (249,30028748000) = 3299213606912
17 12114 kstat_delete:entry flags 0
17 12115 kstat_delete:return
17 39749 net_getnetstackidbynetid:return 249 => 249
17 39723 net_kstat_delete:return (249,300287485f0) = 3299213608432
17 12114 kstat_delete:entry flags 0
17 12115 kstat_delete:return
Because net_kstat_delete() relies on functions within netinfo returning a proper
netid_t (and not -1), it needs to be called in the shutdown callback of ipfilter
so that it happens before neti_stack_fini() is called.
The call to neti_stack_fini() causes functions such as net_getnetstackidbynetid() to
return -1 because it removes the neti_stack_t from the list of active structures
at the top of the function.
|