test_sysctl.c 4.6 KB

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