18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * linux/net/sunrpc/sysctl.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Sysctl interface to sunrpc module. 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * I would prefer to register the sunrpc table below sys/net, but that's 88c2ecf20Sopenharmony_ci * impossible at the moment. 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/types.h> 128c2ecf20Sopenharmony_ci#include <linux/linkage.h> 138c2ecf20Sopenharmony_ci#include <linux/ctype.h> 148c2ecf20Sopenharmony_ci#include <linux/fs.h> 158c2ecf20Sopenharmony_ci#include <linux/sysctl.h> 168c2ecf20Sopenharmony_ci#include <linux/module.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#include <linux/uaccess.h> 198c2ecf20Sopenharmony_ci#include <linux/sunrpc/types.h> 208c2ecf20Sopenharmony_ci#include <linux/sunrpc/sched.h> 218c2ecf20Sopenharmony_ci#include <linux/sunrpc/stats.h> 228c2ecf20Sopenharmony_ci#include <linux/sunrpc/svc_xprt.h> 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#include "netns.h" 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci/* 278c2ecf20Sopenharmony_ci * Declare the debug flags here 288c2ecf20Sopenharmony_ci */ 298c2ecf20Sopenharmony_ciunsigned int rpc_debug; 308c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(rpc_debug); 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ciunsigned int nfs_debug; 338c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(nfs_debug); 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ciunsigned int nfsd_debug; 368c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(nfsd_debug); 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ciunsigned int nlm_debug; 398c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(nlm_debug); 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cistatic struct ctl_table_header *sunrpc_table_header; 448c2ecf20Sopenharmony_cistatic struct ctl_table sunrpc_table[]; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_civoid 478c2ecf20Sopenharmony_cirpc_register_sysctl(void) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci if (!sunrpc_table_header) 508c2ecf20Sopenharmony_ci sunrpc_table_header = register_sysctl_table(sunrpc_table); 518c2ecf20Sopenharmony_ci} 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_civoid 548c2ecf20Sopenharmony_cirpc_unregister_sysctl(void) 558c2ecf20Sopenharmony_ci{ 568c2ecf20Sopenharmony_ci if (sunrpc_table_header) { 578c2ecf20Sopenharmony_ci unregister_sysctl_table(sunrpc_table_header); 588c2ecf20Sopenharmony_ci sunrpc_table_header = NULL; 598c2ecf20Sopenharmony_ci } 608c2ecf20Sopenharmony_ci} 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_cistatic int proc_do_xprt(struct ctl_table *table, int write, 638c2ecf20Sopenharmony_ci void *buffer, size_t *lenp, loff_t *ppos) 648c2ecf20Sopenharmony_ci{ 658c2ecf20Sopenharmony_ci char tmpbuf[256]; 668c2ecf20Sopenharmony_ci ssize_t len; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci if (write || *ppos) { 698c2ecf20Sopenharmony_ci *lenp = 0; 708c2ecf20Sopenharmony_ci return 0; 718c2ecf20Sopenharmony_ci } 728c2ecf20Sopenharmony_ci len = svc_print_xprts(tmpbuf, sizeof(tmpbuf)); 738c2ecf20Sopenharmony_ci len = memory_read_from_buffer(buffer, *lenp, ppos, tmpbuf, len); 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci if (len < 0) { 768c2ecf20Sopenharmony_ci *lenp = 0; 778c2ecf20Sopenharmony_ci return -EINVAL; 788c2ecf20Sopenharmony_ci } 798c2ecf20Sopenharmony_ci *lenp = len; 808c2ecf20Sopenharmony_ci return 0; 818c2ecf20Sopenharmony_ci} 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_cistatic int 848c2ecf20Sopenharmony_ciproc_dodebug(struct ctl_table *table, int write, void *buffer, size_t *lenp, 858c2ecf20Sopenharmony_ci loff_t *ppos) 868c2ecf20Sopenharmony_ci{ 878c2ecf20Sopenharmony_ci char tmpbuf[20], *s = NULL; 888c2ecf20Sopenharmony_ci char *p; 898c2ecf20Sopenharmony_ci unsigned int value; 908c2ecf20Sopenharmony_ci size_t left, len; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci if ((*ppos && !write) || !*lenp) { 938c2ecf20Sopenharmony_ci *lenp = 0; 948c2ecf20Sopenharmony_ci return 0; 958c2ecf20Sopenharmony_ci } 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci left = *lenp; 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci if (write) { 1008c2ecf20Sopenharmony_ci p = buffer; 1018c2ecf20Sopenharmony_ci while (left && isspace(*p)) { 1028c2ecf20Sopenharmony_ci left--; 1038c2ecf20Sopenharmony_ci p++; 1048c2ecf20Sopenharmony_ci } 1058c2ecf20Sopenharmony_ci if (!left) 1068c2ecf20Sopenharmony_ci goto done; 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci if (left > sizeof(tmpbuf) - 1) 1098c2ecf20Sopenharmony_ci return -EINVAL; 1108c2ecf20Sopenharmony_ci memcpy(tmpbuf, p, left); 1118c2ecf20Sopenharmony_ci tmpbuf[left] = '\0'; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci value = simple_strtol(tmpbuf, &s, 0); 1148c2ecf20Sopenharmony_ci if (s) { 1158c2ecf20Sopenharmony_ci left -= (s - tmpbuf); 1168c2ecf20Sopenharmony_ci if (left && !isspace(*s)) 1178c2ecf20Sopenharmony_ci return -EINVAL; 1188c2ecf20Sopenharmony_ci while (left && isspace(*s)) { 1198c2ecf20Sopenharmony_ci left--; 1208c2ecf20Sopenharmony_ci s++; 1218c2ecf20Sopenharmony_ci } 1228c2ecf20Sopenharmony_ci } else 1238c2ecf20Sopenharmony_ci left = 0; 1248c2ecf20Sopenharmony_ci *(unsigned int *) table->data = value; 1258c2ecf20Sopenharmony_ci /* Display the RPC tasks on writing to rpc_debug */ 1268c2ecf20Sopenharmony_ci if (strcmp(table->procname, "rpc_debug") == 0) 1278c2ecf20Sopenharmony_ci rpc_show_tasks(&init_net); 1288c2ecf20Sopenharmony_ci } else { 1298c2ecf20Sopenharmony_ci len = sprintf(tmpbuf, "0x%04x", *(unsigned int *) table->data); 1308c2ecf20Sopenharmony_ci if (len > left) 1318c2ecf20Sopenharmony_ci len = left; 1328c2ecf20Sopenharmony_ci memcpy(buffer, tmpbuf, len); 1338c2ecf20Sopenharmony_ci if ((left -= len) > 0) { 1348c2ecf20Sopenharmony_ci *((char *)buffer + len) = '\n'; 1358c2ecf20Sopenharmony_ci left--; 1368c2ecf20Sopenharmony_ci } 1378c2ecf20Sopenharmony_ci } 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_cidone: 1408c2ecf20Sopenharmony_ci *lenp -= left; 1418c2ecf20Sopenharmony_ci *ppos += *lenp; 1428c2ecf20Sopenharmony_ci return 0; 1438c2ecf20Sopenharmony_ci} 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_cistatic struct ctl_table debug_table[] = { 1478c2ecf20Sopenharmony_ci { 1488c2ecf20Sopenharmony_ci .procname = "rpc_debug", 1498c2ecf20Sopenharmony_ci .data = &rpc_debug, 1508c2ecf20Sopenharmony_ci .maxlen = sizeof(int), 1518c2ecf20Sopenharmony_ci .mode = 0644, 1528c2ecf20Sopenharmony_ci .proc_handler = proc_dodebug 1538c2ecf20Sopenharmony_ci }, 1548c2ecf20Sopenharmony_ci { 1558c2ecf20Sopenharmony_ci .procname = "nfs_debug", 1568c2ecf20Sopenharmony_ci .data = &nfs_debug, 1578c2ecf20Sopenharmony_ci .maxlen = sizeof(int), 1588c2ecf20Sopenharmony_ci .mode = 0644, 1598c2ecf20Sopenharmony_ci .proc_handler = proc_dodebug 1608c2ecf20Sopenharmony_ci }, 1618c2ecf20Sopenharmony_ci { 1628c2ecf20Sopenharmony_ci .procname = "nfsd_debug", 1638c2ecf20Sopenharmony_ci .data = &nfsd_debug, 1648c2ecf20Sopenharmony_ci .maxlen = sizeof(int), 1658c2ecf20Sopenharmony_ci .mode = 0644, 1668c2ecf20Sopenharmony_ci .proc_handler = proc_dodebug 1678c2ecf20Sopenharmony_ci }, 1688c2ecf20Sopenharmony_ci { 1698c2ecf20Sopenharmony_ci .procname = "nlm_debug", 1708c2ecf20Sopenharmony_ci .data = &nlm_debug, 1718c2ecf20Sopenharmony_ci .maxlen = sizeof(int), 1728c2ecf20Sopenharmony_ci .mode = 0644, 1738c2ecf20Sopenharmony_ci .proc_handler = proc_dodebug 1748c2ecf20Sopenharmony_ci }, 1758c2ecf20Sopenharmony_ci { 1768c2ecf20Sopenharmony_ci .procname = "transports", 1778c2ecf20Sopenharmony_ci .maxlen = 256, 1788c2ecf20Sopenharmony_ci .mode = 0444, 1798c2ecf20Sopenharmony_ci .proc_handler = proc_do_xprt, 1808c2ecf20Sopenharmony_ci }, 1818c2ecf20Sopenharmony_ci { } 1828c2ecf20Sopenharmony_ci}; 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_cistatic struct ctl_table sunrpc_table[] = { 1858c2ecf20Sopenharmony_ci { 1868c2ecf20Sopenharmony_ci .procname = "sunrpc", 1878c2ecf20Sopenharmony_ci .mode = 0555, 1888c2ecf20Sopenharmony_ci .child = debug_table 1898c2ecf20Sopenharmony_ci }, 1908c2ecf20Sopenharmony_ci { } 1918c2ecf20Sopenharmony_ci}; 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci#endif 194