Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * linux/net/sunrpc/sysctl.c
0004  *
0005  * Sysctl interface to sunrpc module.
0006  *
0007  * I would prefer to register the sunrpc table below sys/net, but that's
0008  * impossible at the moment.
0009  */
0010 
0011 #include <linux/types.h>
0012 #include <linux/linkage.h>
0013 #include <linux/ctype.h>
0014 #include <linux/fs.h>
0015 #include <linux/sysctl.h>
0016 #include <linux/module.h>
0017 
0018 #include <linux/uaccess.h>
0019 #include <linux/sunrpc/types.h>
0020 #include <linux/sunrpc/sched.h>
0021 #include <linux/sunrpc/stats.h>
0022 #include <linux/sunrpc/svc_xprt.h>
0023 
0024 #include "netns.h"
0025 
0026 /*
0027  * Declare the debug flags here
0028  */
0029 unsigned int    rpc_debug;
0030 EXPORT_SYMBOL_GPL(rpc_debug);
0031 
0032 unsigned int    nfs_debug;
0033 EXPORT_SYMBOL_GPL(nfs_debug);
0034 
0035 unsigned int    nfsd_debug;
0036 EXPORT_SYMBOL_GPL(nfsd_debug);
0037 
0038 unsigned int    nlm_debug;
0039 EXPORT_SYMBOL_GPL(nlm_debug);
0040 
0041 #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
0042 
0043 static struct ctl_table_header *sunrpc_table_header;
0044 static struct ctl_table sunrpc_table[];
0045 
0046 void
0047 rpc_register_sysctl(void)
0048 {
0049     if (!sunrpc_table_header)
0050         sunrpc_table_header = register_sysctl_table(sunrpc_table);
0051 }
0052 
0053 void
0054 rpc_unregister_sysctl(void)
0055 {
0056     if (sunrpc_table_header) {
0057         unregister_sysctl_table(sunrpc_table_header);
0058         sunrpc_table_header = NULL;
0059     }
0060 }
0061 
0062 static int proc_do_xprt(struct ctl_table *table, int write,
0063             void *buffer, size_t *lenp, loff_t *ppos)
0064 {
0065     char tmpbuf[256];
0066     ssize_t len;
0067 
0068     if (write || *ppos) {
0069         *lenp = 0;
0070         return 0;
0071     }
0072     len = svc_print_xprts(tmpbuf, sizeof(tmpbuf));
0073     len = memory_read_from_buffer(buffer, *lenp, ppos, tmpbuf, len);
0074 
0075     if (len < 0) {
0076         *lenp = 0;
0077         return -EINVAL;
0078     }
0079     *lenp = len;
0080     return 0;
0081 }
0082 
0083 static int
0084 proc_dodebug(struct ctl_table *table, int write, void *buffer, size_t *lenp,
0085          loff_t *ppos)
0086 {
0087     char        tmpbuf[20], *s = NULL;
0088     char *p;
0089     unsigned int    value;
0090     size_t      left, len;
0091 
0092     if ((*ppos && !write) || !*lenp) {
0093         *lenp = 0;
0094         return 0;
0095     }
0096 
0097     left = *lenp;
0098 
0099     if (write) {
0100         p = buffer;
0101         while (left && isspace(*p)) {
0102             left--;
0103             p++;
0104         }
0105         if (!left)
0106             goto done;
0107 
0108         if (left > sizeof(tmpbuf) - 1)
0109             return -EINVAL;
0110         memcpy(tmpbuf, p, left);
0111         tmpbuf[left] = '\0';
0112 
0113         value = simple_strtol(tmpbuf, &s, 0);
0114         if (s) {
0115             left -= (s - tmpbuf);
0116             if (left && !isspace(*s))
0117                 return -EINVAL;
0118             while (left && isspace(*s)) {
0119                 left--;
0120                 s++;
0121             }
0122         } else
0123             left = 0;
0124         *(unsigned int *) table->data = value;
0125         /* Display the RPC tasks on writing to rpc_debug */
0126         if (strcmp(table->procname, "rpc_debug") == 0)
0127             rpc_show_tasks(&init_net);
0128     } else {
0129         len = sprintf(tmpbuf, "0x%04x", *(unsigned int *) table->data);
0130         if (len > left)
0131             len = left;
0132         memcpy(buffer, tmpbuf, len);
0133         if ((left -= len) > 0) {
0134             *((char *)buffer + len) = '\n';
0135             left--;
0136         }
0137     }
0138 
0139 done:
0140     *lenp -= left;
0141     *ppos += *lenp;
0142     return 0;
0143 }
0144 
0145 
0146 static struct ctl_table debug_table[] = {
0147     {
0148         .procname   = "rpc_debug",
0149         .data       = &rpc_debug,
0150         .maxlen     = sizeof(int),
0151         .mode       = 0644,
0152         .proc_handler   = proc_dodebug
0153     },
0154     {
0155         .procname   = "nfs_debug",
0156         .data       = &nfs_debug,
0157         .maxlen     = sizeof(int),
0158         .mode       = 0644,
0159         .proc_handler   = proc_dodebug
0160     },
0161     {
0162         .procname   = "nfsd_debug",
0163         .data       = &nfsd_debug,
0164         .maxlen     = sizeof(int),
0165         .mode       = 0644,
0166         .proc_handler   = proc_dodebug
0167     },
0168     {
0169         .procname   = "nlm_debug",
0170         .data       = &nlm_debug,
0171         .maxlen     = sizeof(int),
0172         .mode       = 0644,
0173         .proc_handler   = proc_dodebug
0174     },
0175     {
0176         .procname   = "transports",
0177         .maxlen     = 256,
0178         .mode       = 0444,
0179         .proc_handler   = proc_do_xprt,
0180     },
0181     { }
0182 };
0183 
0184 static struct ctl_table sunrpc_table[] = {
0185     {
0186         .procname   = "sunrpc",
0187         .mode       = 0555,
0188         .child      = debug_table
0189     },
0190     { }
0191 };
0192 
0193 #endif