aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sysctl_check.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2007-11-30 07:54:00 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:55:17 -0500
commite51b6ba077791f2f8c876022b37419be7a2ceec3 (patch)
tree9d8ca18f3239eff84cad5b79b715c332970fa89d /kernel/sysctl_check.c
parent23eb06de7d2d333a0f7ebba2da663e00c9c9483e (diff)
sysctl: Infrastructure for per namespace sysctls
This patch implements the basic infrastructure for per namespace sysctls. A list of lists of sysctl headers is added, allowing each namespace to have it's own list of sysctl headers. Each list of sysctl headers has a lookup function to find the first sysctl header in the list, allowing the lists to have a per namespace instance. register_sysct_root is added to tell sysctl.c about additional lists of sysctl_headers. As all of the users are expected to be in kernel no unregister function is provided. sysctl_head_next is updated to walk through the list of lists. __register_sysctl_paths is added to add a new sysctl table on a non-default sysctl list. The only intrusive part of this patch is propagating the information to decided which list of sysctls to use for sysctl_check_table. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Cc: Serge Hallyn <serue@us.ibm.com> Cc: Daniel Lezcano <dlezcano@fr.ibm.com> Cc: Cedric Le Goater <clg@fr.ibm.com> Cc: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'kernel/sysctl_check.c')
-rw-r--r--kernel/sysctl_check.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/kernel/sysctl_check.c b/kernel/sysctl_check.c
index d8a5558a47b4..c3206fa50048 100644
--- a/kernel/sysctl_check.c
+++ b/kernel/sysctl_check.c
@@ -1342,7 +1342,8 @@ static void sysctl_repair_table(struct ctl_table *table)
1342 } 1342 }
1343} 1343}
1344 1344
1345static struct ctl_table *sysctl_check_lookup(struct ctl_table *table) 1345static struct ctl_table *sysctl_check_lookup(struct nsproxy *namespaces,
1346 struct ctl_table *table)
1346{ 1347{
1347 struct ctl_table_header *head; 1348 struct ctl_table_header *head;
1348 struct ctl_table *ref, *test; 1349 struct ctl_table *ref, *test;
@@ -1350,8 +1351,8 @@ static struct ctl_table *sysctl_check_lookup(struct ctl_table *table)
1350 1351
1351 depth = sysctl_depth(table); 1352 depth = sysctl_depth(table);
1352 1353
1353 for (head = sysctl_head_next(NULL); head; 1354 for (head = __sysctl_head_next(namespaces, NULL); head;
1354 head = sysctl_head_next(head)) { 1355 head = __sysctl_head_next(namespaces, head)) {
1355 cur_depth = depth; 1356 cur_depth = depth;
1356 ref = head->ctl_table; 1357 ref = head->ctl_table;
1357repeat: 1358repeat:
@@ -1396,13 +1397,14 @@ static void set_fail(const char **fail, struct ctl_table *table, const char *str
1396 *fail = str; 1397 *fail = str;
1397} 1398}
1398 1399
1399static int sysctl_check_dir(struct ctl_table *table) 1400static int sysctl_check_dir(struct nsproxy *namespaces,
1401 struct ctl_table *table)
1400{ 1402{
1401 struct ctl_table *ref; 1403 struct ctl_table *ref;
1402 int error; 1404 int error;
1403 1405
1404 error = 0; 1406 error = 0;
1405 ref = sysctl_check_lookup(table); 1407 ref = sysctl_check_lookup(namespaces, table);
1406 if (ref) { 1408 if (ref) {
1407 int match = 0; 1409 int match = 0;
1408 if ((!table->procname && !ref->procname) || 1410 if ((!table->procname && !ref->procname) ||
@@ -1427,11 +1429,12 @@ static int sysctl_check_dir(struct ctl_table *table)
1427 return error; 1429 return error;
1428} 1430}
1429 1431
1430static void sysctl_check_leaf(struct ctl_table *table, const char **fail) 1432static void sysctl_check_leaf(struct nsproxy *namespaces,
1433 struct ctl_table *table, const char **fail)
1431{ 1434{
1432 struct ctl_table *ref; 1435 struct ctl_table *ref;
1433 1436
1434 ref = sysctl_check_lookup(table); 1437 ref = sysctl_check_lookup(namespaces, table);
1435 if (ref && (ref != table)) 1438 if (ref && (ref != table))
1436 set_fail(fail, table, "Sysctl already exists"); 1439 set_fail(fail, table, "Sysctl already exists");
1437} 1440}
@@ -1455,7 +1458,7 @@ static void sysctl_check_bin_path(struct ctl_table *table, const char **fail)
1455 } 1458 }
1456} 1459}
1457 1460
1458int sysctl_check_table(struct ctl_table *table) 1461int sysctl_check_table(struct nsproxy *namespaces, struct ctl_table *table)
1459{ 1462{
1460 int error = 0; 1463 int error = 0;
1461 for (; table->ctl_name || table->procname; table++) { 1464 for (; table->ctl_name || table->procname; table++) {
@@ -1485,7 +1488,7 @@ int sysctl_check_table(struct ctl_table *table)
1485 set_fail(&fail, table, "Directory with extra1"); 1488 set_fail(&fail, table, "Directory with extra1");
1486 if (table->extra2) 1489 if (table->extra2)
1487 set_fail(&fail, table, "Directory with extra2"); 1490 set_fail(&fail, table, "Directory with extra2");
1488 if (sysctl_check_dir(table)) 1491 if (sysctl_check_dir(namespaces, table))
1489 set_fail(&fail, table, "Inconsistent directory names"); 1492 set_fail(&fail, table, "Inconsistent directory names");
1490 } else { 1493 } else {
1491 if ((table->strategy == sysctl_data) || 1494 if ((table->strategy == sysctl_data) ||
@@ -1534,7 +1537,7 @@ int sysctl_check_table(struct ctl_table *table)
1534 if (!table->procname && table->proc_handler) 1537 if (!table->procname && table->proc_handler)
1535 set_fail(&fail, table, "proc_handler without procname"); 1538 set_fail(&fail, table, "proc_handler without procname");
1536#endif 1539#endif
1537 sysctl_check_leaf(table, &fail); 1540 sysctl_check_leaf(namespaces, table, &fail);
1538 } 1541 }
1539 sysctl_check_bin_path(table, &fail); 1542 sysctl_check_bin_path(table, &fail);
1540 if (fail) { 1543 if (fail) {
@@ -1542,7 +1545,7 @@ int sysctl_check_table(struct ctl_table *table)
1542 error = -EINVAL; 1545 error = -EINVAL;
1543 } 1546 }
1544 if (table->child) 1547 if (table->child)
1545 error |= sysctl_check_table(table->child); 1548 error |= sysctl_check_table(namespaces, table->child);
1546 } 1549 }
1547 return error; 1550 return error;
1548} 1551}