[PATCH v2 7/8] docs: add a script to check sysctl docs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This script allows sysctl documentation to be checked against the
kernel source code, to identify missing or obsolete entries. Running
it against 5.5 shows for example that sysctl/kernel.rst has two
obsolete entries and is missing 52 entries.

Signed-off-by: Stephen Kitt <steve@xxxxxxx>
---
 Documentation/admin-guide/sysctl/kernel.rst |   3 +
 scripts/check-sysctl-docs                   | 181 ++++++++++++++++++++
 2 files changed, 184 insertions(+)
 create mode 100755 scripts/check-sysctl-docs

diff --git a/Documentation/admin-guide/sysctl/kernel.rst b/Documentation/admin-guide/sysctl/kernel.rst
index a67c218c4066..3d21e076aea4 100644
--- a/Documentation/admin-guide/sysctl/kernel.rst
+++ b/Documentation/admin-guide/sysctl/kernel.rst
@@ -2,6 +2,9 @@
 Documentation for /proc/sys/kernel/
 ===================================
 
+.. See scripts/check-sysctl-docs to keep this up to date
+
+
 Copyright (c) 1998, 1999,  Rik van Riel <riel@xxxxxxxxxxxx>
 
 Copyright (c) 2009,        Shen Feng<shen@xxxxxxxxxxxxxx>
diff --git a/scripts/check-sysctl-docs b/scripts/check-sysctl-docs
new file mode 100755
index 000000000000..b3b47c188a2d
--- /dev/null
+++ b/scripts/check-sysctl-docs
@@ -0,0 +1,181 @@
+#!/usr/bin/gawk -f
+# SPDX-License-Identifier: GPL-2.0-only
+
+# Script to check sysctl documentation against source files
+#
+# Copyright © 2020 Stephen Kitt
+
+# Example invocation:
+#	scripts/check-sysctl-docs -vtable="kernel" \
+#		Documentation/admin-guide/sysctl/kernel.rst \
+#		$(git grep -l register_sysctl_table)
+#
+# Specify -vdebug=1 to see debugging information
+
+BEGIN {
+    if (!table) {
+	print "Please specify the table to look for using the table variable" > "/dev/stderr"
+	exit 1
+    }
+}
+
+# The following globals are used:
+# children: maps ctl_table names and procnames to child ctl_table names
+# documented: maps documented entries (each key is an entry)
+# entries: maps ctl_table names and procnames to counts (so
+#          enumerating the subkeys for a given ctl_table lists its
+#          procnames)
+# files: maps procnames to source file names
+# paths: maps ctl_path names to paths
+# curpath: the name of the current ctl_path struct
+# curtable: the name of the current ctl_table struct
+# curentry: the name of the current proc entry (procname when parsing
+#           a ctl_table, constructed path when parsing a ctl_path)
+
+
+# Remove punctuation from the given value
+function trimpunct(value) {
+    while (value ~ /^["&]/) {
+	value = substr(value, 2)
+    }
+    while (value ~ /[]["&,}]$/) {
+	value = substr(value, 1, length(value) - 1)
+    }
+    return value
+}
+
+# Print the information for the given entry
+function printentry(entry) {
+    seen[entry]++
+    printf "* %s from %s", entry, file[entry]
+    if (documented[entry]) {
+	printf " (documented)"
+    }
+    print ""
+}
+
+
+# Stage 1: build the list of documented entries
+FNR == NR && /^=+$/ {
+    if (prevline ~ /Documentation for/) {
+	# This is the main title
+	next
+    }
+
+    # The previous line is a section title, parse it
+    $0 = prevline
+    if (debug) print "Parsing " $0
+    inbrackets = 0
+    for (i = 1; i <= NF; i++) {
+	if (length($i) == 0) {
+	    continue
+	}
+	if (!inbrackets && substr($i, 1, 1) == "(") {
+	    inbrackets = 1
+	}
+	if (!inbrackets) {
+	    token = trimpunct($i)
+	    if (length(token) > 0 && token != "and") {
+		if (debug) print trimpunct($i)
+		documented[trimpunct($i)]++
+	    }
+	}
+	if (inbrackets && substr($i, length($i), 1) == ")") {
+	    inbrackets = 0
+	}
+    }
+}
+
+FNR == NR {
+    prevline = $0
+    next
+}
+
+
+# Stage 2: process each file and find all sysctl tables
+BEGINFILE {
+    delete children
+    delete entries
+    delete paths
+    curpath = ""
+    curtable = ""
+    curentry = ""
+    if (debug) print "Processing file " FILENAME
+}
+
+/^static struct ctl_path/ {
+    match($0, /static struct ctl_path ([^][]+)/, tables)
+    curpath = tables[1]
+    if (debug) print "Processing path " curpath
+}
+
+/^static struct ctl_table/ {
+    match($0, /static struct ctl_table ([^][]+)/, tables)
+    curtable = tables[1]
+    if (debug) print "Processing table " curtable
+}
+
+/^};$/ {
+    curpath = ""
+    curtable = ""
+    curentry = ""
+}
+
+curpath && /\.procname[\t ]*=[\t ]*".+"/ {
+    match($0, /.procname[\t ]*=[\t ]*"([^"]+)"/, names)
+    if (curentry) {
+	curentry = curentry "/" names[1]
+    } else {
+	curentry = names[1]
+    }
+    if (debug) print "Setting path " curpath " to " curentry
+    paths[curpath] = curentry
+}
+
+curtable && /\.procname[\t ]*=[\t ]*".+"/ {
+    match($0, /.procname[\t ]*=[\t ]*"([^"]+)"/, names)
+    curentry = names[1]
+    if (debug) print "Adding entry " curentry " to table " curtable
+    entries[curtable][curentry]++
+    file[curentry] = FILENAME
+}
+
+/\.child[\t ]*=/ {
+    child = trimpunct($NF)
+    if (debug) print "Linking child " child " to table " curtable " entry " curentry
+    children[curtable][curentry] = child
+}
+
+/register_sysctl_table\(.*\)/ {
+    match($0, /register_sysctl_table\(([^)]+)\)/, tables)
+    if (debug) print "Registering table " tables[1]
+    if (children[tables[1]][table]) {
+	for (entry in entries[children[tables[1]][table]]) {
+	    printentry(entry)
+	}
+    }
+}
+
+/register_sysctl_paths\(.*\)/ {
+    match($0, /register_sysctl_paths\(([^)]+), ([^)]+)\)/, tables)
+    if (debug) print "Attaching table " tables[2] " to path " tables[1]
+    if (paths[tables[1]] == table) {
+	for (entry in entries[tables[2]]) {
+	    printentry(entry)
+	}
+    }
+    split(paths[tables[1]], components, "/")
+    if (length(components) > 1 && components[1] == table) {
+	# Count the first subdirectory as seen
+	seen[components[2]]++
+    }
+}
+
+
+END {
+    for (entry in documented) {
+	if (!seen[entry]) {
+	    print "No implementation for " entry
+	}
+    }
+}
-- 
2.20.1




[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux