Blame view

lib/test_sysctl.c 3.29 KB
9308f2f9e   Luis R. Rodriguez   test_sysctl: add ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
  /*
   * proc sysctl test driver
   *
   * Copyright (C) 2017 Luis R. Rodriguez <mcgrof@kernel.org>
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License as published by the Free
   * Software Foundation; either version 2 of the License, or at your option any
   * later version; or, when distributed separately from the Linux kernel or
   * when incorporated into other software packages, subject to the following
   * license:
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of copyleft-next (version 0.3.1 or later) as published
   * at http://copyleft-next.org/.
   */
  
  /*
   * This module provides an interface to the the proc sysctl interfaces.  This
   * driver requires CONFIG_PROC_SYSCTL. It will not normally be loaded by the
   * system unless explicitly requested by name. You can also build this driver
   * into your kernel.
   */
  
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  
  #include <linux/init.h>
  #include <linux/list.h>
  #include <linux/module.h>
  #include <linux/printk.h>
  #include <linux/fs.h>
  #include <linux/miscdevice.h>
  #include <linux/slab.h>
  #include <linux/uaccess.h>
  #include <linux/async.h>
  #include <linux/delay.h>
  #include <linux/vmalloc.h>
  
  static int i_zero;
  static int i_one_hundred = 100;
  
  struct test_sysctl_data {
  	int int_0001;
eb965eda1   Luis R. Rodriguez   test_sysctl: add ...
44
  	int int_0002;
7c43a657a   Luis R. Rodriguez   test_sysctl: test...
45
  	int int_0003[4];
eb965eda1   Luis R. Rodriguez   test_sysctl: add ...
46

2920fad3a   Luis R. Rodriguez   test_sysctl: add ...
47
  	unsigned int uint_0001;
9308f2f9e   Luis R. Rodriguez   test_sysctl: add ...
48
49
50
51
52
  	char string_0001[65];
  };
  
  static struct test_sysctl_data test_data = {
  	.int_0001 = 60,
eb965eda1   Luis R. Rodriguez   test_sysctl: add ...
53
  	.int_0002 = 1,
7c43a657a   Luis R. Rodriguez   test_sysctl: test...
54
55
56
57
  	.int_0003[0] = 0,
  	.int_0003[1] = 1,
  	.int_0003[2] = 2,
  	.int_0003[3] = 3,
2920fad3a   Luis R. Rodriguez   test_sysctl: add ...
58
  	.uint_0001 = 314,
9308f2f9e   Luis R. Rodriguez   test_sysctl: add ...
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  	.string_0001 = "(none)",
  };
  
  /* These are all under /proc/sys/debug/test_sysctl/ */
  static struct ctl_table test_table[] = {
  	{
  		.procname	= "int_0001",
  		.data		= &test_data.int_0001,
  		.maxlen		= sizeof(int),
  		.mode		= 0644,
  		.proc_handler	= proc_dointvec_minmax,
  		.extra1		= &i_zero,
  		.extra2         = &i_one_hundred,
  	},
  	{
eb965eda1   Luis R. Rodriguez   test_sysctl: add ...
74
75
76
77
78
79
80
  		.procname	= "int_0002",
  		.data		= &test_data.int_0002,
  		.maxlen		= sizeof(int),
  		.mode		= 0644,
  		.proc_handler	= proc_dointvec,
  	},
  	{
7c43a657a   Luis R. Rodriguez   test_sysctl: test...
81
82
83
84
85
86
87
  		.procname	= "int_0003",
  		.data		= &test_data.int_0003,
  		.maxlen		= sizeof(test_data.int_0003),
  		.mode		= 0644,
  		.proc_handler	= proc_dointvec,
  	},
  	{
2920fad3a   Luis R. Rodriguez   test_sysctl: add ...
88
89
90
91
92
93
94
  		.procname	= "uint_0001",
  		.data		= &test_data.uint_0001,
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
  		.proc_handler	= proc_douintvec,
  	},
  	{
9308f2f9e   Luis R. Rodriguez   test_sysctl: add ...
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
  		.procname	= "string_0001",
  		.data		= &test_data.string_0001,
  		.maxlen		= sizeof(test_data.string_0001),
  		.mode		= 0644,
  		.proc_handler	= proc_dostring,
  	},
  	{ }
  };
  
  static struct ctl_table test_sysctl_table[] = {
  	{
  		.procname	= "test_sysctl",
  		.maxlen		= 0,
  		.mode		= 0555,
  		.child		= test_table,
  	},
  	{ }
  };
  
  static struct ctl_table test_sysctl_root_table[] = {
  	{
  		.procname	= "debug",
  		.maxlen		= 0,
  		.mode		= 0555,
  		.child		= test_sysctl_table,
  	},
  	{ }
  };
  
  static struct ctl_table_header *test_sysctl_header;
  
  static int __init test_sysctl_init(void)
  {
  	test_sysctl_header = register_sysctl_table(test_sysctl_root_table);
  	if (!test_sysctl_header)
  		return -ENOMEM;
  	return 0;
  }
  late_initcall(test_sysctl_init);
  
  static void __exit test_sysctl_exit(void)
  {
  	if (test_sysctl_header)
  		unregister_sysctl_table(test_sysctl_header);
  }
  
  module_exit(test_sysctl_exit);
  
  MODULE_AUTHOR("Luis R. Rodriguez <mcgrof@kernel.org>");
  MODULE_LICENSE("GPL");