Index: sys/kern/kern_sysctl.c =================================================================== --- sys/kern/kern_sysctl.c +++ sys/kern/kern_sysctl.c @@ -1017,53 +1017,52 @@ { int *name = (int *) arg1; u_int namelen = arg2; - int error = 0; - struct sysctl_oid *oid; - struct sysctl_oid_list *lsp = &sysctl__children, *lsp2; + int error = 0, indx = 0; + struct sysctl_oid *oid, *objpath[CTL_MAXNAME]; + struct sysctl_oid_list *lsp = &sysctl__children; struct rm_priotracker tracker; - char buf[10]; SYSCTL_RLOCK(&tracker); - while (namelen) { - if (!lsp) { - snprintf(buf,sizeof(buf),"%d",*name); - if (req->oldidx) - error = SYSCTL_OUT(req, ".", 1); - if (!error) - error = SYSCTL_OUT(req, buf, strlen(buf)); - if (error) - goto out; - namelen--; - name++; - continue; - } - lsp2 = NULL; + while (indx < namelen) { SLIST_FOREACH(oid, lsp, oid_link) { - if (oid->oid_number != *name) - continue; - - if (req->oldidx) - error = SYSCTL_OUT(req, ".", 1); - if (!error) - error = SYSCTL_OUT(req, oid->oid_name, - strlen(oid->oid_name)); - if (error) - goto out; - - namelen--; - name++; - - if ((oid->oid_kind & CTLTYPE) != CTLTYPE_NODE) + if (oid->oid_number == name[indx]) break; + } + if (oid == NULL) { + error = ENOENT; + goto out; + } + objpath[indx] = oid; + indx++; - if (oid->oid_handler) - break; - - lsp2 = SYSCTL_CHILDREN(oid); - break; + if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) { + if (oid->oid_handler != NULL || indx == namelen) { + KASSERT((oid->oid_kind & CTLFLAG_DYING) == 0, + ("%s found DYING node %p", __func__, oid)); + } + lsp = SYSCTL_CHILDREN(oid); + } else if (indx == namelen) { + if ((oid->oid_kind & CTLFLAG_DORMANT) != 0) { + error = ENOENT; + goto out; + } + KASSERT((oid->oid_kind & CTLFLAG_DYING) == 0, + ("%s found DYING node %p", __func__, oid)); + } else { + error = ENOTDIR; + goto out; } - lsp = lsp2; } + + for(indx=0; indx < namelen; indx++) { + if (req->oldidx) + error = SYSCTL_OUT(req, ".", 1); + if (!error) + error = SYSCTL_OUT(req, objpath[indx]->oid_name, + strlen(objpath[indx]->oid_name)); + if (error) + goto out; + } error = SYSCTL_OUT(req, "", 1); out: SYSCTL_RUNLOCK(&tracker);