Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * proc sysctl test driver
0003  *
0004  * Copyright (C) 2017 Luis R. Rodriguez <mcgrof@kernel.org>
0005  *
0006  * This program is free software; you can redistribute it and/or modify it
0007  * under the terms of the GNU General Public License as published by the Free
0008  * Software Foundation; either version 2 of the License, or at your option any
0009  * later version; or, when distributed separately from the Linux kernel or
0010  * when incorporated into other software packages, subject to the following
0011  * license:
0012  *
0013  * This program is free software; you can redistribute it and/or modify it
0014  * under the terms of copyleft-next (version 0.3.1 or later) as published
0015  * at http://copyleft-next.org/.
0016  */
0017 
0018 /*
0019  * This module provides an interface to the proc sysctl interfaces.  This
0020  * driver requires CONFIG_PROC_SYSCTL. It will not normally be loaded by the
0021  * system unless explicitly requested by name. You can also build this driver
0022  * into your kernel.
0023  */
0024 
0025 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0026 
0027 #include <linux/init.h>
0028 #include <linux/list.h>
0029 #include <linux/module.h>
0030 #include <linux/printk.h>
0031 #include <linux/fs.h>
0032 #include <linux/miscdevice.h>
0033 #include <linux/slab.h>
0034 #include <linux/uaccess.h>
0035 #include <linux/async.h>
0036 #include <linux/delay.h>
0037 #include <linux/vmalloc.h>
0038 
0039 static int i_zero;
0040 static int i_one_hundred = 100;
0041 static int match_int_ok = 1;
0042 
0043 struct test_sysctl_data {
0044     int int_0001;
0045     int int_0002;
0046     int int_0003[4];
0047 
0048     int boot_int;
0049 
0050     unsigned int uint_0001;
0051 
0052     char string_0001[65];
0053 
0054 #define SYSCTL_TEST_BITMAP_SIZE 65536
0055     unsigned long *bitmap_0001;
0056 };
0057 
0058 static struct test_sysctl_data test_data = {
0059     .int_0001 = 60,
0060     .int_0002 = 1,
0061 
0062     .int_0003[0] = 0,
0063     .int_0003[1] = 1,
0064     .int_0003[2] = 2,
0065     .int_0003[3] = 3,
0066 
0067     .boot_int = 0,
0068 
0069     .uint_0001 = 314,
0070 
0071     .string_0001 = "(none)",
0072 };
0073 
0074 /* These are all under /proc/sys/debug/test_sysctl/ */
0075 static struct ctl_table test_table[] = {
0076     {
0077         .procname   = "int_0001",
0078         .data       = &test_data.int_0001,
0079         .maxlen     = sizeof(int),
0080         .mode       = 0644,
0081         .proc_handler   = proc_dointvec_minmax,
0082         .extra1     = &i_zero,
0083         .extra2         = &i_one_hundred,
0084     },
0085     {
0086         .procname   = "int_0002",
0087         .data       = &test_data.int_0002,
0088         .maxlen     = sizeof(int),
0089         .mode       = 0644,
0090         .proc_handler   = proc_dointvec,
0091     },
0092     {
0093         .procname   = "int_0003",
0094         .data       = &test_data.int_0003,
0095         .maxlen     = sizeof(test_data.int_0003),
0096         .mode       = 0644,
0097         .proc_handler   = proc_dointvec,
0098     },
0099     {
0100         .procname   = "match_int",
0101         .data       = &match_int_ok,
0102         .maxlen     = sizeof(match_int_ok),
0103         .mode       = 0444,
0104         .proc_handler   = proc_dointvec,
0105     },
0106     {
0107         .procname   = "boot_int",
0108         .data       = &test_data.boot_int,
0109         .maxlen     = sizeof(test_data.boot_int),
0110         .mode       = 0644,
0111         .proc_handler   = proc_dointvec,
0112         .extra1     = SYSCTL_ZERO,
0113         .extra2         = SYSCTL_ONE,
0114     },
0115     {
0116         .procname   = "uint_0001",
0117         .data       = &test_data.uint_0001,
0118         .maxlen     = sizeof(unsigned int),
0119         .mode       = 0644,
0120         .proc_handler   = proc_douintvec,
0121     },
0122     {
0123         .procname   = "string_0001",
0124         .data       = &test_data.string_0001,
0125         .maxlen     = sizeof(test_data.string_0001),
0126         .mode       = 0644,
0127         .proc_handler   = proc_dostring,
0128     },
0129     {
0130         .procname   = "bitmap_0001",
0131         .data       = &test_data.bitmap_0001,
0132         .maxlen     = SYSCTL_TEST_BITMAP_SIZE,
0133         .mode       = 0644,
0134         .proc_handler   = proc_do_large_bitmap,
0135     },
0136     { }
0137 };
0138 
0139 static struct ctl_table_header *test_sysctl_header;
0140 
0141 static int __init test_sysctl_init(void)
0142 {
0143     int i;
0144 
0145     struct {
0146         int defined;
0147         int wanted;
0148     } match_int[] = {
0149         {.defined = *(int *)SYSCTL_ZERO,    .wanted = 0},
0150         {.defined = *(int *)SYSCTL_ONE,     .wanted = 1},
0151         {.defined = *(int *)SYSCTL_TWO,     .wanted = 2},
0152         {.defined = *(int *)SYSCTL_THREE,   .wanted = 3},
0153         {.defined = *(int *)SYSCTL_FOUR,    .wanted = 4},
0154         {.defined = *(int *)SYSCTL_ONE_HUNDRED, .wanted = 100},
0155         {.defined = *(int *)SYSCTL_TWO_HUNDRED, .wanted = 200},
0156         {.defined = *(int *)SYSCTL_ONE_THOUSAND, .wanted = 1000},
0157         {.defined = *(int *)SYSCTL_THREE_THOUSAND, .wanted = 3000},
0158         {.defined = *(int *)SYSCTL_INT_MAX, .wanted = INT_MAX},
0159         {.defined = *(int *)SYSCTL_MAXOLDUID,   .wanted = 65535},
0160         {.defined = *(int *)SYSCTL_NEG_ONE, .wanted = -1},
0161     };
0162 
0163     for (i = 0; i < ARRAY_SIZE(match_int); i++)
0164         if (match_int[i].defined != match_int[i].wanted)
0165             match_int_ok = 0;
0166 
0167     test_data.bitmap_0001 = kzalloc(SYSCTL_TEST_BITMAP_SIZE/8, GFP_KERNEL);
0168     if (!test_data.bitmap_0001)
0169         return -ENOMEM;
0170     test_sysctl_header = register_sysctl("debug/test_sysctl", test_table);
0171     if (!test_sysctl_header) {
0172         kfree(test_data.bitmap_0001);
0173         return -ENOMEM;
0174     }
0175     return 0;
0176 }
0177 module_init(test_sysctl_init);
0178 
0179 static void __exit test_sysctl_exit(void)
0180 {
0181     kfree(test_data.bitmap_0001);
0182     if (test_sysctl_header)
0183         unregister_sysctl_table(test_sysctl_header);
0184 }
0185 
0186 module_exit(test_sysctl_exit);
0187 
0188 MODULE_AUTHOR("Luis R. Rodriguez <mcgrof@kernel.org>");
0189 MODULE_LICENSE("GPL");