diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2007-11-30 07:54:00 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:55:17 -0500 |
commit | e51b6ba077791f2f8c876022b37419be7a2ceec3 (patch) | |
tree | 9d8ca18f3239eff84cad5b79b715c332970fa89d /kernel/sysctl_check.c | |
parent | 23eb06de7d2d333a0f7ebba2da663e00c9c9483e (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.c | 25 |
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 | ||
1345 | static struct ctl_table *sysctl_check_lookup(struct ctl_table *table) | 1345 | static 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; |
1357 | repeat: | 1358 | repeat: |
@@ -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 | ||
1399 | static int sysctl_check_dir(struct ctl_table *table) | 1400 | static 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 | ||
1430 | static void sysctl_check_leaf(struct ctl_table *table, const char **fail) | 1432 | static 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 | ||
1458 | int sysctl_check_table(struct ctl_table *table) | 1461 | int 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 | } |