[PATCH 1/6] sysctl: add and use base directory declarer and registration helper

From: Luis Chamberlain
Date: Mon Nov 29 2021 - 17:59:43 EST


Add a set of helpers which can be used to declare and register
base directory sysctls on their own. We do this so we can later
move each of the base sysctl directories like "fs", "kernel", etc,
to their own respective files instead of shoving the declarations
and registrations all on kernel/sysctl.c. The lazy approach has
caught up and with this, we just end up extending the list of
base directories / sysctls on one file and this makes maintenance
difficult due to merge conflicts from many developers.

The declarations is used first by kernel/sysctl.c for registration
its own base which over time we'll try to clean up. It will be used
in the next patch to demonstrate how to cleanly deal with base sysctl
directories.

Signed-off-by: Luis Chamberlain <mcgrof@xxxxxxxxxx>
---
fs/proc/proc_sysctl.c | 9 +++++++++
include/linux/sysctl.h | 23 +++++++++++++++++++++++
kernel/sysctl.c | 41 ++++++++++-------------------------------
3 files changed, 42 insertions(+), 31 deletions(-)

diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index 675b625fa898..93a49ca82d64 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -1646,6 +1646,15 @@ struct ctl_table_header *register_sysctl_table(struct ctl_table *table)
}
EXPORT_SYMBOL(register_sysctl_table);

+int __register_sysctl_base(struct ctl_table *base_table)
+{
+ struct ctl_table_header *hdr;
+
+ hdr = register_sysctl_table(base_table);
+ kmemleak_not_leak(hdr);
+ return 0;
+}
+
static void put_links(struct ctl_table_header *header)
{
struct ctl_table_set *root_set = &sysctl_table_root.default_set;
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 4294e9668bd5..b4b280e7b6c1 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -194,6 +194,19 @@ struct ctl_path {

#ifdef CONFIG_SYSCTL

+#define DECLARE_SYSCTL_BASE(_name, _table) \
+static struct ctl_table _name##_base_table[] = { \
+ { \
+ .procname = #_name, \
+ .mode = 0555, \
+ .child = _table, \
+ }, \
+}
+
+extern int __register_sysctl_base(struct ctl_table *base_table);
+
+#define register_sysctl_base(_name) __register_sysctl_base(_name##_base_table)
+
void proc_sys_poll_notify(struct ctl_table_poll *poll);

extern void setup_sysctl_set(struct ctl_table_set *p,
@@ -236,6 +249,16 @@ extern int no_unaligned_warning;
extern struct ctl_table sysctl_mount_point[];

#else /* CONFIG_SYSCTL */
+
+#define DECLARE_SYSCTL_BASE(_name, _table)
+
+static inline int __register_sysctl_base(struct ctl_table *base_table)
+{
+ return 0;
+}
+
+#define register_sysctl_base(table) __register_sysctl_base(table)
+
static inline struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
{
return NULL;
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index a4cde441635d..bbbafe545723 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -2850,41 +2850,20 @@ static struct ctl_table dev_table[] = {
{ }
};

-static struct ctl_table sysctl_base_table[] = {
- {
- .procname = "kernel",
- .mode = 0555,
- .child = kern_table,
- },
- {
- .procname = "vm",
- .mode = 0555,
- .child = vm_table,
- },
- {
- .procname = "fs",
- .mode = 0555,
- .child = fs_table,
- },
- {
- .procname = "debug",
- .mode = 0555,
- .child = debug_table,
- },
- {
- .procname = "dev",
- .mode = 0555,
- .child = dev_table,
- },
- { }
-};
+DECLARE_SYSCTL_BASE(kernel, kern_table);
+DECLARE_SYSCTL_BASE(vm, vm_table);
+DECLARE_SYSCTL_BASE(fs, fs_table);
+DECLARE_SYSCTL_BASE(debug, debug_table);
+DECLARE_SYSCTL_BASE(dev, dev_table);

int __init sysctl_init(void)
{
- struct ctl_table_header *hdr;
+ register_sysctl_base(kernel);
+ register_sysctl_base(vm);
+ register_sysctl_base(fs);
+ register_sysctl_base(debug);
+ register_sysctl_base(dev);

- hdr = register_sysctl_table(sysctl_base_table);
- kmemleak_not_leak(hdr);
return 0;
}
#endif /* CONFIG_SYSCTL */
--
2.33.0