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);
                                }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to