bin/123644: Allow sysctl(8) to ignore unknown OIDs

David Wolfskill david at catwhisker.org
Tue May 13 22:50:02 UTC 2008


>Number:         123644
>Category:       bin
>Synopsis:       Allow sysctl(8) to ignore unknown OIDs
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue May 13 22:50:01 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator:     David Wolfskill
>Release:        FreeBSD 8.0-CURRENT i386
>Organization:
Wolfskill & Dowling Residence
>Environment:
FreeBSD localhost 8.0-CURRENT FreeBSD 8.0-CURRENT #769: Mon May 12 07:17:44 PDT 2008     root at g1-37.catwhisker.org:/common/S4/obj/usr/src/sys/CANARY  i386
>Description:
Generally, requesting that sysctl(8) report the value of an OID it
doesn't know causes the program to exit without attempting to process
any additional OIDs.  there is a -q option, but that does not control
whether or not sysctl(8) exits -- merely whether or not it whines in the
process.

I propose the addition of a flag (the below patch uses "-i," but I don't
care which letter is used) to specify that sysctl(8) should silently
ignore the specification of any unknown OIDs.

The reason for this is that I have been using sysctl(8) to retrieve
information on resource usage on various machines.  I find that if I try
to use a single list of OIDs for all of the machines I'm querying, it's
fairly probable that my OID list includes an OID that isn't supported by
at least one of the systems.  I realize that in an ideal world, it may
be reasonable to expect me to use a separate, machine-specific list of
OIDs for each such system, but in practice, this is quite
counter-productive.

By using the patched version of the code (which, IMO, should be a
candidate for MFC if it's committed to HEAD), I transform sysctl(8) into
a "best effort" OID-reporting tool.  And if I don't get values for some
OID, my scripts know how to handle that easily enough.

>How-To-Repeat:
On a FreeBSD 8-CURRENT system:

localhost(8.0-C)[2] sysctl hw.ncpu kern.sched.quantum net.inet.ip.fw.enable
hw.ncpu: 1
sysctl: unknown oid 'kern.sched.quantum'
localhost(8.0-C)[3] 

Notice that we didn't get a report for "net.inet.ip.fw.enable".

Now, after applying the patch, then rebuilding & re-installing sysctl(8):

localhost(8.0-C)[3] sysctl -i hw.ncpu kern.sched.quantum net.inet.ip.fw.enable
hw.ncpu: 1
net.inet.ip.fw.enable: 1
localhost(8.0-C)[4] 

We now get the value for net.inet.ip.fw.enable; the request for
kern.sched.quantum is silently ignored.

>Fix:

Index: sysctl.8
===================================================================
RCS file: /cvs/freebsd/src/sbin/sysctl/sysctl.8,v
retrieving revision 1.64
diff -u -r1.64 sysctl.8
--- sysctl.8	28 Nov 2007 14:48:30 -0000	1.64
+++ sysctl.8	12 May 2008 19:14:08 -0000
@@ -82,6 +82,12 @@
 is specified, or a variable is being set.
 .It Fl h
 Format output for human, rather than machine, readability.
+.It Fl i
+Ignore unknown OIDs.
+The purpose is to make use of
+.Nm
+for collecting data from a variety of machines (not all of which
+are necessarily running exactly the same software) easier.
 .It Fl N
 Show only variable names, not their values.
 This is particularly useful with shells that offer programmable
Index: sysctl.c
===================================================================
RCS file: /cvs/freebsd/src/sbin/sysctl/sysctl.c,v
retrieving revision 1.88
diff -u -r1.88 sysctl.c
--- sysctl.c	15 Oct 2007 20:00:19 -0000	1.88
+++ sysctl.c	12 May 2008 19:07:34 -0000
@@ -58,8 +58,8 @@
 #include <string.h>
 #include <unistd.h>
 
-static int	aflag, bflag, dflag, eflag, hflag, Nflag, nflag, oflag;
-static int	qflag, xflag;
+static int	aflag, bflag, dflag, eflag, hflag, iflag, Nflag, nflag;
+static int	oflag, qflag, xflag;
 
 static int	oidfmt(int *, int, char *, u_int *);
 static void	parse(char *);
@@ -89,7 +89,7 @@
 	setbuf(stdout,0);
 	setbuf(stderr,0);
 
-	while ((ch = getopt(argc, argv, "AabdehNnoqwxX")) != -1) {
+	while ((ch = getopt(argc, argv, "AabdehiNnoqwxX")) != -1) {
 		switch (ch) {
 		case 'A':
 			/* compatibility */
@@ -110,6 +110,9 @@
 		case 'h':
 			hflag = 1;
 			break;
+		case 'i':
+			iflag = 1;
+			break;
 		case 'N':
 			Nflag = 1;
 			break;
@@ -185,6 +188,8 @@
 	len = name2oid(bufp, mib);
 
 	if (len < 0) {
+		if (iflag)
+			return;
 		if (qflag)
 			exit(1);
 		else
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list