11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * linux/net/sunrpc/sysctl.c 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Sysctl interface to sunrpc module. 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * I would prefer to register the sunrpc table below sys/net, but that's 71da177e4SLinus Torvalds * impossible at the moment. 81da177e4SLinus Torvalds */ 91da177e4SLinus Torvalds 101da177e4SLinus Torvalds #include <linux/config.h> 111da177e4SLinus Torvalds #include <linux/types.h> 121da177e4SLinus Torvalds #include <linux/linkage.h> 131da177e4SLinus Torvalds #include <linux/ctype.h> 141da177e4SLinus Torvalds #include <linux/fs.h> 151da177e4SLinus Torvalds #include <linux/sysctl.h> 161da177e4SLinus Torvalds #include <linux/module.h> 171da177e4SLinus Torvalds 181da177e4SLinus Torvalds #include <asm/uaccess.h> 191da177e4SLinus Torvalds #include <linux/sunrpc/types.h> 201da177e4SLinus Torvalds #include <linux/sunrpc/sched.h> 211da177e4SLinus Torvalds #include <linux/sunrpc/stats.h> 221da177e4SLinus Torvalds #include <linux/sunrpc/xprt.h> 231da177e4SLinus Torvalds 241da177e4SLinus Torvalds /* 251da177e4SLinus Torvalds * Declare the debug flags here 261da177e4SLinus Torvalds */ 271da177e4SLinus Torvalds unsigned int rpc_debug; 281da177e4SLinus Torvalds unsigned int nfs_debug; 291da177e4SLinus Torvalds unsigned int nfsd_debug; 301da177e4SLinus Torvalds unsigned int nlm_debug; 311da177e4SLinus Torvalds 321da177e4SLinus Torvalds #ifdef RPC_DEBUG 331da177e4SLinus Torvalds 341da177e4SLinus Torvalds static struct ctl_table_header *sunrpc_table_header; 351da177e4SLinus Torvalds static ctl_table sunrpc_table[]; 361da177e4SLinus Torvalds 371da177e4SLinus Torvalds void 381da177e4SLinus Torvalds rpc_register_sysctl(void) 391da177e4SLinus Torvalds { 401da177e4SLinus Torvalds if (!sunrpc_table_header) { 411da177e4SLinus Torvalds sunrpc_table_header = register_sysctl_table(sunrpc_table, 1); 421da177e4SLinus Torvalds #ifdef CONFIG_PROC_FS 431da177e4SLinus Torvalds if (sunrpc_table[0].de) 441da177e4SLinus Torvalds sunrpc_table[0].de->owner = THIS_MODULE; 451da177e4SLinus Torvalds #endif 461da177e4SLinus Torvalds } 471da177e4SLinus Torvalds 481da177e4SLinus Torvalds } 491da177e4SLinus Torvalds 501da177e4SLinus Torvalds void 511da177e4SLinus Torvalds rpc_unregister_sysctl(void) 521da177e4SLinus Torvalds { 531da177e4SLinus Torvalds if (sunrpc_table_header) { 541da177e4SLinus Torvalds unregister_sysctl_table(sunrpc_table_header); 551da177e4SLinus Torvalds sunrpc_table_header = NULL; 561da177e4SLinus Torvalds } 571da177e4SLinus Torvalds } 581da177e4SLinus Torvalds 591da177e4SLinus Torvalds static int 601da177e4SLinus Torvalds proc_dodebug(ctl_table *table, int write, struct file *file, 611da177e4SLinus Torvalds void __user *buffer, size_t *lenp, loff_t *ppos) 621da177e4SLinus Torvalds { 631da177e4SLinus Torvalds char tmpbuf[20], c, *s; 641da177e4SLinus Torvalds char __user *p; 651da177e4SLinus Torvalds unsigned int value; 661da177e4SLinus Torvalds size_t left, len; 671da177e4SLinus Torvalds 681da177e4SLinus Torvalds if ((*ppos && !write) || !*lenp) { 691da177e4SLinus Torvalds *lenp = 0; 701da177e4SLinus Torvalds return 0; 711da177e4SLinus Torvalds } 721da177e4SLinus Torvalds 731da177e4SLinus Torvalds left = *lenp; 741da177e4SLinus Torvalds 751da177e4SLinus Torvalds if (write) { 761da177e4SLinus Torvalds if (!access_ok(VERIFY_READ, buffer, left)) 771da177e4SLinus Torvalds return -EFAULT; 781da177e4SLinus Torvalds p = buffer; 791da177e4SLinus Torvalds while (left && __get_user(c, p) >= 0 && isspace(c)) 801da177e4SLinus Torvalds left--, p++; 811da177e4SLinus Torvalds if (!left) 821da177e4SLinus Torvalds goto done; 831da177e4SLinus Torvalds 841da177e4SLinus Torvalds if (left > sizeof(tmpbuf) - 1) 851da177e4SLinus Torvalds return -EINVAL; 861da177e4SLinus Torvalds if (copy_from_user(tmpbuf, p, left)) 871da177e4SLinus Torvalds return -EFAULT; 881da177e4SLinus Torvalds tmpbuf[left] = '\0'; 891da177e4SLinus Torvalds 901da177e4SLinus Torvalds for (s = tmpbuf, value = 0; '0' <= *s && *s <= '9'; s++, left--) 911da177e4SLinus Torvalds value = 10 * value + (*s - '0'); 921da177e4SLinus Torvalds if (*s && !isspace(*s)) 931da177e4SLinus Torvalds return -EINVAL; 941da177e4SLinus Torvalds while (left && isspace(*s)) 951da177e4SLinus Torvalds left--, s++; 961da177e4SLinus Torvalds *(unsigned int *) table->data = value; 971da177e4SLinus Torvalds /* Display the RPC tasks on writing to rpc_debug */ 981da177e4SLinus Torvalds if (table->ctl_name == CTL_RPCDEBUG) { 991da177e4SLinus Torvalds rpc_show_tasks(); 1001da177e4SLinus Torvalds } 1011da177e4SLinus Torvalds } else { 1021da177e4SLinus Torvalds if (!access_ok(VERIFY_WRITE, buffer, left)) 1031da177e4SLinus Torvalds return -EFAULT; 1041da177e4SLinus Torvalds len = sprintf(tmpbuf, "%d", *(unsigned int *) table->data); 1051da177e4SLinus Torvalds if (len > left) 1061da177e4SLinus Torvalds len = left; 1071da177e4SLinus Torvalds if (__copy_to_user(buffer, tmpbuf, len)) 1081da177e4SLinus Torvalds return -EFAULT; 1091da177e4SLinus Torvalds if ((left -= len) > 0) { 1101da177e4SLinus Torvalds if (put_user('\n', (char __user *)buffer + len)) 1111da177e4SLinus Torvalds return -EFAULT; 1121da177e4SLinus Torvalds left--; 1131da177e4SLinus Torvalds } 1141da177e4SLinus Torvalds } 1151da177e4SLinus Torvalds 1161da177e4SLinus Torvalds done: 1171da177e4SLinus Torvalds *lenp -= left; 1181da177e4SLinus Torvalds *ppos += *lenp; 1191da177e4SLinus Torvalds return 0; 1201da177e4SLinus Torvalds } 1211da177e4SLinus Torvalds 1221da177e4SLinus Torvalds static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE; 1231da177e4SLinus Torvalds static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE; 1241da177e4SLinus Torvalds 1251da177e4SLinus Torvalds static ctl_table debug_table[] = { 1261da177e4SLinus Torvalds { 1271da177e4SLinus Torvalds .ctl_name = CTL_RPCDEBUG, 1281da177e4SLinus Torvalds .procname = "rpc_debug", 1291da177e4SLinus Torvalds .data = &rpc_debug, 1301da177e4SLinus Torvalds .maxlen = sizeof(int), 1311da177e4SLinus Torvalds .mode = 0644, 1321da177e4SLinus Torvalds .proc_handler = &proc_dodebug 1331da177e4SLinus Torvalds }, 1341da177e4SLinus Torvalds { 1351da177e4SLinus Torvalds .ctl_name = CTL_NFSDEBUG, 1361da177e4SLinus Torvalds .procname = "nfs_debug", 1371da177e4SLinus Torvalds .data = &nfs_debug, 1381da177e4SLinus Torvalds .maxlen = sizeof(int), 1391da177e4SLinus Torvalds .mode = 0644, 1401da177e4SLinus Torvalds .proc_handler = &proc_dodebug 1411da177e4SLinus Torvalds }, 1421da177e4SLinus Torvalds { 1431da177e4SLinus Torvalds .ctl_name = CTL_NFSDDEBUG, 1441da177e4SLinus Torvalds .procname = "nfsd_debug", 1451da177e4SLinus Torvalds .data = &nfsd_debug, 1461da177e4SLinus Torvalds .maxlen = sizeof(int), 1471da177e4SLinus Torvalds .mode = 0644, 1481da177e4SLinus Torvalds .proc_handler = &proc_dodebug 1491da177e4SLinus Torvalds }, 1501da177e4SLinus Torvalds { 1511da177e4SLinus Torvalds .ctl_name = CTL_NLMDEBUG, 1521da177e4SLinus Torvalds .procname = "nlm_debug", 1531da177e4SLinus Torvalds .data = &nlm_debug, 1541da177e4SLinus Torvalds .maxlen = sizeof(int), 1551da177e4SLinus Torvalds .mode = 0644, 1561da177e4SLinus Torvalds .proc_handler = &proc_dodebug 1571da177e4SLinus Torvalds }, 1581da177e4SLinus Torvalds { 1591da177e4SLinus Torvalds .ctl_name = CTL_SLOTTABLE_UDP, 1601da177e4SLinus Torvalds .procname = "udp_slot_table_entries", 1611da177e4SLinus Torvalds .data = &xprt_udp_slot_table_entries, 1621da177e4SLinus Torvalds .maxlen = sizeof(unsigned int), 1631da177e4SLinus Torvalds .mode = 0644, 1641da177e4SLinus Torvalds .proc_handler = &proc_dointvec_minmax, 1651da177e4SLinus Torvalds .strategy = &sysctl_intvec, 1661da177e4SLinus Torvalds .extra1 = &min_slot_table_size, 1671da177e4SLinus Torvalds .extra2 = &max_slot_table_size 1681da177e4SLinus Torvalds }, 1691da177e4SLinus Torvalds { 1701da177e4SLinus Torvalds .ctl_name = CTL_SLOTTABLE_TCP, 1711da177e4SLinus Torvalds .procname = "tcp_slot_table_entries", 1721da177e4SLinus Torvalds .data = &xprt_tcp_slot_table_entries, 1731da177e4SLinus Torvalds .maxlen = sizeof(unsigned int), 1741da177e4SLinus Torvalds .mode = 0644, 1751da177e4SLinus Torvalds .proc_handler = &proc_dointvec_minmax, 1761da177e4SLinus Torvalds .strategy = &sysctl_intvec, 1771da177e4SLinus Torvalds .extra1 = &min_slot_table_size, 1781da177e4SLinus Torvalds .extra2 = &max_slot_table_size 1791da177e4SLinus Torvalds }, 1801da177e4SLinus Torvalds { .ctl_name = 0 } 1811da177e4SLinus Torvalds }; 1821da177e4SLinus Torvalds 1831da177e4SLinus Torvalds static ctl_table sunrpc_table[] = { 1841da177e4SLinus Torvalds { 1851da177e4SLinus Torvalds .ctl_name = CTL_SUNRPC, 1861da177e4SLinus Torvalds .procname = "sunrpc", 1871da177e4SLinus Torvalds .mode = 0555, 1881da177e4SLinus Torvalds .child = debug_table 1891da177e4SLinus Torvalds }, 1901da177e4SLinus Torvalds { .ctl_name = 0 } 1911da177e4SLinus Torvalds }; 1921da177e4SLinus Torvalds 1931da177e4SLinus Torvalds #endif 194