Author: cem
Date: Sun Aug 27 17:12:30 2017
New Revision: 322954
URL: https://svnweb.freebsd.org/changeset/base/322954

Log:
  Enhance debugibility of sysctl leaf re-use warnings
  
  Print the full conflicting oid path, and include the function name in the
  warning so it is clear that the warnings are sysctl-related.
  
  PR:           221853
  Submitted by: Fabian Keil <fk AT fabiankeil.de> (earlier version)
  Sponsored by: Dell EMC Isilon

Modified:
  head/sys/kern/kern_sysctl.c

Modified: head/sys/kern/kern_sysctl.c
==============================================================================
--- head/sys/kern/kern_sysctl.c Sun Aug 27 17:08:08 2017        (r322953)
+++ head/sys/kern/kern_sysctl.c Sun Aug 27 17:12:30 2017        (r322954)
@@ -323,6 +323,91 @@ sysctl_load_tunable_by_oid_locked(struct sysctl_oid *o
                freeenv(penv);
 }
 
+static int
+sbuf_printf_drain(void *arg __unused, const char *data, int len)
+{
+
+       return (printf("%.*s", len, data));
+}
+
+/*
+ * Locate the path to a given oid.  Returns the length of the resulting path,
+ * or -1 if the oid was not found.  nodes must have room for CTL_MAXNAME
+ * elements and be NULL initialized.
+ */
+static int
+sysctl_search_oid(struct sysctl_oid **nodes, struct sysctl_oid *needle)
+{
+       int indx;
+
+       SYSCTL_ASSERT_LOCKED();
+       indx = 0;
+       while (indx < CTL_MAXNAME && indx >= 0) {
+               if (nodes[indx] == NULL && indx == 0)
+                       nodes[indx] = SLIST_FIRST(&sysctl__children);
+               else if (nodes[indx] == NULL)
+                       nodes[indx] = SLIST_FIRST(&nodes[indx - 
1]->oid_children);
+               else
+                       nodes[indx] = SLIST_NEXT(nodes[indx], oid_link);
+
+               if (nodes[indx] == needle)
+                       return (indx + 1);
+
+               if (nodes[indx] == NULL) {
+                       indx--;
+                       continue;
+               }
+
+               if ((nodes[indx]->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
+                       indx++;
+                       continue;
+               }
+       }
+       return (-1);
+}
+
+static void
+sysctl_warn_reuse(const char *func, struct sysctl_oid *leaf)
+{
+       struct sysctl_oid *nodes[CTL_MAXNAME];
+       char buf[128];
+       struct sbuf sb;
+       int rc, i;
+
+       (void)sbuf_new(&sb, buf, sizeof(buf), SBUF_FIXEDLEN | SBUF_INCLUDENUL);
+       sbuf_set_drain(&sb, sbuf_printf_drain, NULL);
+
+       sbuf_printf(&sb, "%s: can't re-use a leaf (", __func__);
+
+       memset(nodes, 0, sizeof(nodes));
+       rc = sysctl_search_oid(nodes, leaf);
+       if (rc > 0) {
+               for (i = 0; i < rc; i++)
+                       sbuf_printf(&sb, "%s%.*s", nodes[i]->oid_name,
+                           i != (rc - 1), ".");
+       } else {
+               sbuf_printf(&sb, "%s", leaf->oid_name);
+       }
+       sbuf_printf(&sb, ")!\n");
+
+       (void)sbuf_finish(&sb);
+}
+
+#ifdef SYSCTL_DEBUG
+static int
+sysctl_reuse_test(SYSCTL_HANDLER_ARGS)
+{
+       struct rm_priotracker tracker;
+
+       SYSCTL_RLOCK(&tracker);
+       sysctl_warn_reuse(__func__, oidp);
+       SYSCTL_RUNLOCK(&tracker);
+       return (0);
+}
+SYSCTL_PROC(_sysctl, 0, reuse_test, CTLTYPE_STRING|CTLFLAG_RD|CTLFLAG_MPSAFE,
+       0, 0, sysctl_reuse_test, "-", "");
+#endif
+
 void
 sysctl_register_oid(struct sysctl_oid *oidp)
 {
@@ -343,7 +428,7 @@ sysctl_register_oid(struct sysctl_oid *oidp)
                        p->oid_refcnt++;
                        return;
                } else {
-                       printf("can't re-use a leaf (%s)!\n", p->oid_name);
+                       sysctl_warn_reuse(__func__, p);
                        return;
                }
        }
@@ -715,8 +800,8 @@ sysctl_add_oid(struct sysctl_ctx_list *clist, struct s
                        SYSCTL_WUNLOCK();
                        return (oidp);
                } else {
+                       sysctl_warn_reuse(__func__, oidp);
                        SYSCTL_WUNLOCK();
-                       printf("can't re-use a leaf (%s)!\n", name);
                        return (NULL);
                }
        }
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to