Page MenuHomeFreeBSD

D26854.id78414.diff
No OneTemporary

D26854.id78414.diff

Index: sys/kern/kern_sysctl.c
===================================================================
--- sys/kern/kern_sysctl.c
+++ sys/kern/kern_sysctl.c
@@ -573,7 +573,7 @@
}
}
- /*
+ /*
* This can happen when a module fails to register and is
* being unloaded afterwards. It should not be a panic()
* for normal use.
@@ -939,7 +939,7 @@
/*
* "Staff-functions"
*
- * These functions implement a presently undocumented interface
+ * These functions implement a presently undocumented interface
* used by the sysctl program to walk the tree, and get the type
* so it can print the value.
* This interface is under work and consideration, and should probably
@@ -1076,7 +1076,7 @@
namelen--;
name++;
- if ((oid->oid_kind & CTLTYPE) != CTLTYPE_NODE)
+ if ((oid->oid_kind & CTLTYPE) != CTLTYPE_NODE)
break;
if (oid->oid_handler)
@@ -1100,9 +1100,13 @@
static SYSCTL_NODE(_sysctl, CTL_SYSCTL_NAME, name, CTLFLAG_RD |
CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_name, "");
+/*
+ * Walk the sysctl subtree at lsp until we find the given name,
+ * and return the next name in order by oid_number.
+ */
static int
-sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int *name, u_int namelen,
- int *next, int *len, int level, struct sysctl_oid **oidpp, bool honor_skip)
+sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int *name, u_int namelen,
+ int *next, int *len, int level, bool honor_skip)
{
struct sysctl_oid *oidp;
@@ -1110,7 +1114,6 @@
*len = level;
SLIST_FOREACH(oidp, lsp, oid_link) {
*next = oidp->oid_number;
- *oidpp = oidp;
if ((oidp->oid_kind & CTLFLAG_DORMANT) != 0)
continue;
@@ -1118,46 +1121,77 @@
if (honor_skip && (oidp->oid_kind & CTLFLAG_SKIP) != 0)
continue;
- if (!namelen) {
- if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
+ if (namelen == 0) {
+ /*
+ * We have reached a node with a full name match and are
+ * looking for the next oid in its children.
+ *
+ * For CTL_SYSCTL_NEXT we skip CTLTYPE_NODE (unless it
+ * has a handler) and move on to the children.
+ */
+ if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
return (0);
- if (oidp->oid_handler)
- /* We really should call the handler here...*/
+ if (oidp->oid_handler)
return (0);
lsp = SYSCTL_CHILDREN(oidp);
- if (!sysctl_sysctl_next_ls(lsp, 0, 0, next+1,
- len, level+1, oidpp, honor_skip))
+ if (!sysctl_sysctl_next_ls(lsp, NULL, 0, next + 1, len,
+ level + 1, honor_skip))
return (0);
+ /*
+ * There were no useable children in this node.
+ * Continue searching for the next oid at this level.
+ */
goto emptynode;
}
+ /*
+ * No match yet. Continue seeking the given name.
+ *
+ * We are iterating in order by oid_number, so skip oids lower
+ * than the one we are looking for.
+ *
+ * When the current oid_number is higher than the one we seek,
+ * that means we have reached the next oid in the sequence and
+ * should return it.
+ *
+ * If the oid_number matches the name at this level then we
+ * have to find a node to continue searching at the next level.
+ */
if (oidp->oid_number < *name)
continue;
-
if (oidp->oid_number > *name) {
+ /*
+ * We have reached the next oid.
+ *
+ * For CTL_SYSCTL_NEXT we skip CTLTYPE_NODE (unless it
+ * has a handler) and move on to the children.
+ */
if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
return (0);
if (oidp->oid_handler)
return (0);
lsp = SYSCTL_CHILDREN(oidp);
- if (!sysctl_sysctl_next_ls(lsp, name+1, namelen-1,
- next+1, len, level+1, oidpp, honor_skip))
+ if (!sysctl_sysctl_next_ls(lsp, name + 1, namelen - 1,
+ next + 1, len, level + 1, honor_skip))
return (0);
goto next;
}
if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
continue;
-
if (oidp->oid_handler)
continue;
-
lsp = SYSCTL_CHILDREN(oidp);
- if (!sysctl_sysctl_next_ls(lsp, name+1, namelen-1, next+1,
- len, level+1, oidpp, honor_skip))
+ if (!sysctl_sysctl_next_ls(lsp, name + 1, namelen - 1,
+ next + 1, len, level + 1, honor_skip))
return (0);
next:
+ /*
+ * There were no useable children in this node.
+ * Continue searching for the next oid at the root level.
+ */
namelen = 1;
emptynode:
+ /* Reset len in case a failed recursive call changed it. */
*len = level;
}
return (ENOENT);
@@ -1166,16 +1200,15 @@
static int
sysctl_sysctl_next(SYSCTL_HANDLER_ARGS)
{
- int *name = (int *) arg1;
+ int *name = (int *)arg1;
u_int namelen = arg2;
int len, error;
- struct sysctl_oid *oid;
struct sysctl_oid_list *lsp = &sysctl__children;
struct rm_priotracker tracker;
int next[CTL_MAXNAME];
SYSCTL_RLOCK(&tracker);
- error = sysctl_sysctl_next_ls(lsp, name, namelen, next, &len, 1, &oid,
+ error = sysctl_sysctl_next_ls(lsp, name, namelen, next, &len, 1,
oidp->oid_number == CTL_SYSCTL_NEXT);
SYSCTL_RUNLOCK(&tracker);
if (error)
@@ -1242,7 +1275,7 @@
struct rm_priotracker tracker;
char buf[32];
- if (!req->newlen)
+ if (!req->newlen)
return (ENOENT);
if (req->newlen >= MAXPATHLEN) /* XXX arbitrary, undocumented */
return (ENAMETOOLONG);

File Metadata

Mime Type
text/plain
Expires
Thu, Oct 8, 8:47 PM (19 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40442628
Default Alt Text
D26854.id78414.diff (5 KB)

Event Timeline