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