Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 5 Oct 2020 20:13:23 +0000 (UTC)
From:      Ryan Moeller <freqlabs@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r366465 - in head: sbin/sysctl sys/kern sys/sys usr.bin/truss
Message-ID:  <202010052013.095KDNHJ073900@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: freqlabs
Date: Mon Oct  5 20:13:22 2020
New Revision: 366465
URL: https://svnweb.freebsd.org/changeset/base/366465

Log:
  Enable iterating all sysctls, even ones with CTLFLAG_SKIP
  
  Add an "nextnoskip" sysctl that allows for listing of sysctls intended to be
  normally skipped for cost reasons.
  
  This makes it so the names/descriptions of those sysctls can be discovered with
  sysctl -aN/sysctl -ad/sysctl -at.
  
  It also makes it so children are visited when a node flagged with CTLFLAG_SKIP
  is explicitly requested.
  
  The intended use case is to mark the root "kstat" node with CTLFLAG_SKIP so that
  the extensive and expensive stats are skipped by default but may still be easily
  obtained without having to know them all (which may not even be possible) and
  request each one-by-one.
  
  Reviewed by:	jhb
  MFC after:	2 weeks
  Relnotes:	yes
  Sponsored by:	iXsystems, Inc.
  Differential Revision:	https://reviews.freebsd.org/D26560

Modified:
  head/sbin/sysctl/sysctl.c
  head/sys/kern/kern_sysctl.c
  head/sys/sys/sysctl.h
  head/usr.bin/truss/syscalls.c

Modified: head/sbin/sysctl/sysctl.c
==============================================================================
--- head/sbin/sysctl/sysctl.c	Mon Oct  5 19:58:55 2020	(r366464)
+++ head/sbin/sysctl/sysctl.c	Mon Oct  5 20:13:22 2020	(r366465)
@@ -81,7 +81,7 @@ static int	Nflag, nflag, oflag, qflag, tflag, Tflag, W
 static int	oidfmt(int *, int, char *, u_int *);
 static int	parsefile(const char *);
 static int	parse(const char *, int);
-static int	show_var(int *, int);
+static int	show_var(int *, int, bool);
 static int	sysctl_all(int *oid, int len);
 static int	name2oid(const char *, int *);
 
@@ -428,13 +428,13 @@ parse(const char *string, int lineno)
 	if (newvalstr == NULL || dflag) {
 		if ((kind & CTLTYPE) == CTLTYPE_NODE) {
 			if (dflag) {
-				i = show_var(mib, len);
+				i = show_var(mib, len, false);
 				if (!i && !bflag)
 					putchar('\n');
 			}
 			sysctl_all(mib, len);
 		} else {
-			i = show_var(mib, len);
+			i = show_var(mib, len, false);
 			if (!i && !bflag)
 				putchar('\n');
 		}
@@ -504,7 +504,7 @@ parse(const char *string, int lineno)
 			break;
 		}
 
-		i = show_var(mib, len);
+		i = show_var(mib, len, false);
 		if (sysctl(mib, len, 0, 0, newval, newsize) == -1) {
 			free(newbuf);
 			if (!i && !bflag)
@@ -532,7 +532,7 @@ parse(const char *string, int lineno)
 			printf(" -> ");
 		i = nflag;
 		nflag = 1;
-		j = show_var(mib, len);
+		j = show_var(mib, len, false);
 		if (!j && !bflag)
 			putchar('\n');
 		nflag = i;
@@ -942,7 +942,7 @@ oidfmt(int *oid, int len, char *fmt, u_int *kind)
  * Return minus one if we had errors.
  */
 static int
-show_var(int *oid, int nlen)
+show_var(int *oid, int nlen, bool honor_skip)
 {
 	u_char buf[BUFSIZ], *val, *oval, *p;
 	char name[BUFSIZ], fmt[BUFSIZ];
@@ -976,11 +976,11 @@ show_var(int *oid, int nlen)
 	oidfmt(oid, nlen, fmt, &kind);
 	/* if Wflag then only list sysctls that are writeable and not stats. */
 	if (Wflag && ((kind & CTLFLAG_WR) == 0 || (kind & CTLFLAG_STATS) != 0))
-		return 1;
+		return (1);
 
 	/* if Tflag then only list sysctls that are tuneables. */
 	if (Tflag && (kind & CTLFLAG_TUN) == 0)
-		return 1;
+		return (1);
 
 	if (Nflag) {
 		printf("%s", name);
@@ -1013,6 +1013,10 @@ show_var(int *oid, int nlen)
 		return (0);
 	}
 
+	/* bail before fetching the value if we're honoring skip */
+	if (honor_skip && (kind & CTLFLAG_SKIP) != 0)
+		return (1);
+
 	/* don't fetch opaques that we don't know how to print */
 	if (ctltype == CTLTYPE_OPAQUE) {
 		if (strcmp(fmt, "S,clockinfo") == 0)
@@ -1195,15 +1199,17 @@ sysctl_all(int *oid, int len)
 	int name1[22], name2[22];
 	int i, j;
 	size_t l1, l2;
+	bool honor_skip = false;
 
-	name1[0] = 0;
-	name1[1] = 2;
+	name1[0] = CTL_SYSCTL;
+	name1[1] = (oid != NULL || Nflag || dflag || tflag) ?
+	    CTL_SYSCTL_NEXTNOSKIP : CTL_SYSCTL_NEXT;
 	l1 = 2;
 	if (len) {
-		memcpy(name1+2, oid, len * sizeof(int));
+		memcpy(name1 + 2, oid, len * sizeof(int));
 		l1 += len;
 	} else {
-		name1[2] = 1;
+		name1[2] = CTL_KERN;
 		l1++;
 	}
 	for (;;) {
@@ -1225,11 +1231,12 @@ sysctl_all(int *oid, int len)
 			if (name2[i] != oid[i])
 				return (0);
 
-		i = show_var(name2, l2);
+		i = show_var(name2, l2, honor_skip);
 		if (!i && !bflag)
 			putchar('\n');
 
-		memcpy(name1+2, name2, l2 * sizeof(int));
+		memcpy(name1 + 2, name2, l2 * sizeof(int));
 		l1 = 2 + l2;
+		honor_skip = true;
 	}
 }

Modified: head/sys/kern/kern_sysctl.c
==============================================================================
--- head/sys/kern/kern_sysctl.c	Mon Oct  5 19:58:55 2020	(r366464)
+++ head/sys/kern/kern_sysctl.c	Mon Oct  5 20:13:22 2020	(r366465)
@@ -950,7 +950,8 @@ SYSINIT(sysctl, SI_SUB_KMEM, SI_ORDER_FIRST, sysctl_re
  * {CTL_SYSCTL, CTL_SYSCTL_DEBUG}		printf the entire MIB-tree.
  * {CTL_SYSCTL, CTL_SYSCTL_NAME, ...}		return the name of the "..."
  *						OID.
- * {CTL_SYSCTL, CTL_SYSCTL_NEXT, ...}		return the next OID.
+ * {CTL_SYSCTL, CTL_SYSCTL_NEXT, ...}		return the next OID, honoring
+ *						CTLFLAG_SKIP.
  * {CTL_SYSCTL, CTL_SYSCTL_NAME2OID}		return the OID of the name in
  *						"new"
  * {CTL_SYSCTL, CTL_SYSCTL_OIDFMT, ...}		return the kind & format info
@@ -959,6 +960,8 @@ SYSINIT(sysctl, SI_SUB_KMEM, SI_ORDER_FIRST, sysctl_re
  *						"..." OID.
  * {CTL_SYSCTL, CTL_SYSCTL_OIDLABEL, ...}	return the aggregation label of
  *						the "..." OID.
+ * {CTL_SYSCTL, CTL_SYSCTL_NEXTNOSKIP, ...}	return the next OID, ignoring
+ *						CTLFLAG_SKIP.
  */
 
 #ifdef SYSCTL_DEBUG
@@ -1099,7 +1102,7 @@ static SYSCTL_NODE(_sysctl, CTL_SYSCTL_NAME, name, CTL
 
 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)
+    int *next, int *len, int level, struct sysctl_oid **oidpp, bool honor_skip)
 {
 	struct sysctl_oid *oidp;
 
@@ -1109,9 +1112,12 @@ sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int
 		*next = oidp->oid_number;
 		*oidpp = oidp;
 
-		if ((oidp->oid_kind & (CTLFLAG_SKIP | CTLFLAG_DORMANT)) != 0)
+		if ((oidp->oid_kind & CTLFLAG_DORMANT) != 0)
 			continue;
 
+		if (honor_skip && (oidp->oid_kind & CTLFLAG_SKIP) != 0)
+			continue;
+
 		if (!namelen) {
 			if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE) 
 				return (0);
@@ -1120,7 +1126,7 @@ sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int
 				return (0);
 			lsp = SYSCTL_CHILDREN(oidp);
 			if (!sysctl_sysctl_next_ls(lsp, 0, 0, next+1, 
-				len, level+1, oidpp))
+				len, level+1, oidpp, honor_skip))
 				return (0);
 			goto emptynode;
 		}
@@ -1135,7 +1141,7 @@ sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int
 				return (0);
 			lsp = SYSCTL_CHILDREN(oidp);
 			if (!sysctl_sysctl_next_ls(lsp, name+1, namelen-1, 
-				next+1, len, level+1, oidpp))
+				next+1, len, level+1, oidpp, honor_skip))
 				return (0);
 			goto next;
 		}
@@ -1147,14 +1153,14 @@ sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int
 
 		lsp = SYSCTL_CHILDREN(oidp);
 		if (!sysctl_sysctl_next_ls(lsp, name+1, namelen-1, next+1, 
-			len, level+1, oidpp))
+			len, level+1, oidpp, honor_skip))
 			return (0);
 	next:
 		namelen = 1;
 	emptynode:
 		*len = level;
 	}
-	return (1);
+	return (ENOENT);
 }
 
 static int
@@ -1162,18 +1168,19 @@ sysctl_sysctl_next(SYSCTL_HANDLER_ARGS)
 {
 	int *name = (int *) arg1;
 	u_int namelen = arg2;
-	int i, j, error;
+	int len, error;
 	struct sysctl_oid *oid;
 	struct sysctl_oid_list *lsp = &sysctl__children;
 	struct rm_priotracker tracker;
-	int newoid[CTL_MAXNAME];
+	int next[CTL_MAXNAME];
 
 	SYSCTL_RLOCK(&tracker);
-	i = sysctl_sysctl_next_ls(lsp, name, namelen, newoid, &j, 1, &oid);
+	error = sysctl_sysctl_next_ls(lsp, name, namelen, next, &len, 1, &oid,
+	    oidp->oid_number == CTL_SYSCTL_NEXT);
 	SYSCTL_RUNLOCK(&tracker);
-	if (i)
-		return (ENOENT);
-	error = SYSCTL_OUT(req, newoid, j * sizeof (int));
+	if (error)
+		return (error);
+	error = SYSCTL_OUT(req, next, len * sizeof (int));
 	return (error);
 }
 
@@ -1184,6 +1191,9 @@ sysctl_sysctl_next(SYSCTL_HANDLER_ARGS)
 static SYSCTL_NODE(_sysctl, CTL_SYSCTL_NEXT, next, CTLFLAG_RD |
     CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_next, "");
 
+static SYSCTL_NODE(_sysctl, CTL_SYSCTL_NEXTNOSKIP, nextnoskip, CTLFLAG_RD |
+    CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_next, "");
+
 static int
 name2oid(char *name, int *oid, int *len, struct sysctl_oid **oidpp)
 {
@@ -2726,10 +2736,10 @@ db_show_sysctl_all(int *oid, size_t len, int flags)
 	name1[1] = CTL_SYSCTL_NEXT;
 	l1 = 2;
 	if (len) {
-		memcpy(name1+2, oid, len * sizeof(int));
-		l1 +=len;
+		memcpy(name1 + 2, oid, len * sizeof(int));
+		l1 += len;
 	} else {
-		name1[2] = 1;
+		name1[2] = CTL_KERN;
 		l1++;
 	}
 	for (;;) {
@@ -2742,7 +2752,7 @@ db_show_sysctl_all(int *oid, size_t len, int flags)
 			if (error == ENOENT)
 				return (0);
 			else
-				db_error("sysctl(getnext)");
+				db_error("sysctl(next)");
 		}
 
 		l2 /= sizeof(int);

Modified: head/sys/sys/sysctl.h
==============================================================================
--- head/sys/sys/sysctl.h	Mon Oct  5 19:58:55 2020	(r366464)
+++ head/sys/sys/sysctl.h	Mon Oct  5 20:13:22 2020	(r366465)
@@ -934,11 +934,12 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
  */
 #define	CTL_SYSCTL_DEBUG	0	/* printf all nodes */
 #define	CTL_SYSCTL_NAME		1	/* string name of OID */
-#define	CTL_SYSCTL_NEXT		2	/* next OID */
+#define	CTL_SYSCTL_NEXT		2	/* next OID, honoring CTLFLAG_SKIP */
 #define	CTL_SYSCTL_NAME2OID	3	/* int array of name */
 #define	CTL_SYSCTL_OIDFMT	4	/* OID's kind and format */
 #define	CTL_SYSCTL_OIDDESCR	5	/* OID's description */
 #define	CTL_SYSCTL_OIDLABEL	6	/* aggregation label */
+#define	CTL_SYSCTL_NEXTNOSKIP	7	/* next OID, ignoring CTLFLAG_SKIP */
 
 /*
  * CTL_KERN identifiers

Modified: head/usr.bin/truss/syscalls.c
==============================================================================
--- head/usr.bin/truss/syscalls.c	Mon Oct  5 19:58:55 2020	(r366464)
+++ head/usr.bin/truss/syscalls.c	Mon Oct  5 20:13:22 2020	(r366465)
@@ -2360,6 +2360,9 @@ print_arg(struct syscall_args *sc, unsigned long *args
 					fprintf(fp, "oidlabel ");
 					print_sysctl(fp, oid + 2, len - 2);
 					break;
+				case CTL_SYSCTL_NEXTNOSKIP:
+					fprintf(fp, "nextnoskip");
+					break;
 				default:
 					print_sysctl(fp, oid + 1, len - 1);
 				}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202010052013.095KDNHJ073900>