11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * linux/net/sunrpc/sysctl.c
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Sysctl interface to sunrpc module.
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * I would prefer to register the sunrpc table below sys/net, but that's
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * impossible at the moment.
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h>
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/linkage.h>
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ctype.h>
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/fs.h>
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/sysctl.h>
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/uaccess.h>
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/sunrpc/types.h>
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/sunrpc/sched.h>
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/sunrpc/stats.h>
21dc9a16e49dbba3dd042e6aec5d9a7929e099a89bTom Tucker#include <linux/sunrpc/svc_xprt.h>
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2370abc49b4f4a4ef04a6bd9852edbd047b480bed7Stanislav Kinsbursky#include "netns.h"
2470abc49b4f4a4ef04a6bd9852edbd047b480bed7Stanislav Kinsbursky
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Declare the debug flags here
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsunsigned int	rpc_debug;
29e8914c65f7f8d4e8701b8e78a12b714872ea0402Trond MyklebustEXPORT_SYMBOL_GPL(rpc_debug);
30a6eaf8bdf9308b51ec84e358915fc65400029519Trond Myklebust
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsunsigned int	nfs_debug;
32e8914c65f7f8d4e8701b8e78a12b714872ea0402Trond MyklebustEXPORT_SYMBOL_GPL(nfs_debug);
33a6eaf8bdf9308b51ec84e358915fc65400029519Trond Myklebust
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsunsigned int	nfsd_debug;
35e8914c65f7f8d4e8701b8e78a12b714872ea0402Trond MyklebustEXPORT_SYMBOL_GPL(nfsd_debug);
36a6eaf8bdf9308b51ec84e358915fc65400029519Trond Myklebust
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsunsigned int	nlm_debug;
38e8914c65f7f8d4e8701b8e78a12b714872ea0402Trond MyklebustEXPORT_SYMBOL_GPL(nlm_debug);
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef RPC_DEBUG
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct ctl_table_header *sunrpc_table_header;
43fe2c6338fd2c6f383c4d4164262f35c8f3708e1fJoe Perchesstatic struct ctl_table sunrpc_table[];
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsrpc_register_sysctl(void)
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
482b1bec5f52fec033ed0026e7d85f641e20e1cbb9Eric W. Biederman	if (!sunrpc_table_header)
490b4d414714f0d2f922d39424b0c5c82ad900a381Eric W. Biederman		sunrpc_table_header = register_sysctl_table(sunrpc_table);
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsrpc_unregister_sysctl(void)
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (sunrpc_table_header) {
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		unregister_sysctl_table(sunrpc_table_header);
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sunrpc_table_header = NULL;
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
61fe2c6338fd2c6f383c4d4164262f35c8f3708e1fJoe Perchesstatic int proc_do_xprt(struct ctl_table *table, int write,
62dc9a16e49dbba3dd042e6aec5d9a7929e099a89bTom Tucker			void __user *buffer, size_t *lenp, loff_t *ppos)
63dc9a16e49dbba3dd042e6aec5d9a7929e099a89bTom Tucker{
64dc9a16e49dbba3dd042e6aec5d9a7929e099a89bTom Tucker	char tmpbuf[256];
6527df6f25ff218072e0e879a96beeb398a79cdbc8Cyrill Gorcunov	size_t len;
6627df6f25ff218072e0e879a96beeb398a79cdbc8Cyrill Gorcunov
67dc9a16e49dbba3dd042e6aec5d9a7929e099a89bTom Tucker	if ((*ppos && !write) || !*lenp) {
68dc9a16e49dbba3dd042e6aec5d9a7929e099a89bTom Tucker		*lenp = 0;
69dc9a16e49dbba3dd042e6aec5d9a7929e099a89bTom Tucker		return 0;
70dc9a16e49dbba3dd042e6aec5d9a7929e099a89bTom Tucker	}
7127df6f25ff218072e0e879a96beeb398a79cdbc8Cyrill Gorcunov	len = svc_print_xprts(tmpbuf, sizeof(tmpbuf));
7227df6f25ff218072e0e879a96beeb398a79cdbc8Cyrill Gorcunov	return simple_read_from_buffer(buffer, *lenp, ppos, tmpbuf, len);
73dc9a16e49dbba3dd042e6aec5d9a7929e099a89bTom Tucker}
74dc9a16e49dbba3dd042e6aec5d9a7929e099a89bTom Tucker
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
76fe2c6338fd2c6f383c4d4164262f35c8f3708e1fJoe Perchesproc_dodebug(struct ctl_table *table, int write,
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				void __user *buffer, size_t *lenp, loff_t *ppos)
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char		tmpbuf[20], c, *s;
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char __user *p;
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int	value;
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	size_t		left, len;
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((*ppos && !write) || !*lenp) {
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		*lenp = 0;
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	left = *lenp;
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (write) {
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!access_ok(VERIFY_READ, buffer, left))
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return -EFAULT;
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		p = buffer;
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		while (left && __get_user(c, p) >= 0 && isspace(c))
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			left--, p++;
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!left)
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto done;
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (left > sizeof(tmpbuf) - 1)
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return -EINVAL;
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (copy_from_user(tmpbuf, p, left))
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return -EFAULT;
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		tmpbuf[left] = '\0';
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (s = tmpbuf, value = 0; '0' <= *s && *s <= '9'; s++, left--)
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			value = 10 * value + (*s - '0');
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (*s && !isspace(*s))
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return -EINVAL;
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		while (left && isspace(*s))
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			left--, s++;
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		*(unsigned int *) table->data = value;
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Display the RPC tasks on writing to rpc_debug */
114bc2a3f86f46569fb091792867ce67c9ab24dfd0fJ. Bruce Fields		if (strcmp(table->procname, "rpc_debug") == 0)
11570abc49b4f4a4ef04a6bd9852edbd047b480bed7Stanislav Kinsbursky			rpc_show_tasks(&init_net);
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!access_ok(VERIFY_WRITE, buffer, left))
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return -EFAULT;
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		len = sprintf(tmpbuf, "%d", *(unsigned int *) table->data);
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (len > left)
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			len = left;
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (__copy_to_user(buffer, tmpbuf, len))
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return -EFAULT;
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((left -= len) > 0) {
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (put_user('\n', (char __user *)buffer + len))
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return -EFAULT;
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			left--;
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdone:
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*lenp -= left;
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*ppos += *lenp;
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
137a246b0105bbd9a70a698f69baae2042996f2a0e9Chuck Lever
138fe2c6338fd2c6f383c4d4164262f35c8f3708e1fJoe Perchesstatic struct ctl_table debug_table[] = {
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.procname	= "rpc_debug",
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.data		= &rpc_debug,
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.maxlen		= sizeof(int),
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.mode		= 0644,
1446d4561110a3e9fa742aeec6717248a491dfb1878Eric W. Biederman		.proc_handler	= proc_dodebug
145cca5172a7ec10dfdb0b787cd8e9d5b0b8f179793YOSHIFUJI Hideaki	},
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.procname	= "nfs_debug",
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.data		= &nfs_debug,
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.maxlen		= sizeof(int),
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.mode		= 0644,
1516d4561110a3e9fa742aeec6717248a491dfb1878Eric W. Biederman		.proc_handler	= proc_dodebug
152cca5172a7ec10dfdb0b787cd8e9d5b0b8f179793YOSHIFUJI Hideaki	},
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.procname	= "nfsd_debug",
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.data		= &nfsd_debug,
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.maxlen		= sizeof(int),
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.mode		= 0644,
1586d4561110a3e9fa742aeec6717248a491dfb1878Eric W. Biederman		.proc_handler	= proc_dodebug
159cca5172a7ec10dfdb0b787cd8e9d5b0b8f179793YOSHIFUJI Hideaki	},
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.procname	= "nlm_debug",
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.data		= &nlm_debug,
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.maxlen		= sizeof(int),
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.mode		= 0644,
1656d4561110a3e9fa742aeec6717248a491dfb1878Eric W. Biederman		.proc_handler	= proc_dodebug
166cca5172a7ec10dfdb0b787cd8e9d5b0b8f179793YOSHIFUJI Hideaki	},
167dc9a16e49dbba3dd042e6aec5d9a7929e099a89bTom Tucker	{
168dc9a16e49dbba3dd042e6aec5d9a7929e099a89bTom Tucker		.procname	= "transports",
169dc9a16e49dbba3dd042e6aec5d9a7929e099a89bTom Tucker		.maxlen		= 256,
170dc9a16e49dbba3dd042e6aec5d9a7929e099a89bTom Tucker		.mode		= 0444,
1716d4561110a3e9fa742aeec6717248a491dfb1878Eric W. Biederman		.proc_handler	= proc_do_xprt,
172dc9a16e49dbba3dd042e6aec5d9a7929e099a89bTom Tucker	},
173f8572d8f2a2ba75408b97dc24ef47c83671795d7Eric W. Biederman	{ }
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
176fe2c6338fd2c6f383c4d4164262f35c8f3708e1fJoe Perchesstatic struct ctl_table sunrpc_table[] = {
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.procname	= "sunrpc",
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.mode		= 0555,
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.child		= debug_table
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	},
182f8572d8f2a2ba75408b97dc24ef47c83671795d7Eric W. Biederman	{ }
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
186