xref: /kernel/linux/linux-5.10/lib/test_sysctl.c (revision 8c2ecf20)
18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * proc sysctl test driver
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Copyright (C) 2017 Luis R. Rodriguez <mcgrof@kernel.org>
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * This program is free software; you can redistribute it and/or modify it
78c2ecf20Sopenharmony_ci * under the terms of the GNU General Public License as published by the Free
88c2ecf20Sopenharmony_ci * Software Foundation; either version 2 of the License, or at your option any
98c2ecf20Sopenharmony_ci * later version; or, when distributed separately from the Linux kernel or
108c2ecf20Sopenharmony_ci * when incorporated into other software packages, subject to the following
118c2ecf20Sopenharmony_ci * license:
128c2ecf20Sopenharmony_ci *
138c2ecf20Sopenharmony_ci * This program is free software; you can redistribute it and/or modify it
148c2ecf20Sopenharmony_ci * under the terms of copyleft-next (version 0.3.1 or later) as published
158c2ecf20Sopenharmony_ci * at http://copyleft-next.org/.
168c2ecf20Sopenharmony_ci */
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci/*
198c2ecf20Sopenharmony_ci * This module provides an interface to the proc sysctl interfaces.  This
208c2ecf20Sopenharmony_ci * driver requires CONFIG_PROC_SYSCTL. It will not normally be loaded by the
218c2ecf20Sopenharmony_ci * system unless explicitly requested by name. You can also build this driver
228c2ecf20Sopenharmony_ci * into your kernel.
238c2ecf20Sopenharmony_ci */
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci#include <linux/init.h>
288c2ecf20Sopenharmony_ci#include <linux/list.h>
298c2ecf20Sopenharmony_ci#include <linux/module.h>
308c2ecf20Sopenharmony_ci#include <linux/printk.h>
318c2ecf20Sopenharmony_ci#include <linux/fs.h>
328c2ecf20Sopenharmony_ci#include <linux/miscdevice.h>
338c2ecf20Sopenharmony_ci#include <linux/slab.h>
348c2ecf20Sopenharmony_ci#include <linux/uaccess.h>
358c2ecf20Sopenharmony_ci#include <linux/async.h>
368c2ecf20Sopenharmony_ci#include <linux/delay.h>
378c2ecf20Sopenharmony_ci#include <linux/vmalloc.h>
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_cistatic int i_zero;
408c2ecf20Sopenharmony_cistatic int i_one_hundred = 100;
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_cistruct test_sysctl_data {
438c2ecf20Sopenharmony_ci	int int_0001;
448c2ecf20Sopenharmony_ci	int int_0002;
458c2ecf20Sopenharmony_ci	int int_0003[4];
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci	int boot_int;
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci	unsigned int uint_0001;
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	char string_0001[65];
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci#define SYSCTL_TEST_BITMAP_SIZE	65536
548c2ecf20Sopenharmony_ci	unsigned long *bitmap_0001;
558c2ecf20Sopenharmony_ci};
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_cistatic struct test_sysctl_data test_data = {
588c2ecf20Sopenharmony_ci	.int_0001 = 60,
598c2ecf20Sopenharmony_ci	.int_0002 = 1,
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci	.int_0003[0] = 0,
628c2ecf20Sopenharmony_ci	.int_0003[1] = 1,
638c2ecf20Sopenharmony_ci	.int_0003[2] = 2,
648c2ecf20Sopenharmony_ci	.int_0003[3] = 3,
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	.boot_int = 0,
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	.uint_0001 = 314,
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci	.string_0001 = "(none)",
718c2ecf20Sopenharmony_ci};
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci/* These are all under /proc/sys/debug/test_sysctl/ */
748c2ecf20Sopenharmony_cistatic struct ctl_table test_table[] = {
758c2ecf20Sopenharmony_ci	{
768c2ecf20Sopenharmony_ci		.procname	= "int_0001",
778c2ecf20Sopenharmony_ci		.data		= &test_data.int_0001,
788c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
798c2ecf20Sopenharmony_ci		.mode		= 0644,
808c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
818c2ecf20Sopenharmony_ci		.extra1		= &i_zero,
828c2ecf20Sopenharmony_ci		.extra2         = &i_one_hundred,
838c2ecf20Sopenharmony_ci	},
848c2ecf20Sopenharmony_ci	{
858c2ecf20Sopenharmony_ci		.procname	= "int_0002",
868c2ecf20Sopenharmony_ci		.data		= &test_data.int_0002,
878c2ecf20Sopenharmony_ci		.maxlen		= sizeof(int),
888c2ecf20Sopenharmony_ci		.mode		= 0644,
898c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec,
908c2ecf20Sopenharmony_ci	},
918c2ecf20Sopenharmony_ci	{
928c2ecf20Sopenharmony_ci		.procname	= "int_0003",
938c2ecf20Sopenharmony_ci		.data		= &test_data.int_0003,
948c2ecf20Sopenharmony_ci		.maxlen		= sizeof(test_data.int_0003),
958c2ecf20Sopenharmony_ci		.mode		= 0644,
968c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec,
978c2ecf20Sopenharmony_ci	},
988c2ecf20Sopenharmony_ci	{
998c2ecf20Sopenharmony_ci		.procname	= "boot_int",
1008c2ecf20Sopenharmony_ci		.data		= &test_data.boot_int,
1018c2ecf20Sopenharmony_ci		.maxlen		= sizeof(test_data.boot_int),
1028c2ecf20Sopenharmony_ci		.mode		= 0644,
1038c2ecf20Sopenharmony_ci		.proc_handler	= proc_dointvec,
1048c2ecf20Sopenharmony_ci		.extra1		= SYSCTL_ZERO,
1058c2ecf20Sopenharmony_ci		.extra2         = SYSCTL_ONE,
1068c2ecf20Sopenharmony_ci	},
1078c2ecf20Sopenharmony_ci	{
1088c2ecf20Sopenharmony_ci		.procname	= "uint_0001",
1098c2ecf20Sopenharmony_ci		.data		= &test_data.uint_0001,
1108c2ecf20Sopenharmony_ci		.maxlen		= sizeof(unsigned int),
1118c2ecf20Sopenharmony_ci		.mode		= 0644,
1128c2ecf20Sopenharmony_ci		.proc_handler	= proc_douintvec,
1138c2ecf20Sopenharmony_ci	},
1148c2ecf20Sopenharmony_ci	{
1158c2ecf20Sopenharmony_ci		.procname	= "string_0001",
1168c2ecf20Sopenharmony_ci		.data		= &test_data.string_0001,
1178c2ecf20Sopenharmony_ci		.maxlen		= sizeof(test_data.string_0001),
1188c2ecf20Sopenharmony_ci		.mode		= 0644,
1198c2ecf20Sopenharmony_ci		.proc_handler	= proc_dostring,
1208c2ecf20Sopenharmony_ci	},
1218c2ecf20Sopenharmony_ci	{
1228c2ecf20Sopenharmony_ci		.procname	= "bitmap_0001",
1238c2ecf20Sopenharmony_ci		.data		= &test_data.bitmap_0001,
1248c2ecf20Sopenharmony_ci		.maxlen		= SYSCTL_TEST_BITMAP_SIZE,
1258c2ecf20Sopenharmony_ci		.mode		= 0644,
1268c2ecf20Sopenharmony_ci		.proc_handler	= proc_do_large_bitmap,
1278c2ecf20Sopenharmony_ci	},
1288c2ecf20Sopenharmony_ci	{ }
1298c2ecf20Sopenharmony_ci};
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_cistatic struct ctl_table test_sysctl_table[] = {
1328c2ecf20Sopenharmony_ci	{
1338c2ecf20Sopenharmony_ci		.procname	= "test_sysctl",
1348c2ecf20Sopenharmony_ci		.maxlen		= 0,
1358c2ecf20Sopenharmony_ci		.mode		= 0555,
1368c2ecf20Sopenharmony_ci		.child		= test_table,
1378c2ecf20Sopenharmony_ci	},
1388c2ecf20Sopenharmony_ci	{ }
1398c2ecf20Sopenharmony_ci};
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_cistatic struct ctl_table test_sysctl_root_table[] = {
1428c2ecf20Sopenharmony_ci	{
1438c2ecf20Sopenharmony_ci		.procname	= "debug",
1448c2ecf20Sopenharmony_ci		.maxlen		= 0,
1458c2ecf20Sopenharmony_ci		.mode		= 0555,
1468c2ecf20Sopenharmony_ci		.child		= test_sysctl_table,
1478c2ecf20Sopenharmony_ci	},
1488c2ecf20Sopenharmony_ci	{ }
1498c2ecf20Sopenharmony_ci};
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_cistatic struct ctl_table_header *test_sysctl_header;
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_cistatic int __init test_sysctl_init(void)
1548c2ecf20Sopenharmony_ci{
1558c2ecf20Sopenharmony_ci	test_data.bitmap_0001 = kzalloc(SYSCTL_TEST_BITMAP_SIZE/8, GFP_KERNEL);
1568c2ecf20Sopenharmony_ci	if (!test_data.bitmap_0001)
1578c2ecf20Sopenharmony_ci		return -ENOMEM;
1588c2ecf20Sopenharmony_ci	test_sysctl_header = register_sysctl_table(test_sysctl_root_table);
1598c2ecf20Sopenharmony_ci	if (!test_sysctl_header) {
1608c2ecf20Sopenharmony_ci		kfree(test_data.bitmap_0001);
1618c2ecf20Sopenharmony_ci		return -ENOMEM;
1628c2ecf20Sopenharmony_ci	}
1638c2ecf20Sopenharmony_ci	return 0;
1648c2ecf20Sopenharmony_ci}
1658c2ecf20Sopenharmony_cimodule_init(test_sysctl_init);
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_cistatic void __exit test_sysctl_exit(void)
1688c2ecf20Sopenharmony_ci{
1698c2ecf20Sopenharmony_ci	kfree(test_data.bitmap_0001);
1708c2ecf20Sopenharmony_ci	if (test_sysctl_header)
1718c2ecf20Sopenharmony_ci		unregister_sysctl_table(test_sysctl_header);
1728c2ecf20Sopenharmony_ci}
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_cimodule_exit(test_sysctl_exit);
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_ciMODULE_AUTHOR("Luis R. Rodriguez <mcgrof@kernel.org>");
1778c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL");
178