]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
decnet: Fix disappearing sysctl entries
authorEric W. Biederman <ebiederm@xmission.com>
Tue, 12 Mar 2013 00:41:28 +0000 (17:41 -0700)
committerBen Hutchings <ben@decadent.org.uk>
Wed, 20 Mar 2013 15:03:28 +0000 (15:03 +0000)
When decnet is built as a module a simple:
echo 0.0 >/proc/sys/net/decnet/node_address

results in most of the sysctl entries under /proc/sys/net/decnet and
/proc/sys/net/decnet/conf disappearing.

For more details see http://www.spinics.net/lists/netdev/msg226123.html.

This change applies the same workaround used in
net/core/sysctl_net_core.c and net/ipv6/sysctl_net_ipv6.c of creating
a skeleton of decnet sysctl entries before doing anything else.

The problem first appeared in kernel 2.6.27.  The later rewrite of
sysctl in kernel 3.4 restored the previous behavior and eliminated the
need for this workaround.

This patch was heavily inspired by a similar but more complex patch by
Larry Baker.

Reported-by: Larry Baker <baker@usgs.gov>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
net/decnet/af_decnet.c
net/decnet/sysctl_net_decnet.c

index 19acd00a63826b66bb3f8076bc75b7fa48d2f241..16fbf8c28e313b5b52c3f861ae91446b18eadc07 100644 (file)
@@ -2354,6 +2354,8 @@ static const struct proto_ops dn_proto_ops = {
        .sendpage =     sock_no_sendpage,
 };
 
+void dn_register_sysctl_skeleton(void);
+void dn_unregister_sysctl_skeleton(void);
 void dn_register_sysctl(void);
 void dn_unregister_sysctl(void);
 
@@ -2374,6 +2376,7 @@ static int __init decnet_init(void)
        if (rc != 0)
                goto out;
 
+       dn_register_sysctl_skeleton();
        dn_neigh_init();
        dn_dev_init();
        dn_route_init();
@@ -2413,6 +2416,7 @@ static void __exit decnet_exit(void)
        dn_fib_cleanup();
 
        proc_net_remove(&init_net, "decnet");
+       dn_unregister_sysctl_skeleton();
 
        proto_unregister(&dn_proto);
 
index 02e75d11cfbb2e73a1a473e536bfa81e1429c92e..d50a13cbb04c123e9eca3a3df4effa633ac2ad3e 100644 (file)
@@ -55,6 +55,7 @@ static int max_decnet_no_fc_max_cwnd[] = { NSP_MAX_WINDOW };
 static char node_name[7] = "???";
 
 static struct ctl_table_header *dn_table_header = NULL;
+static struct ctl_table_header *dn_skeleton_table_header = NULL;
 
 /*
  * ctype.h :-)
@@ -357,6 +358,27 @@ static struct ctl_path dn_path[] = {
        { }
 };
 
+static struct ctl_table empty[1];
+
+static struct ctl_table dn_skeleton[] = {
+       {
+               .procname = "conf",
+               .mode = 0555,
+               .child = empty,
+       },
+       { }
+};
+
+void dn_register_sysctl_skeleton(void)
+{
+       dn_skeleton_table_header = register_sysctl_paths(dn_path, dn_skeleton);
+}
+
+void dn_unregister_sysctl_skeleton(void)
+{
+       unregister_sysctl_table(dn_skeleton_table_header);
+}
+
 void dn_register_sysctl(void)
 {
        dn_table_header = register_sysctl_paths(dn_path, dn_table);
@@ -368,6 +390,12 @@ void dn_unregister_sysctl(void)
 }
 
 #else  /* CONFIG_SYSCTL */
+void dn_register_sysctl_skeleton(void)
+{
+}
+void dn_unregister_sysctl_skeleton(void)
+{
+}
 void dn_unregister_sysctl(void)
 {
 }