Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  test_sysctl.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-or-later OR copyleft-next-0.3.1
/*
 * proc sysctl test driver
 *
 * Copyright (C) 2017 Luis R. Rodriguez <mcgrof@kernel.org>
 */


/*
 * This module provides an interface to 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;
static int match_int_ok = 1;

enum {
 TEST_H_SETUP_NODE,
 TEST_H_MNT,
 TEST_H_MNTERROR,
 TEST_H_EMPTY_ADD,
 TEST_H_EMPTY,
 TEST_H_U8,
 TEST_H_SIZE /* Always at the end */
};

static struct ctl_table_header *ctl_headers[TEST_H_SIZE] = {};
struct test_sysctl_data {
 int int_0001;
 int int_0002;
 int int_0003[4];

 int boot_int;

 unsigned int uint_0001;

 char string_0001[65];

#define SYSCTL_TEST_BITMAP_SIZE 65536
 unsigned long *bitmap_0001;
};

static struct test_sysctl_data test_data = {
 .int_0001 = 60,
 .int_0002 = 1,

 .int_0003[0] = 0,
 .int_0003[1] = 1,
 .int_0003[2] = 2,
 .int_0003[3] = 3,

 .boot_int = 0,

 .uint_0001 = 314,

 .string_0001 = "(none)",
};

/* These are all under /proc/sys/debug/test_sysctl/ */
static const 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,
 },
 {
  .procname = "int_0002",
  .data  = &test_data.int_0002,
  .maxlen  = sizeof(int),
  .mode  = 0644,
  .proc_handler = proc_dointvec,
 },
 {
  .procname = "int_0003",
  .data  = &test_data.int_0003,
  .maxlen  = sizeof(test_data.int_0003),
  .mode  = 0644,
  .proc_handler = proc_dointvec,
 },
 {
  .procname = "match_int",
  .data  = &match_int_ok,
  .maxlen  = sizeof(match_int_ok),
  .mode  = 0444,
  .proc_handler = proc_dointvec,
 },
 {
  .procname = "boot_int",
  .data  = &test_data.boot_int,
  .maxlen  = sizeof(test_data.boot_int),
  .mode  = 0644,
  .proc_handler = proc_dointvec,
  .extra1  = SYSCTL_ZERO,
  .extra2         = SYSCTL_ONE,
 },
 {
  .procname = "uint_0001",
  .data  = &test_data.uint_0001,
  .maxlen  = sizeof(unsigned int),
  .mode  = 0644,
  .proc_handler = proc_douintvec,
 },
 {
  .procname = "string_0001",
  .data  = &test_data.string_0001,
  .maxlen  = sizeof(test_data.string_0001),
  .mode  = 0644,
  .proc_handler = proc_dostring,
 },
 {
  .procname = "bitmap_0001",
  .data  = &test_data.bitmap_0001,
  .maxlen  = SYSCTL_TEST_BITMAP_SIZE,
  .mode  = 0644,
  .proc_handler = proc_do_large_bitmap,
 },
};

static void test_sysctl_calc_match_int_ok(void)
{
 int i;

 struct {
  int defined;
  int wanted;
 } match_int[] = {
  {.defined = *(int *)SYSCTL_ZERO, .wanted = 0},
  {.defined = *(int *)SYSCTL_ONE,  .wanted = 1},
  {.defined = *(int *)SYSCTL_TWO,  .wanted = 2},
  {.defined = *(int *)SYSCTL_THREE, .wanted = 3},
  {.defined = *(int *)SYSCTL_FOUR, .wanted = 4},
  {.defined = *(int *)SYSCTL_ONE_HUNDRED, .wanted = 100},
  {.defined = *(int *)SYSCTL_TWO_HUNDRED, .wanted = 200},
  {.defined = *(int *)SYSCTL_ONE_THOUSAND, .wanted = 1000},
  {.defined = *(int *)SYSCTL_THREE_THOUSAND, .wanted = 3000},
  {.defined = *(int *)SYSCTL_INT_MAX, .wanted = INT_MAX},
  {.defined = *(int *)SYSCTL_MAXOLDUID, .wanted = 65535},
  {.defined = *(int *)SYSCTL_NEG_ONE, .wanted = -1},
 };

 for (i = 0; i < ARRAY_SIZE(match_int); i++)
  if (match_int[i].defined != match_int[i].wanted)
   match_int_ok = 0;
}

static int test_sysctl_setup_node_tests(void)
{
 test_sysctl_calc_match_int_ok();
 test_data.bitmap_0001 = kzalloc(SYSCTL_TEST_BITMAP_SIZE/8, GFP_KERNEL);
 if (!test_data.bitmap_0001)
  return -ENOMEM;
 ctl_headers[TEST_H_SETUP_NODE] = register_sysctl("debug/test_sysctl", test_table);
 if (!ctl_headers[TEST_H_SETUP_NODE]) {
  kfree(test_data.bitmap_0001);
  return -ENOMEM;
 }

 return 0;
}

/* Used to test that unregister actually removes the directory */
static const struct ctl_table test_table_unregister[] = {
 {
  .procname = "unregister_error",
  .data  = &test_data.int_0001,
  .maxlen  = sizeof(int),
  .mode  = 0644,
  .proc_handler = proc_dointvec_minmax,
 },
};

static int test_sysctl_run_unregister_nested(void)
{
 struct ctl_table_header *unregister;

 unregister = register_sysctl("debug/test_sysctl/unregister_error",
       test_table_unregister);
 if (!unregister)
  return -ENOMEM;

 unregister_sysctl_table(unregister);
 return 0;
}

static int test_sysctl_run_register_mount_point(void)
{
 ctl_headers[TEST_H_MNT]
  = register_sysctl_mount_point("debug/test_sysctl/mnt");
 if (!ctl_headers[TEST_H_MNT])
  return -ENOMEM;

 ctl_headers[TEST_H_MNTERROR]
  = register_sysctl("debug/test_sysctl/mnt/mnt_error",
      test_table_unregister);
 /*
 * Don't check the result.:
 * If it fails (expected behavior), return 0.
 * If successful (missbehavior of register mount point), we want to see
 * mnt_error when we run the sysctl test script
 */


 return 0;
}

static const struct ctl_table test_table_empty[] = { };

static int test_sysctl_run_register_empty(void)
{
 /* Tets that an empty dir can be created */
 ctl_headers[TEST_H_EMPTY_ADD]
  = register_sysctl("debug/test_sysctl/empty_add", test_table_empty);
 if (!ctl_headers[TEST_H_EMPTY_ADD])
  return -ENOMEM;

 /* Test that register on top of an empty dir works */
 ctl_headers[TEST_H_EMPTY]
  = register_sysctl("debug/test_sysctl/empty_add/empty", test_table_empty);
 if (!ctl_headers[TEST_H_EMPTY])
  return -ENOMEM;

 return 0;
}

static const struct ctl_table table_u8_over[] = {
 {
  .procname = "u8_over",
  .data  = &test_data.uint_0001,
  .maxlen  = sizeof(u8),
  .mode  = 0644,
  .proc_handler = proc_dou8vec_minmax,
  .extra1  = SYSCTL_FOUR,
  .extra2  = SYSCTL_ONE_THOUSAND,
 },
};

static const struct ctl_table table_u8_under[] = {
 {
  .procname = "u8_under",
  .data  = &test_data.uint_0001,
  .maxlen  = sizeof(u8),
  .mode  = 0644,
  .proc_handler = proc_dou8vec_minmax,
  .extra1  = SYSCTL_NEG_ONE,
  .extra2  = SYSCTL_ONE_HUNDRED,
 },
};

static const struct ctl_table table_u8_valid[] = {
 {
  .procname = "u8_valid",
  .data  = &test_data.uint_0001,
  .maxlen  = sizeof(u8),
  .mode  = 0644,
  .proc_handler = proc_dou8vec_minmax,
  .extra1  = SYSCTL_ZERO,
  .extra2  = SYSCTL_TWO_HUNDRED,
 },
};

static int test_sysctl_register_u8_extra(void)
{
 /* should fail because it's over */
 ctl_headers[TEST_H_U8]
  = register_sysctl("debug/test_sysctl", table_u8_over);
 if (ctl_headers[TEST_H_U8])
  return -ENOMEM;

 /* should fail because it's under */
 ctl_headers[TEST_H_U8]
  = register_sysctl("debug/test_sysctl", table_u8_under);
 if (ctl_headers[TEST_H_U8])
  return -ENOMEM;

 /* should not fail because it's valid */
 ctl_headers[TEST_H_U8]
  = register_sysctl("debug/test_sysctl", table_u8_valid);
 if (!ctl_headers[TEST_H_U8])
  return -ENOMEM;

 return 0;
}

static int __init test_sysctl_init(void)
{
 int err = 0;

 int (*func_array[])(void) = {
  test_sysctl_setup_node_tests,
  test_sysctl_run_unregister_nested,
  test_sysctl_run_register_mount_point,
  test_sysctl_run_register_empty,
  test_sysctl_register_u8_extra
 };

 for (int i = 0; !err && i < ARRAY_SIZE(func_array); i++)
  err = func_array[i]();

 return err;
}
module_init(test_sysctl_init);

static void __exit test_sysctl_exit(void)
{
 kfree(test_data.bitmap_0001);
 for (int i = 0; i < TEST_H_SIZE; i++) {
  if (ctl_headers[i])
   unregister_sysctl_table(ctl_headers[i]);
 }
}

module_exit(test_sysctl_exit);

MODULE_AUTHOR("Luis R. Rodriguez ");
MODULE_DESCRIPTION("proc sysctl test driver");
MODULE_LICENSE("GPL");

Messung V0.5
C=96 H=100 G=97

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge