xref: /linux/lib/test_sysctl.c (revision 57b19468b369c5f70068540d698ea2a5f4598945)
19308f2f9SLuis R. Rodriguez /*
29308f2f9SLuis R. Rodriguez  * proc sysctl test driver
39308f2f9SLuis R. Rodriguez  *
49308f2f9SLuis R. Rodriguez  * Copyright (C) 2017 Luis R. Rodriguez <mcgrof@kernel.org>
59308f2f9SLuis R. Rodriguez  *
69308f2f9SLuis R. Rodriguez  * This program is free software; you can redistribute it and/or modify it
79308f2f9SLuis R. Rodriguez  * under the terms of the GNU General Public License as published by the Free
89308f2f9SLuis R. Rodriguez  * Software Foundation; either version 2 of the License, or at your option any
99308f2f9SLuis R. Rodriguez  * later version; or, when distributed separately from the Linux kernel or
109308f2f9SLuis R. Rodriguez  * when incorporated into other software packages, subject to the following
119308f2f9SLuis R. Rodriguez  * license:
129308f2f9SLuis R. Rodriguez  *
139308f2f9SLuis R. Rodriguez  * This program is free software; you can redistribute it and/or modify it
149308f2f9SLuis R. Rodriguez  * under the terms of copyleft-next (version 0.3.1 or later) as published
159308f2f9SLuis R. Rodriguez  * at http://copyleft-next.org/.
169308f2f9SLuis R. Rodriguez  */
179308f2f9SLuis R. Rodriguez 
189308f2f9SLuis R. Rodriguez /*
192d046981SRandy Dunlap  * This module provides an interface to the proc sysctl interfaces.  This
209308f2f9SLuis R. Rodriguez  * driver requires CONFIG_PROC_SYSCTL. It will not normally be loaded by the
219308f2f9SLuis R. Rodriguez  * system unless explicitly requested by name. You can also build this driver
229308f2f9SLuis R. Rodriguez  * into your kernel.
239308f2f9SLuis R. Rodriguez  */
249308f2f9SLuis R. Rodriguez 
259308f2f9SLuis R. Rodriguez #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
269308f2f9SLuis R. Rodriguez 
279308f2f9SLuis R. Rodriguez #include <linux/init.h>
289308f2f9SLuis R. Rodriguez #include <linux/list.h>
299308f2f9SLuis R. Rodriguez #include <linux/module.h>
309308f2f9SLuis R. Rodriguez #include <linux/printk.h>
319308f2f9SLuis R. Rodriguez #include <linux/fs.h>
329308f2f9SLuis R. Rodriguez #include <linux/miscdevice.h>
339308f2f9SLuis R. Rodriguez #include <linux/slab.h>
349308f2f9SLuis R. Rodriguez #include <linux/uaccess.h>
359308f2f9SLuis R. Rodriguez #include <linux/async.h>
369308f2f9SLuis R. Rodriguez #include <linux/delay.h>
379308f2f9SLuis R. Rodriguez #include <linux/vmalloc.h>
389308f2f9SLuis R. Rodriguez 
399308f2f9SLuis R. Rodriguez static int i_zero;
409308f2f9SLuis R. Rodriguez static int i_one_hundred = 100;
41*57b19468STonghao Zhang static int match_int_ok = 1;
429308f2f9SLuis R. Rodriguez 
439308f2f9SLuis R. Rodriguez struct test_sysctl_data {
449308f2f9SLuis R. Rodriguez 	int int_0001;
45eb965edaSLuis R. Rodriguez 	int int_0002;
467c43a657SLuis R. Rodriguez 	int int_0003[4];
47eb965edaSLuis R. Rodriguez 
484f2f682dSVlastimil Babka 	int boot_int;
494f2f682dSVlastimil Babka 
502920fad3SLuis R. Rodriguez 	unsigned int uint_0001;
512920fad3SLuis R. Rodriguez 
529308f2f9SLuis R. Rodriguez 	char string_0001[65];
532ea622b8SEric Sandeen 
542ea622b8SEric Sandeen #define SYSCTL_TEST_BITMAP_SIZE	65536
552ea622b8SEric Sandeen 	unsigned long *bitmap_0001;
569308f2f9SLuis R. Rodriguez };
579308f2f9SLuis R. Rodriguez 
589308f2f9SLuis R. Rodriguez static struct test_sysctl_data test_data = {
599308f2f9SLuis R. Rodriguez 	.int_0001 = 60,
60eb965edaSLuis R. Rodriguez 	.int_0002 = 1,
61eb965edaSLuis R. Rodriguez 
627c43a657SLuis R. Rodriguez 	.int_0003[0] = 0,
637c43a657SLuis R. Rodriguez 	.int_0003[1] = 1,
647c43a657SLuis R. Rodriguez 	.int_0003[2] = 2,
657c43a657SLuis R. Rodriguez 	.int_0003[3] = 3,
667c43a657SLuis R. Rodriguez 
674f2f682dSVlastimil Babka 	.boot_int = 0,
684f2f682dSVlastimil Babka 
692920fad3SLuis R. Rodriguez 	.uint_0001 = 314,
702920fad3SLuis R. Rodriguez 
719308f2f9SLuis R. Rodriguez 	.string_0001 = "(none)",
729308f2f9SLuis R. Rodriguez };
739308f2f9SLuis R. Rodriguez 
749308f2f9SLuis R. Rodriguez /* These are all under /proc/sys/debug/test_sysctl/ */
759308f2f9SLuis R. Rodriguez static struct ctl_table test_table[] = {
769308f2f9SLuis R. Rodriguez 	{
779308f2f9SLuis R. Rodriguez 		.procname	= "int_0001",
789308f2f9SLuis R. Rodriguez 		.data		= &test_data.int_0001,
799308f2f9SLuis R. Rodriguez 		.maxlen		= sizeof(int),
809308f2f9SLuis R. Rodriguez 		.mode		= 0644,
819308f2f9SLuis R. Rodriguez 		.proc_handler	= proc_dointvec_minmax,
829308f2f9SLuis R. Rodriguez 		.extra1		= &i_zero,
839308f2f9SLuis R. Rodriguez 		.extra2         = &i_one_hundred,
849308f2f9SLuis R. Rodriguez 	},
859308f2f9SLuis R. Rodriguez 	{
86eb965edaSLuis R. Rodriguez 		.procname	= "int_0002",
87eb965edaSLuis R. Rodriguez 		.data		= &test_data.int_0002,
88eb965edaSLuis R. Rodriguez 		.maxlen		= sizeof(int),
89eb965edaSLuis R. Rodriguez 		.mode		= 0644,
90eb965edaSLuis R. Rodriguez 		.proc_handler	= proc_dointvec,
91eb965edaSLuis R. Rodriguez 	},
92eb965edaSLuis R. Rodriguez 	{
937c43a657SLuis R. Rodriguez 		.procname	= "int_0003",
947c43a657SLuis R. Rodriguez 		.data		= &test_data.int_0003,
957c43a657SLuis R. Rodriguez 		.maxlen		= sizeof(test_data.int_0003),
967c43a657SLuis R. Rodriguez 		.mode		= 0644,
977c43a657SLuis R. Rodriguez 		.proc_handler	= proc_dointvec,
987c43a657SLuis R. Rodriguez 	},
997c43a657SLuis R. Rodriguez 	{
100*57b19468STonghao Zhang 		.procname	= "match_int",
101*57b19468STonghao Zhang 		.data		= &match_int_ok,
102*57b19468STonghao Zhang 		.maxlen		= sizeof(match_int_ok),
103*57b19468STonghao Zhang 		.mode		= 0444,
104*57b19468STonghao Zhang 		.proc_handler	= proc_dointvec,
105*57b19468STonghao Zhang 	},
106*57b19468STonghao Zhang 	{
1074f2f682dSVlastimil Babka 		.procname	= "boot_int",
1084f2f682dSVlastimil Babka 		.data		= &test_data.boot_int,
1094f2f682dSVlastimil Babka 		.maxlen		= sizeof(test_data.boot_int),
1104f2f682dSVlastimil Babka 		.mode		= 0644,
1114f2f682dSVlastimil Babka 		.proc_handler	= proc_dointvec,
1124f2f682dSVlastimil Babka 		.extra1		= SYSCTL_ZERO,
1134f2f682dSVlastimil Babka 		.extra2         = SYSCTL_ONE,
1144f2f682dSVlastimil Babka 	},
1154f2f682dSVlastimil Babka 	{
1162920fad3SLuis R. Rodriguez 		.procname	= "uint_0001",
1172920fad3SLuis R. Rodriguez 		.data		= &test_data.uint_0001,
1182920fad3SLuis R. Rodriguez 		.maxlen		= sizeof(unsigned int),
1192920fad3SLuis R. Rodriguez 		.mode		= 0644,
1202920fad3SLuis R. Rodriguez 		.proc_handler	= proc_douintvec,
1212920fad3SLuis R. Rodriguez 	},
1222920fad3SLuis R. Rodriguez 	{
1239308f2f9SLuis R. Rodriguez 		.procname	= "string_0001",
1249308f2f9SLuis R. Rodriguez 		.data		= &test_data.string_0001,
1259308f2f9SLuis R. Rodriguez 		.maxlen		= sizeof(test_data.string_0001),
1269308f2f9SLuis R. Rodriguez 		.mode		= 0644,
1279308f2f9SLuis R. Rodriguez 		.proc_handler	= proc_dostring,
1289308f2f9SLuis R. Rodriguez 	},
1292ea622b8SEric Sandeen 	{
1302ea622b8SEric Sandeen 		.procname	= "bitmap_0001",
1312ea622b8SEric Sandeen 		.data		= &test_data.bitmap_0001,
1322ea622b8SEric Sandeen 		.maxlen		= SYSCTL_TEST_BITMAP_SIZE,
1332ea622b8SEric Sandeen 		.mode		= 0644,
1342ea622b8SEric Sandeen 		.proc_handler	= proc_do_large_bitmap,
1352ea622b8SEric Sandeen 	},
1369308f2f9SLuis R. Rodriguez 	{ }
1379308f2f9SLuis R. Rodriguez };
1389308f2f9SLuis R. Rodriguez 
1399308f2f9SLuis R. Rodriguez static struct ctl_table_header *test_sysctl_header;
1409308f2f9SLuis R. Rodriguez 
1419308f2f9SLuis R. Rodriguez static int __init test_sysctl_init(void)
1429308f2f9SLuis R. Rodriguez {
143*57b19468STonghao Zhang 	int i;
144*57b19468STonghao Zhang 
145*57b19468STonghao Zhang 	struct {
146*57b19468STonghao Zhang 		int defined;
147*57b19468STonghao Zhang 		int wanted;
148*57b19468STonghao Zhang 	} match_int[] = {
149*57b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_ZERO,	.wanted = 0},
150*57b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_ONE,		.wanted = 1},
151*57b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_TWO,		.wanted = 2},
152*57b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_THREE,	.wanted = 3},
153*57b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_FOUR,	.wanted = 4},
154*57b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_ONE_HUNDRED, .wanted = 100},
155*57b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_TWO_HUNDRED,	.wanted = 200},
156*57b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_ONE_THOUSAND, .wanted = 1000},
157*57b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_THREE_THOUSAND, .wanted = 3000},
158*57b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_INT_MAX,	.wanted = INT_MAX},
159*57b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_MAXOLDUID,	.wanted = 65535},
160*57b19468STonghao Zhang 		{.defined = *(int *)SYSCTL_NEG_ONE,	.wanted = -1},
161*57b19468STonghao Zhang 	};
162*57b19468STonghao Zhang 
163*57b19468STonghao Zhang 	for (i = 0; i < ARRAY_SIZE(match_int); i++)
164*57b19468STonghao Zhang 		if (match_int[i].defined != match_int[i].wanted)
165*57b19468STonghao Zhang 			match_int_ok = 0;
166*57b19468STonghao Zhang 
1672ea622b8SEric Sandeen 	test_data.bitmap_0001 = kzalloc(SYSCTL_TEST_BITMAP_SIZE/8, GFP_KERNEL);
1682ea622b8SEric Sandeen 	if (!test_data.bitmap_0001)
1699308f2f9SLuis R. Rodriguez 		return -ENOMEM;
17004bc883cSLuis Chamberlain 	test_sysctl_header = register_sysctl("debug/test_sysctl", test_table);
1712ea622b8SEric Sandeen 	if (!test_sysctl_header) {
1722ea622b8SEric Sandeen 		kfree(test_data.bitmap_0001);
1732ea622b8SEric Sandeen 		return -ENOMEM;
1742ea622b8SEric Sandeen 	}
1759308f2f9SLuis R. Rodriguez 	return 0;
1769308f2f9SLuis R. Rodriguez }
1772f56f845SMasami Hiramatsu module_init(test_sysctl_init);
1789308f2f9SLuis R. Rodriguez 
1799308f2f9SLuis R. Rodriguez static void __exit test_sysctl_exit(void)
1809308f2f9SLuis R. Rodriguez {
1812ea622b8SEric Sandeen 	kfree(test_data.bitmap_0001);
1829308f2f9SLuis R. Rodriguez 	if (test_sysctl_header)
1839308f2f9SLuis R. Rodriguez 		unregister_sysctl_table(test_sysctl_header);
1849308f2f9SLuis R. Rodriguez }
1859308f2f9SLuis R. Rodriguez 
1869308f2f9SLuis R. Rodriguez module_exit(test_sysctl_exit);
1879308f2f9SLuis R. Rodriguez 
1889308f2f9SLuis R. Rodriguez MODULE_AUTHOR("Luis R. Rodriguez <mcgrof@kernel.org>");
1899308f2f9SLuis R. Rodriguez MODULE_LICENSE("GPL");
190