xref: /OK3568_Linux_fs/kernel/lib/test_sysctl.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * proc sysctl test driver
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Copyright (C) 2017 Luis R. Rodriguez <mcgrof@kernel.org>
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * This program is free software; you can redistribute it and/or modify it
7*4882a593Smuzhiyun  * under the terms of the GNU General Public License as published by the Free
8*4882a593Smuzhiyun  * Software Foundation; either version 2 of the License, or at your option any
9*4882a593Smuzhiyun  * later version; or, when distributed separately from the Linux kernel or
10*4882a593Smuzhiyun  * when incorporated into other software packages, subject to the following
11*4882a593Smuzhiyun  * license:
12*4882a593Smuzhiyun  *
13*4882a593Smuzhiyun  * This program is free software; you can redistribute it and/or modify it
14*4882a593Smuzhiyun  * under the terms of copyleft-next (version 0.3.1 or later) as published
15*4882a593Smuzhiyun  * at http://copyleft-next.org/.
16*4882a593Smuzhiyun  */
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun /*
19*4882a593Smuzhiyun  * This module provides an interface to the proc sysctl interfaces.  This
20*4882a593Smuzhiyun  * driver requires CONFIG_PROC_SYSCTL. It will not normally be loaded by the
21*4882a593Smuzhiyun  * system unless explicitly requested by name. You can also build this driver
22*4882a593Smuzhiyun  * into your kernel.
23*4882a593Smuzhiyun  */
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #include <linux/init.h>
28*4882a593Smuzhiyun #include <linux/list.h>
29*4882a593Smuzhiyun #include <linux/module.h>
30*4882a593Smuzhiyun #include <linux/printk.h>
31*4882a593Smuzhiyun #include <linux/fs.h>
32*4882a593Smuzhiyun #include <linux/miscdevice.h>
33*4882a593Smuzhiyun #include <linux/slab.h>
34*4882a593Smuzhiyun #include <linux/uaccess.h>
35*4882a593Smuzhiyun #include <linux/async.h>
36*4882a593Smuzhiyun #include <linux/delay.h>
37*4882a593Smuzhiyun #include <linux/vmalloc.h>
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun static int i_zero;
40*4882a593Smuzhiyun static int i_one_hundred = 100;
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun struct test_sysctl_data {
43*4882a593Smuzhiyun 	int int_0001;
44*4882a593Smuzhiyun 	int int_0002;
45*4882a593Smuzhiyun 	int int_0003[4];
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun 	int boot_int;
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun 	unsigned int uint_0001;
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun 	char string_0001[65];
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun #define SYSCTL_TEST_BITMAP_SIZE	65536
54*4882a593Smuzhiyun 	unsigned long *bitmap_0001;
55*4882a593Smuzhiyun };
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun static struct test_sysctl_data test_data = {
58*4882a593Smuzhiyun 	.int_0001 = 60,
59*4882a593Smuzhiyun 	.int_0002 = 1,
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 	.int_0003[0] = 0,
62*4882a593Smuzhiyun 	.int_0003[1] = 1,
63*4882a593Smuzhiyun 	.int_0003[2] = 2,
64*4882a593Smuzhiyun 	.int_0003[3] = 3,
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	.boot_int = 0,
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun 	.uint_0001 = 314,
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun 	.string_0001 = "(none)",
71*4882a593Smuzhiyun };
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun /* These are all under /proc/sys/debug/test_sysctl/ */
74*4882a593Smuzhiyun static struct ctl_table test_table[] = {
75*4882a593Smuzhiyun 	{
76*4882a593Smuzhiyun 		.procname	= "int_0001",
77*4882a593Smuzhiyun 		.data		= &test_data.int_0001,
78*4882a593Smuzhiyun 		.maxlen		= sizeof(int),
79*4882a593Smuzhiyun 		.mode		= 0644,
80*4882a593Smuzhiyun 		.proc_handler	= proc_dointvec_minmax,
81*4882a593Smuzhiyun 		.extra1		= &i_zero,
82*4882a593Smuzhiyun 		.extra2         = &i_one_hundred,
83*4882a593Smuzhiyun 	},
84*4882a593Smuzhiyun 	{
85*4882a593Smuzhiyun 		.procname	= "int_0002",
86*4882a593Smuzhiyun 		.data		= &test_data.int_0002,
87*4882a593Smuzhiyun 		.maxlen		= sizeof(int),
88*4882a593Smuzhiyun 		.mode		= 0644,
89*4882a593Smuzhiyun 		.proc_handler	= proc_dointvec,
90*4882a593Smuzhiyun 	},
91*4882a593Smuzhiyun 	{
92*4882a593Smuzhiyun 		.procname	= "int_0003",
93*4882a593Smuzhiyun 		.data		= &test_data.int_0003,
94*4882a593Smuzhiyun 		.maxlen		= sizeof(test_data.int_0003),
95*4882a593Smuzhiyun 		.mode		= 0644,
96*4882a593Smuzhiyun 		.proc_handler	= proc_dointvec,
97*4882a593Smuzhiyun 	},
98*4882a593Smuzhiyun 	{
99*4882a593Smuzhiyun 		.procname	= "boot_int",
100*4882a593Smuzhiyun 		.data		= &test_data.boot_int,
101*4882a593Smuzhiyun 		.maxlen		= sizeof(test_data.boot_int),
102*4882a593Smuzhiyun 		.mode		= 0644,
103*4882a593Smuzhiyun 		.proc_handler	= proc_dointvec,
104*4882a593Smuzhiyun 		.extra1		= SYSCTL_ZERO,
105*4882a593Smuzhiyun 		.extra2         = SYSCTL_ONE,
106*4882a593Smuzhiyun 	},
107*4882a593Smuzhiyun 	{
108*4882a593Smuzhiyun 		.procname	= "uint_0001",
109*4882a593Smuzhiyun 		.data		= &test_data.uint_0001,
110*4882a593Smuzhiyun 		.maxlen		= sizeof(unsigned int),
111*4882a593Smuzhiyun 		.mode		= 0644,
112*4882a593Smuzhiyun 		.proc_handler	= proc_douintvec,
113*4882a593Smuzhiyun 	},
114*4882a593Smuzhiyun 	{
115*4882a593Smuzhiyun 		.procname	= "string_0001",
116*4882a593Smuzhiyun 		.data		= &test_data.string_0001,
117*4882a593Smuzhiyun 		.maxlen		= sizeof(test_data.string_0001),
118*4882a593Smuzhiyun 		.mode		= 0644,
119*4882a593Smuzhiyun 		.proc_handler	= proc_dostring,
120*4882a593Smuzhiyun 	},
121*4882a593Smuzhiyun 	{
122*4882a593Smuzhiyun 		.procname	= "bitmap_0001",
123*4882a593Smuzhiyun 		.data		= &test_data.bitmap_0001,
124*4882a593Smuzhiyun 		.maxlen		= SYSCTL_TEST_BITMAP_SIZE,
125*4882a593Smuzhiyun 		.mode		= 0644,
126*4882a593Smuzhiyun 		.proc_handler	= proc_do_large_bitmap,
127*4882a593Smuzhiyun 	},
128*4882a593Smuzhiyun 	{ }
129*4882a593Smuzhiyun };
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun static struct ctl_table test_sysctl_table[] = {
132*4882a593Smuzhiyun 	{
133*4882a593Smuzhiyun 		.procname	= "test_sysctl",
134*4882a593Smuzhiyun 		.maxlen		= 0,
135*4882a593Smuzhiyun 		.mode		= 0555,
136*4882a593Smuzhiyun 		.child		= test_table,
137*4882a593Smuzhiyun 	},
138*4882a593Smuzhiyun 	{ }
139*4882a593Smuzhiyun };
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun static struct ctl_table test_sysctl_root_table[] = {
142*4882a593Smuzhiyun 	{
143*4882a593Smuzhiyun 		.procname	= "debug",
144*4882a593Smuzhiyun 		.maxlen		= 0,
145*4882a593Smuzhiyun 		.mode		= 0555,
146*4882a593Smuzhiyun 		.child		= test_sysctl_table,
147*4882a593Smuzhiyun 	},
148*4882a593Smuzhiyun 	{ }
149*4882a593Smuzhiyun };
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun static struct ctl_table_header *test_sysctl_header;
152*4882a593Smuzhiyun 
test_sysctl_init(void)153*4882a593Smuzhiyun static int __init test_sysctl_init(void)
154*4882a593Smuzhiyun {
155*4882a593Smuzhiyun 	test_data.bitmap_0001 = kzalloc(SYSCTL_TEST_BITMAP_SIZE/8, GFP_KERNEL);
156*4882a593Smuzhiyun 	if (!test_data.bitmap_0001)
157*4882a593Smuzhiyun 		return -ENOMEM;
158*4882a593Smuzhiyun 	test_sysctl_header = register_sysctl_table(test_sysctl_root_table);
159*4882a593Smuzhiyun 	if (!test_sysctl_header) {
160*4882a593Smuzhiyun 		kfree(test_data.bitmap_0001);
161*4882a593Smuzhiyun 		return -ENOMEM;
162*4882a593Smuzhiyun 	}
163*4882a593Smuzhiyun 	return 0;
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun module_init(test_sysctl_init);
166*4882a593Smuzhiyun 
test_sysctl_exit(void)167*4882a593Smuzhiyun static void __exit test_sysctl_exit(void)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun 	kfree(test_data.bitmap_0001);
170*4882a593Smuzhiyun 	if (test_sysctl_header)
171*4882a593Smuzhiyun 		unregister_sysctl_table(test_sysctl_header);
172*4882a593Smuzhiyun }
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun module_exit(test_sysctl_exit);
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun MODULE_AUTHOR("Luis R. Rodriguez <mcgrof@kernel.org>");
177*4882a593Smuzhiyun MODULE_LICENSE("GPL");
178