aboutsummaryrefslogtreecommitdiffstats
path: root/net/decnet
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2013-03-11 17:41:28 -0700
committerBen Hutchings <ben@decadent.org.uk>2013-03-20 15:03:28 +0000
commit3125bdd601790d03f36343d9d0941c5f94244f27 (patch)
treef6f959a90a2ebc2dd174c93149e69f45992de4e3 /net/decnet
parent3ac94a54e1e69d5e510c92c56dda242a7398ce54 (diff)
downloadkernel_samsung_smdk4412-3125bdd601790d03f36343d9d0941c5f94244f27.zip
kernel_samsung_smdk4412-3125bdd601790d03f36343d9d0941c5f94244f27.tar.gz
kernel_samsung_smdk4412-3125bdd601790d03f36343d9d0941c5f94244f27.tar.bz2
decnet: Fix disappearing sysctl entries
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>
Diffstat (limited to 'net/decnet')
-rw-r--r--net/decnet/af_decnet.c4
-rw-r--r--net/decnet/sysctl_net_decnet.c28
2 files changed, 32 insertions, 0 deletions
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index 19acd00..16fbf8c 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -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);
diff --git a/net/decnet/sysctl_net_decnet.c b/net/decnet/sysctl_net_decnet.c
index 02e75d1..d50a13c 100644
--- a/net/decnet/sysctl_net_decnet.c
+++ b/net/decnet/sysctl_net_decnet.c
@@ -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)
{
}