Current-Users archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: sysctl_teardown() with dynamic nodes?
A little bit of progress in the on-going saga of sysctl_teardown() not
working as expected...
I still can't determine what the problem is, but I can reproduce it at
will. I put in some extra debugging stuff (a few calls to
sysctl_log_print()) and here's what I see (manual line-breaks inserted
for readability)
* The sysv_ipc module gets autoloaded and sets up its sysctl stuff.
sysv_ipc_modcmd: clog = 0xfffffe81f04dc318
root 0xffffffff806c0420 left 62 size 128 content \
version 715 type 2 len 3: 1 82 1369 \
version 714 type 2 len 3: 1 82 1368 \
version 713 type 2 len 3: 1 82 1367 \
version 712 type 2 len 3: 1 82 9 \
version 711 type 2 len 3: 1 82 8 \
version 710 type 2 len 3: 1 82 7 \
version 709 type 2 len 3: 1 82 6 \
version 708 type 4 len 3: 1 82 5 \
version 707 type 2 len 3: 1 82 1366 \
version 706 type 2 len 3: 1 82 1365 \
version 705 type 5 len 3: 1 82 1 end
* The module gets auto-unloaded, and syscall_teardown() returns
successfully.
sysv_ipc_modcmd: clog = 0xfffffe81f04dc318
root 0xffffffff806c0420 left 62 size 128 content \
<remainder of sysctl_log_print() elided>
* The module gets reloaded, and once again the sysctllog output
looks correct. Everything is the same except for the version and
node numbers:
sysv_ipc_modcmd: clog = 0xfffffe810f3b97d0
root 0xffffffff806c0420 left 62 size 128 content \
version 752 type 2 len 3: 1 83 1374 \
version 751 type 2 len 3: 1 83 1373 \
version 750 type 2 len 3: 1 83 1372 \
version 749 type 2 len 3: 1 82 9 \
version 748 type 2 len 3: 1 82 8 \
version 747 type 2 len 3: 1 82 7 \
version 746 type 2 len 3: 1 82 6 \
version 745 type 4 len 3: 1 82 5 \
version 744 type 2 len 3: 1 83 1371 \
version 743 type 2 len 3: 1 83 1370 \
version 742 type 5 len 3: 1 82 1 end
* Now, when auto-unload comes around, we get a failure for each of
the dynamically-assigned nodes (1370 thru 1374). Each of them
fails with error == 20 (ENOTDIR). Here's the debug output from
the first failure (note that the first entry in the log has been
consumed before the call to sysctl_log_print()).
sysctl_teardown: log 0xfffffe810f3b97d0 error 20 \
type 2 ver 752 name 1 83 1374
root 0xffffffff806c0420 left 68 size 128 content \
version 751 type 2 len 3: 1 83 1373 \
version 750 type 2 len 3: 1 83 1372 \
version 749 type 2 len 3: 1 82 9 \
version 748 type 2 len 3: 1 82 8 \
version 747 type 2 len 3: 1 82 7 \
version 746 type 2 len 3: 1 82 6 \
version 745 type 4 len 3: 1 82 5 \
version 744 type 2 len 3: 1 83 1371 \
version 743 type 2 len 3: 1 83 1370 \
version 742 type 5 len 3: 1 82 1 end
* And according to sysctl, these entries still exist in the tree:
# sysctl -M kern.ipc | sed -e "s/ flag/\\
flag/"
kern.ipc (1.82): CTLTYPE_NODE, children 8/16, size 96,
flags 0x200<READONLY,PERMANENT>, ver=758
kern.ipc.sysvmsg (1.82.2): CTLTYPE_INT, size 4,
flags 0x200<READONLY,PERMANENT>, ver=104
kern.ipc.sysvsem (1.82.3): CTLTYPE_INT, size 4,
flags 0x200<READONLY,PERMANENT>, ver=105
kern.ipc.sysvshm (1.82.4): CTLTYPE_INT, size 4,
flags 0x200<READONLY,PERMANENT>, ver=106
kern.ipc.msgmni (1.82.1370): CTLTYPE_INT, size 4,
flags 0x70<READWRITE>, func=0xffffffff808fc1db, ver=743
kern.ipc.msgseg (1.82.1371): CTLTYPE_INT, size 4,
flags 0x70<READWRITE>, func=0xffffffff808fc0eb, ver=744
kern.ipc.semmni (1.82.1372): CTLTYPE_INT, size 4,
flags 0x70<READWRITE>, func=0xffffffff808fdd93, ver=750
kern.ipc.semmns (1.82.1373): CTLTYPE_INT, size 4,
flags 0x70<READWRITE>, func=0xffffffff808fdccc, ver=751
kern.ipc.semmnu (1.82.1374): CTLTYPE_INT, size 4,
flags 0x70<READWRITE>, func=0xffffffff808fdc05, ver=752
I haven't tried this time, but on previous iterations, any attempt to
actually read these lingering entries results in a crash, since the
func pointers are no longer valid (the module has been unloaded).
It doesn't make a lot of sense to me how this could happen. The
failing entries are on either side of five entries that are torn-
down successfully. The only code I can find that would return a
ENOTDIR for sysctl_teardown() is in routine sysctl_locate()
int
sysctl_locate(struct lwp *l, const int *name, u_int namelen,
const struct sysctlnode **rnode, int *nip)
{
...
for (ni = 0; ni < namelen; ni++) {
/*
* walked off bottom of tree
*/
if (node == NULL) {
if (SYSCTL_TYPE(pnode->sysctl_flags) == CTLTYPE_NODE)
error = ENOENT;
else
error = ENOTDIR;
break;
}
...
}
*rnode = pnode;
if (nip)
*nip = ni;
return (error);
}
I just don't see how this could return ENOTDIR for some entries and
succeed for others.
+------------------+--------------------------+-------------------------+
| Paul Goyette | PGP Key fingerprint: | E-mail addresses: |
| (Retired) | FA29 0E3B 35AF E8AE 6651 | paul at whooppee.com |
| Kernel Developer | 0786 F758 55DE 53BA 7731 | pgoyette at netbsd.org |
+------------------+--------------------------+-------------------------+
Home |
Main Index |
Thread Index |
Old Index