Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'akpm' (patches from Andrew)

Merge even more updates from Andrew Morton:

- a few leftovers

- fault-injector rework

- add a module loader test driver

* emailed patches from Andrew Morton <akpm@linux-foundation.org>:
kmod: throttle kmod thread limit
kmod: add test driver to stress test the module loader
MAINTAINERS: give kmod some maintainer love
xtensa: use generic fb.h
fault-inject: add /proc/<pid>/fail-nth
fault-inject: simplify access check for fail-nth
fault-inject: make fail-nth read/write interface symmetric
fault-inject: parse as natural 1-based value for fail-nth write interface
fault-inject: automatically detect the number base for fail-nth write interface
kernel/watchdog.c: use better pr_fmt prefix
MAINTAINERS: move the befs tree to kernel.org
lib/atomic64_test.c: add a test that atomic64_inc_not_zero() returns an int
mm: fix overflow check in expand_upwards()

+1969 -62
+11 -10
Documentation/fault-injection/fault-injection.txt
··· 136 136 137 137 o proc entries 138 138 139 - - /proc/self/task/<current-tid>/fail-nth: 139 + - /proc/<pid>/fail-nth: 140 + - /proc/self/task/<tid>/fail-nth: 140 141 141 - Write to this file of integer N makes N-th call in the current task fail 142 - (N is 0-based). Read from this file returns a single char 'Y' or 'N' 143 - that says if the fault setup with a previous write to this file was 144 - injected or not, and disables the fault if it wasn't yet injected. 142 + Write to this file of integer N makes N-th call in the task fail. 143 + Read from this file returns a integer value. A value of '0' indicates 144 + that the fault setup with a previous write to this file was injected. 145 + A positive integer N indicates that the fault wasn't yet injected. 145 146 Note that this file enables all types of faults (slab, futex, etc). 146 147 This setting takes precedence over all other generic debugfs settings 147 148 like probability, interval, times, etc. But per-capability settings ··· 321 320 system("echo N > /sys/kernel/debug/failslab/ignore-gfp-wait"); 322 321 sprintf(buf, "/proc/self/task/%ld/fail-nth", syscall(SYS_gettid)); 323 322 fail_nth = open(buf, O_RDWR); 324 - for (i = 0;; i++) { 323 + for (i = 1;; i++) { 325 324 sprintf(buf, "%d", i); 326 325 write(fail_nth, buf, strlen(buf)); 327 326 res = socketpair(AF_LOCAL, SOCK_STREAM, 0, fds); 328 327 err = errno; 329 - read(fail_nth, buf, 1); 328 + pread(fail_nth, buf, sizeof(buf), 0); 330 329 if (res == 0) { 331 330 close(fds[0]); 332 331 close(fds[1]); 333 332 } 334 - printf("%d-th fault %c: res=%d/%d\n", i, buf[0], res, err); 335 - if (buf[0] != 'Y') 333 + printf("%d-th fault %c: res=%d/%d\n", i, atoi(buf) ? 'N' : 'Y', 334 + res, err); 335 + if (atoi(buf)) 336 336 break; 337 337 } 338 338 return 0; ··· 341 339 342 340 An example output: 343 341 344 - 0-th fault Y: res=-1/23 345 342 1-th fault Y: res=-1/23 346 343 2-th fault Y: res=-1/23 347 344 3-th fault Y: res=-1/12
+11 -2
MAINTAINERS
··· 2516 2516 F: drivers/media/platform/sti/delta 2517 2517 2518 2518 BEFS FILE SYSTEM 2519 - M: Luis de Bethencourt <luisbg@osg.samsung.com> 2519 + M: Luis de Bethencourt <luisbg@kernel.org> 2520 2520 M: Salah Triki <salah.triki@gmail.com> 2521 2521 S: Maintained 2522 - T: git git://github.com/luisbg/linux-befs.git 2522 + T: git git://git.kernel.org/pub/scm/linux/kernel/git/luisbg/linux-befs.git 2523 2523 F: Documentation/filesystems/befs.txt 2524 2524 F: fs/befs/ 2525 2525 ··· 7553 7553 F: include/linux/kmemleak.h 7554 7554 F: mm/kmemleak.c 7555 7555 F: mm/kmemleak-test.c 7556 + 7557 + KMOD MODULE USERMODE HELPER 7558 + M: "Luis R. Rodriguez" <mcgrof@kernel.org> 7559 + L: linux-kernel@vger.kernel.org 7560 + S: Maintained 7561 + F: kernel/kmod.c 7562 + F: include/linux/kmod.h 7563 + F: lib/test_kmod.c 7564 + F: tools/testing/selftests/kmod/ 7556 7565 7557 7566 KPROBES 7558 7567 M: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
+1
arch/xtensa/include/asm/Kbuild
··· 5 5 generic-y += emergency-restart.h 6 6 generic-y += exec.h 7 7 generic-y += extable.h 8 + generic-y += fb.h 8 9 generic-y += hardirq.h 9 10 generic-y += irq_regs.h 10 11 generic-y += irq_work.h
-12
arch/xtensa/include/asm/fb.h
··· 1 - #ifndef _ASM_FB_H_ 2 - #define _ASM_FB_H_ 3 - #include <linux/fb.h> 4 - 5 - #define fb_pgprotect(...) do {} while (0) 6 - 7 - static inline int fb_is_primary_device(struct fb_info *info) 8 - { 9 - return 0; 10 - } 11 - 12 - #endif /* _ASM_FB_H_ */
+17 -24
fs/proc/base.c
··· 1360 1360 size_t count, loff_t *ppos) 1361 1361 { 1362 1362 struct task_struct *task; 1363 - int err, n; 1363 + int err; 1364 + unsigned int n; 1365 + 1366 + err = kstrtouint_from_user(buf, count, 0, &n); 1367 + if (err) 1368 + return err; 1364 1369 1365 1370 task = get_proc_task(file_inode(file)); 1366 1371 if (!task) 1367 1372 return -ESRCH; 1373 + WRITE_ONCE(task->fail_nth, n); 1368 1374 put_task_struct(task); 1369 - if (task != current) 1370 - return -EPERM; 1371 - err = kstrtoint_from_user(buf, count, 10, &n); 1372 - if (err) 1373 - return err; 1374 - if (n < 0 || n == INT_MAX) 1375 - return -EINVAL; 1376 - current->fail_nth = n + 1; 1375 + 1377 1376 return count; 1378 1377 } 1379 1378 ··· 1380 1381 size_t count, loff_t *ppos) 1381 1382 { 1382 1383 struct task_struct *task; 1383 - int err; 1384 + char numbuf[PROC_NUMBUF]; 1385 + ssize_t len; 1384 1386 1385 1387 task = get_proc_task(file_inode(file)); 1386 1388 if (!task) 1387 1389 return -ESRCH; 1390 + len = snprintf(numbuf, sizeof(numbuf), "%u\n", 1391 + READ_ONCE(task->fail_nth)); 1392 + len = simple_read_from_buffer(buf, count, ppos, numbuf, len); 1388 1393 put_task_struct(task); 1389 - if (task != current) 1390 - return -EPERM; 1391 - if (count < 1) 1392 - return -EINVAL; 1393 - err = put_user((char)(current->fail_nth ? 'N' : 'Y'), buf); 1394 - if (err) 1395 - return err; 1396 - current->fail_nth = 0; 1397 - return 1; 1394 + 1395 + return len; 1398 1396 } 1399 1397 1400 1398 static const struct file_operations proc_fail_nth_operations = { ··· 2962 2966 #endif 2963 2967 #ifdef CONFIG_FAULT_INJECTION 2964 2968 REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations), 2969 + REG("fail-nth", 0644, proc_fail_nth_operations), 2965 2970 #endif 2966 2971 #ifdef CONFIG_ELF_CORE 2967 2972 REG("coredump_filter", S_IRUGO|S_IWUSR, proc_coredump_filter_operations), ··· 3355 3358 #endif 3356 3359 #ifdef CONFIG_FAULT_INJECTION 3357 3360 REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations), 3358 - /* 3359 - * Operations on the file check that the task is current, 3360 - * so we create it with 0666 to support testing under unprivileged user. 3361 - */ 3362 - REG("fail-nth", 0666, proc_fail_nth_operations), 3361 + REG("fail-nth", 0644, proc_fail_nth_operations), 3363 3362 #endif 3364 3363 #ifdef CONFIG_TASK_IO_ACCOUNTING 3365 3364 ONE("io", S_IRUSR, proc_tid_io_accounting),
+1 -1
include/linux/sched.h
··· 974 974 975 975 #ifdef CONFIG_FAULT_INJECTION 976 976 int make_it_fail; 977 - int fail_nth; 977 + unsigned int fail_nth; 978 978 #endif 979 979 /* 980 980 * When (nr_dirtied >= nr_dirtied_pause), it's time to call
+7 -9
kernel/kmod.c
··· 68 68 */ 69 69 #define MAX_KMOD_CONCURRENT 50 70 70 static atomic_t kmod_concurrent_max = ATOMIC_INIT(MAX_KMOD_CONCURRENT); 71 + static DECLARE_WAIT_QUEUE_HEAD(kmod_wq); 71 72 72 73 /* 73 74 modprobe_path is set via /proc/sys. ··· 141 140 va_list args; 142 141 char module_name[MODULE_NAME_LEN]; 143 142 int ret; 144 - static int kmod_loop_msg; 145 143 146 144 /* 147 145 * We don't allow synchronous module loading from async. Module ··· 164 164 return ret; 165 165 166 166 if (atomic_dec_if_positive(&kmod_concurrent_max) < 0) { 167 - /* We may be blaming an innocent here, but unlikely */ 168 - if (kmod_loop_msg < 5) { 169 - printk(KERN_ERR 170 - "request_module: runaway loop modprobe %s\n", 171 - module_name); 172 - kmod_loop_msg++; 173 - } 174 - return -ENOMEM; 167 + pr_warn_ratelimited("request_module: kmod_concurrent_max (%u) close to 0 (max_modprobes: %u), for module %s, throttling...", 168 + atomic_read(&kmod_concurrent_max), 169 + MAX_KMOD_CONCURRENT, module_name); 170 + wait_event_interruptible(kmod_wq, 171 + atomic_dec_if_positive(&kmod_concurrent_max) >= 0); 175 172 } 176 173 177 174 trace_module_request(module_name, wait, _RET_IP_); ··· 176 179 ret = call_modprobe(module_name, wait ? UMH_WAIT_PROC : UMH_WAIT_EXEC); 177 180 178 181 atomic_inc(&kmod_concurrent_max); 182 + wake_up(&kmod_wq); 179 183 180 184 return ret; 181 185 }
+1 -1
kernel/watchdog.c
··· 9 9 * to those contributors as well. 10 10 */ 11 11 12 - #define pr_fmt(fmt) "NMI watchdog: " fmt 12 + #define pr_fmt(fmt) "watchdog: " fmt 13 13 14 14 #include <linux/mm.h> 15 15 #include <linux/cpu.h>
+27
lib/Kconfig.debug
··· 1847 1847 1848 1848 If unsure, say N. 1849 1849 1850 + config TEST_KMOD 1851 + tristate "kmod stress tester" 1852 + default n 1853 + depends on m 1854 + depends on BLOCK && (64BIT || LBDAF) # for XFS, BTRFS 1855 + depends on NETDEVICES && NET_CORE && INET # for TUN 1856 + select TEST_LKM 1857 + select XFS_FS 1858 + select TUN 1859 + select BTRFS_FS 1860 + help 1861 + Test the kernel's module loading mechanism: kmod. kmod implements 1862 + support to load modules using the Linux kernel's usermode helper. 1863 + This test provides a series of tests against kmod. 1864 + 1865 + Although technically you can either build test_kmod as a module or 1866 + into the kernel we disallow building it into the kernel since 1867 + it stress tests request_module() and this will very likely cause 1868 + some issues by taking over precious threads available from other 1869 + module load requests, ultimately this could be fatal. 1870 + 1871 + To run tests run: 1872 + 1873 + tools/testing/selftests/kmod/kmod.sh --help 1874 + 1875 + If unsure, say N. 1876 + 1850 1877 source "samples/Kconfig" 1851 1878 1852 1879 source "lib/Kconfig.kgdb"
+1
lib/Makefile
··· 61 61 obj-$(CONFIG_TEST_BITMAP) += test_bitmap.o 62 62 obj-$(CONFIG_TEST_UUID) += test_uuid.o 63 63 obj-$(CONFIG_TEST_PARMAN) += test_parman.o 64 + obj-$(CONFIG_TEST_KMOD) += test_kmod.o 64 65 65 66 ifeq ($(CONFIG_DEBUG_KOBJECT),y) 66 67 CFLAGS_kobject.o += -DDEBUG
+7
lib/atomic64_test.c
··· 153 153 long long v0 = 0xaaa31337c001d00dLL; 154 154 long long v1 = 0xdeadbeefdeafcafeLL; 155 155 long long v2 = 0xfaceabadf00df001LL; 156 + long long v3 = 0x8000000000000000LL; 156 157 long long onestwos = 0x1111111122222222LL; 157 158 long long one = 1LL; 159 + int r_int; 158 160 159 161 atomic64_t v = ATOMIC64_INIT(v0); 160 162 long long r = v0; ··· 242 240 BUG_ON(!atomic64_inc_not_zero(&v)); 243 241 r += one; 244 242 BUG_ON(v.counter != r); 243 + 244 + /* Confirm the return value fits in an int, even if the value doesn't */ 245 + INIT(v3); 246 + r_int = atomic64_inc_not_zero(&v); 247 + BUG_ON(!r_int); 245 248 } 246 249 247 250 static __init int test_atomics_init(void)
+5 -2
lib/fault-inject.c
··· 107 107 108 108 bool should_fail(struct fault_attr *attr, ssize_t size) 109 109 { 110 - if (in_task() && current->fail_nth) { 111 - if (--current->fail_nth == 0) 110 + if (in_task()) { 111 + unsigned int fail_nth = READ_ONCE(current->fail_nth); 112 + 113 + if (fail_nth && !WRITE_ONCE(current->fail_nth, fail_nth - 1)) 112 114 goto fail; 115 + 113 116 return false; 114 117 } 115 118
+1246
lib/test_kmod.c
··· 1 + /* 2 + * kmod stress test driver 3 + * 4 + * Copyright (C) 2017 Luis R. Rodriguez <mcgrof@kernel.org> 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 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 18 + 19 + /* 20 + * This driver provides an interface to trigger and test the kernel's 21 + * module loader through a series of configurations and a few triggers. 22 + * To test this driver use the following script as root: 23 + * 24 + * tools/testing/selftests/kmod/kmod.sh --help 25 + */ 26 + 27 + #include <linux/kernel.h> 28 + #include <linux/module.h> 29 + #include <linux/kmod.h> 30 + #include <linux/printk.h> 31 + #include <linux/kthread.h> 32 + #include <linux/sched.h> 33 + #include <linux/fs.h> 34 + #include <linux/miscdevice.h> 35 + #include <linux/vmalloc.h> 36 + #include <linux/slab.h> 37 + #include <linux/device.h> 38 + 39 + #define TEST_START_NUM_THREADS 50 40 + #define TEST_START_DRIVER "test_module" 41 + #define TEST_START_TEST_FS "xfs" 42 + #define TEST_START_TEST_CASE TEST_KMOD_DRIVER 43 + 44 + 45 + static bool force_init_test = false; 46 + module_param(force_init_test, bool_enable_only, 0644); 47 + MODULE_PARM_DESC(force_init_test, 48 + "Force kicking a test immediately after driver loads"); 49 + 50 + /* 51 + * For device allocation / registration 52 + */ 53 + static DEFINE_MUTEX(reg_dev_mutex); 54 + static LIST_HEAD(reg_test_devs); 55 + 56 + /* 57 + * num_test_devs actually represents the *next* ID of the next 58 + * device we will allow to create. 59 + */ 60 + static int num_test_devs; 61 + 62 + /** 63 + * enum kmod_test_case - linker table test case 64 + * 65 + * If you add a test case, please be sure to review if you need to se 66 + * @need_mod_put for your tests case. 67 + * 68 + * @TEST_KMOD_DRIVER: stress tests request_module() 69 + * @TEST_KMOD_FS_TYPE: stress tests get_fs_type() 70 + */ 71 + enum kmod_test_case { 72 + __TEST_KMOD_INVALID = 0, 73 + 74 + TEST_KMOD_DRIVER, 75 + TEST_KMOD_FS_TYPE, 76 + 77 + __TEST_KMOD_MAX, 78 + }; 79 + 80 + struct test_config { 81 + char *test_driver; 82 + char *test_fs; 83 + unsigned int num_threads; 84 + enum kmod_test_case test_case; 85 + int test_result; 86 + }; 87 + 88 + struct kmod_test_device; 89 + 90 + /** 91 + * kmod_test_device_info - thread info 92 + * 93 + * @ret_sync: return value if request_module() is used, sync request for 94 + * @TEST_KMOD_DRIVER 95 + * @fs_sync: return value of get_fs_type() for @TEST_KMOD_FS_TYPE 96 + * @thread_idx: thread ID 97 + * @test_dev: test device test is being performed under 98 + * @need_mod_put: Some tests (get_fs_type() is one) requires putting the module 99 + * (module_put(fs_sync->owner)) when done, otherwise you will not be able 100 + * to unload the respective modules and re-test. We use this to keep 101 + * accounting of when we need this and to help out in case we need to 102 + * error out and deal with module_put() on error. 103 + */ 104 + struct kmod_test_device_info { 105 + int ret_sync; 106 + struct file_system_type *fs_sync; 107 + struct task_struct *task_sync; 108 + unsigned int thread_idx; 109 + struct kmod_test_device *test_dev; 110 + bool need_mod_put; 111 + }; 112 + 113 + /** 114 + * kmod_test_device - test device to help test kmod 115 + * 116 + * @dev_idx: unique ID for test device 117 + * @config: configuration for the test 118 + * @misc_dev: we use a misc device under the hood 119 + * @dev: pointer to misc_dev's own struct device 120 + * @config_mutex: protects configuration of test 121 + * @trigger_mutex: the test trigger can only be fired once at a time 122 + * @thread_lock: protects @done count, and the @info per each thread 123 + * @done: number of threads which have completed or failed 124 + * @test_is_oom: when we run out of memory, use this to halt moving forward 125 + * @kthreads_done: completion used to signal when all work is done 126 + * @list: needed to be part of the reg_test_devs 127 + * @info: array of info for each thread 128 + */ 129 + struct kmod_test_device { 130 + int dev_idx; 131 + struct test_config config; 132 + struct miscdevice misc_dev; 133 + struct device *dev; 134 + struct mutex config_mutex; 135 + struct mutex trigger_mutex; 136 + struct mutex thread_mutex; 137 + 138 + unsigned int done; 139 + 140 + bool test_is_oom; 141 + struct completion kthreads_done; 142 + struct list_head list; 143 + 144 + struct kmod_test_device_info *info; 145 + }; 146 + 147 + static const char *test_case_str(enum kmod_test_case test_case) 148 + { 149 + switch (test_case) { 150 + case TEST_KMOD_DRIVER: 151 + return "TEST_KMOD_DRIVER"; 152 + case TEST_KMOD_FS_TYPE: 153 + return "TEST_KMOD_FS_TYPE"; 154 + default: 155 + return "invalid"; 156 + } 157 + } 158 + 159 + static struct miscdevice *dev_to_misc_dev(struct device *dev) 160 + { 161 + return dev_get_drvdata(dev); 162 + } 163 + 164 + static struct kmod_test_device *misc_dev_to_test_dev(struct miscdevice *misc_dev) 165 + { 166 + return container_of(misc_dev, struct kmod_test_device, misc_dev); 167 + } 168 + 169 + static struct kmod_test_device *dev_to_test_dev(struct device *dev) 170 + { 171 + struct miscdevice *misc_dev; 172 + 173 + misc_dev = dev_to_misc_dev(dev); 174 + 175 + return misc_dev_to_test_dev(misc_dev); 176 + } 177 + 178 + /* Must run with thread_mutex held */ 179 + static void kmod_test_done_check(struct kmod_test_device *test_dev, 180 + unsigned int idx) 181 + { 182 + struct test_config *config = &test_dev->config; 183 + 184 + test_dev->done++; 185 + dev_dbg(test_dev->dev, "Done thread count: %u\n", test_dev->done); 186 + 187 + if (test_dev->done == config->num_threads) { 188 + dev_info(test_dev->dev, "Done: %u threads have all run now\n", 189 + test_dev->done); 190 + dev_info(test_dev->dev, "Last thread to run: %u\n", idx); 191 + complete(&test_dev->kthreads_done); 192 + } 193 + } 194 + 195 + static void test_kmod_put_module(struct kmod_test_device_info *info) 196 + { 197 + struct kmod_test_device *test_dev = info->test_dev; 198 + struct test_config *config = &test_dev->config; 199 + 200 + if (!info->need_mod_put) 201 + return; 202 + 203 + switch (config->test_case) { 204 + case TEST_KMOD_DRIVER: 205 + break; 206 + case TEST_KMOD_FS_TYPE: 207 + if (info && info->fs_sync && info->fs_sync->owner) 208 + module_put(info->fs_sync->owner); 209 + break; 210 + default: 211 + BUG(); 212 + } 213 + 214 + info->need_mod_put = true; 215 + } 216 + 217 + static int run_request(void *data) 218 + { 219 + struct kmod_test_device_info *info = data; 220 + struct kmod_test_device *test_dev = info->test_dev; 221 + struct test_config *config = &test_dev->config; 222 + 223 + switch (config->test_case) { 224 + case TEST_KMOD_DRIVER: 225 + info->ret_sync = request_module("%s", config->test_driver); 226 + break; 227 + case TEST_KMOD_FS_TYPE: 228 + info->fs_sync = get_fs_type(config->test_fs); 229 + info->need_mod_put = true; 230 + break; 231 + default: 232 + /* __trigger_config_run() already checked for test sanity */ 233 + BUG(); 234 + return -EINVAL; 235 + } 236 + 237 + dev_dbg(test_dev->dev, "Ran thread %u\n", info->thread_idx); 238 + 239 + test_kmod_put_module(info); 240 + 241 + mutex_lock(&test_dev->thread_mutex); 242 + info->task_sync = NULL; 243 + kmod_test_done_check(test_dev, info->thread_idx); 244 + mutex_unlock(&test_dev->thread_mutex); 245 + 246 + return 0; 247 + } 248 + 249 + static int tally_work_test(struct kmod_test_device_info *info) 250 + { 251 + struct kmod_test_device *test_dev = info->test_dev; 252 + struct test_config *config = &test_dev->config; 253 + int err_ret = 0; 254 + 255 + switch (config->test_case) { 256 + case TEST_KMOD_DRIVER: 257 + /* 258 + * Only capture errors, if one is found that's 259 + * enough, for now. 260 + */ 261 + if (info->ret_sync != 0) 262 + err_ret = info->ret_sync; 263 + dev_info(test_dev->dev, 264 + "Sync thread %d return status: %d\n", 265 + info->thread_idx, info->ret_sync); 266 + break; 267 + case TEST_KMOD_FS_TYPE: 268 + /* For now we make this simple */ 269 + if (!info->fs_sync) 270 + err_ret = -EINVAL; 271 + dev_info(test_dev->dev, "Sync thread %u fs: %s\n", 272 + info->thread_idx, info->fs_sync ? config->test_fs : 273 + "NULL"); 274 + break; 275 + default: 276 + BUG(); 277 + } 278 + 279 + return err_ret; 280 + } 281 + 282 + /* 283 + * XXX: add result option to display if all errors did not match. 284 + * For now we just keep any error code if one was found. 285 + * 286 + * If this ran it means *all* tasks were created fine and we 287 + * are now just collecting results. 288 + * 289 + * Only propagate errors, do not override with a subsequent sucess case. 290 + */ 291 + static void tally_up_work(struct kmod_test_device *test_dev) 292 + { 293 + struct test_config *config = &test_dev->config; 294 + struct kmod_test_device_info *info; 295 + unsigned int idx; 296 + int err_ret = 0; 297 + int ret = 0; 298 + 299 + mutex_lock(&test_dev->thread_mutex); 300 + 301 + dev_info(test_dev->dev, "Results:\n"); 302 + 303 + for (idx=0; idx < config->num_threads; idx++) { 304 + info = &test_dev->info[idx]; 305 + ret = tally_work_test(info); 306 + if (ret) 307 + err_ret = ret; 308 + } 309 + 310 + /* 311 + * Note: request_module() returns 256 for a module not found even 312 + * though modprobe itself returns 1. 313 + */ 314 + config->test_result = err_ret; 315 + 316 + mutex_unlock(&test_dev->thread_mutex); 317 + } 318 + 319 + static int try_one_request(struct kmod_test_device *test_dev, unsigned int idx) 320 + { 321 + struct kmod_test_device_info *info = &test_dev->info[idx]; 322 + int fail_ret = -ENOMEM; 323 + 324 + mutex_lock(&test_dev->thread_mutex); 325 + 326 + info->thread_idx = idx; 327 + info->test_dev = test_dev; 328 + info->task_sync = kthread_run(run_request, info, "%s-%u", 329 + KBUILD_MODNAME, idx); 330 + 331 + if (!info->task_sync || IS_ERR(info->task_sync)) { 332 + test_dev->test_is_oom = true; 333 + dev_err(test_dev->dev, "Setting up thread %u failed\n", idx); 334 + info->task_sync = NULL; 335 + goto err_out; 336 + } else 337 + dev_dbg(test_dev->dev, "Kicked off thread %u\n", idx); 338 + 339 + mutex_unlock(&test_dev->thread_mutex); 340 + 341 + return 0; 342 + 343 + err_out: 344 + info->ret_sync = fail_ret; 345 + mutex_unlock(&test_dev->thread_mutex); 346 + 347 + return fail_ret; 348 + } 349 + 350 + static void test_dev_kmod_stop_tests(struct kmod_test_device *test_dev) 351 + { 352 + struct test_config *config = &test_dev->config; 353 + struct kmod_test_device_info *info; 354 + unsigned int i; 355 + 356 + dev_info(test_dev->dev, "Ending request_module() tests\n"); 357 + 358 + mutex_lock(&test_dev->thread_mutex); 359 + 360 + for (i=0; i < config->num_threads; i++) { 361 + info = &test_dev->info[i]; 362 + if (info->task_sync && !IS_ERR(info->task_sync)) { 363 + dev_info(test_dev->dev, 364 + "Stopping still-running thread %i\n", i); 365 + kthread_stop(info->task_sync); 366 + } 367 + 368 + /* 369 + * info->task_sync is well protected, it can only be 370 + * NULL or a pointer to a struct. If its NULL we either 371 + * never ran, or we did and we completed the work. Completed 372 + * tasks *always* put the module for us. This is a sanity 373 + * check -- just in case. 374 + */ 375 + if (info->task_sync && info->need_mod_put) 376 + test_kmod_put_module(info); 377 + } 378 + 379 + mutex_unlock(&test_dev->thread_mutex); 380 + } 381 + 382 + /* 383 + * Only wait *iff* we did not run into any errors during all of our thread 384 + * set up. If run into any issues we stop threads and just bail out with 385 + * an error to the trigger. This also means we don't need any tally work 386 + * for any threads which fail. 387 + */ 388 + static int try_requests(struct kmod_test_device *test_dev) 389 + { 390 + struct test_config *config = &test_dev->config; 391 + unsigned int idx; 392 + int ret; 393 + bool any_error = false; 394 + 395 + for (idx=0; idx < config->num_threads; idx++) { 396 + if (test_dev->test_is_oom) { 397 + any_error = true; 398 + break; 399 + } 400 + 401 + ret = try_one_request(test_dev, idx); 402 + if (ret) { 403 + any_error = true; 404 + break; 405 + } 406 + } 407 + 408 + if (!any_error) { 409 + test_dev->test_is_oom = false; 410 + dev_info(test_dev->dev, 411 + "No errors were found while initializing threads\n"); 412 + wait_for_completion(&test_dev->kthreads_done); 413 + tally_up_work(test_dev); 414 + } else { 415 + test_dev->test_is_oom = true; 416 + dev_info(test_dev->dev, 417 + "At least one thread failed to start, stop all work\n"); 418 + test_dev_kmod_stop_tests(test_dev); 419 + return -ENOMEM; 420 + } 421 + 422 + return 0; 423 + } 424 + 425 + static int run_test_driver(struct kmod_test_device *test_dev) 426 + { 427 + struct test_config *config = &test_dev->config; 428 + 429 + dev_info(test_dev->dev, "Test case: %s (%u)\n", 430 + test_case_str(config->test_case), 431 + config->test_case); 432 + dev_info(test_dev->dev, "Test driver to load: %s\n", 433 + config->test_driver); 434 + dev_info(test_dev->dev, "Number of threads to run: %u\n", 435 + config->num_threads); 436 + dev_info(test_dev->dev, "Thread IDs will range from 0 - %u\n", 437 + config->num_threads - 1); 438 + 439 + return try_requests(test_dev); 440 + } 441 + 442 + static int run_test_fs_type(struct kmod_test_device *test_dev) 443 + { 444 + struct test_config *config = &test_dev->config; 445 + 446 + dev_info(test_dev->dev, "Test case: %s (%u)\n", 447 + test_case_str(config->test_case), 448 + config->test_case); 449 + dev_info(test_dev->dev, "Test filesystem to load: %s\n", 450 + config->test_fs); 451 + dev_info(test_dev->dev, "Number of threads to run: %u\n", 452 + config->num_threads); 453 + dev_info(test_dev->dev, "Thread IDs will range from 0 - %u\n", 454 + config->num_threads - 1); 455 + 456 + return try_requests(test_dev); 457 + } 458 + 459 + static ssize_t config_show(struct device *dev, 460 + struct device_attribute *attr, 461 + char *buf) 462 + { 463 + struct kmod_test_device *test_dev = dev_to_test_dev(dev); 464 + struct test_config *config = &test_dev->config; 465 + int len = 0; 466 + 467 + mutex_lock(&test_dev->config_mutex); 468 + 469 + len += snprintf(buf, PAGE_SIZE, 470 + "Custom trigger configuration for: %s\n", 471 + dev_name(dev)); 472 + 473 + len += snprintf(buf+len, PAGE_SIZE - len, 474 + "Number of threads:\t%u\n", 475 + config->num_threads); 476 + 477 + len += snprintf(buf+len, PAGE_SIZE - len, 478 + "Test_case:\t%s (%u)\n", 479 + test_case_str(config->test_case), 480 + config->test_case); 481 + 482 + if (config->test_driver) 483 + len += snprintf(buf+len, PAGE_SIZE - len, 484 + "driver:\t%s\n", 485 + config->test_driver); 486 + else 487 + len += snprintf(buf+len, PAGE_SIZE - len, 488 + "driver:\tEMTPY\n"); 489 + 490 + if (config->test_fs) 491 + len += snprintf(buf+len, PAGE_SIZE - len, 492 + "fs:\t%s\n", 493 + config->test_fs); 494 + else 495 + len += snprintf(buf+len, PAGE_SIZE - len, 496 + "fs:\tEMTPY\n"); 497 + 498 + mutex_unlock(&test_dev->config_mutex); 499 + 500 + return len; 501 + } 502 + static DEVICE_ATTR_RO(config); 503 + 504 + /* 505 + * This ensures we don't allow kicking threads through if our configuration 506 + * is faulty. 507 + */ 508 + static int __trigger_config_run(struct kmod_test_device *test_dev) 509 + { 510 + struct test_config *config = &test_dev->config; 511 + 512 + test_dev->done = 0; 513 + 514 + switch (config->test_case) { 515 + case TEST_KMOD_DRIVER: 516 + return run_test_driver(test_dev); 517 + case TEST_KMOD_FS_TYPE: 518 + return run_test_fs_type(test_dev); 519 + default: 520 + dev_warn(test_dev->dev, 521 + "Invalid test case requested: %u\n", 522 + config->test_case); 523 + return -EINVAL; 524 + } 525 + } 526 + 527 + static int trigger_config_run(struct kmod_test_device *test_dev) 528 + { 529 + struct test_config *config = &test_dev->config; 530 + int ret; 531 + 532 + mutex_lock(&test_dev->trigger_mutex); 533 + mutex_lock(&test_dev->config_mutex); 534 + 535 + ret = __trigger_config_run(test_dev); 536 + if (ret < 0) 537 + goto out; 538 + dev_info(test_dev->dev, "General test result: %d\n", 539 + config->test_result); 540 + 541 + /* 542 + * We must return 0 after a trigger even unless something went 543 + * wrong with the setup of the test. If the test setup went fine 544 + * then userspace must just check the result of config->test_result. 545 + * One issue with relying on the return from a call in the kernel 546 + * is if the kernel returns a possitive value using this trigger 547 + * will not return the value to userspace, it would be lost. 548 + * 549 + * By not relying on capturing the return value of tests we are using 550 + * through the trigger it also us to run tests with set -e and only 551 + * fail when something went wrong with the driver upon trigger 552 + * requests. 553 + */ 554 + ret = 0; 555 + 556 + out: 557 + mutex_unlock(&test_dev->config_mutex); 558 + mutex_unlock(&test_dev->trigger_mutex); 559 + 560 + return ret; 561 + } 562 + 563 + static ssize_t 564 + trigger_config_store(struct device *dev, 565 + struct device_attribute *attr, 566 + const char *buf, size_t count) 567 + { 568 + struct kmod_test_device *test_dev = dev_to_test_dev(dev); 569 + int ret; 570 + 571 + if (test_dev->test_is_oom) 572 + return -ENOMEM; 573 + 574 + /* For all intents and purposes we don't care what userspace 575 + * sent this trigger, we care only that we were triggered. 576 + * We treat the return value only for caputuring issues with 577 + * the test setup. At this point all the test variables should 578 + * have been allocated so typically this should never fail. 579 + */ 580 + ret = trigger_config_run(test_dev); 581 + if (unlikely(ret < 0)) 582 + goto out; 583 + 584 + /* 585 + * Note: any return > 0 will be treated as success 586 + * and the error value will not be available to userspace. 587 + * Do not rely on trying to send to userspace a test value 588 + * return value as possitive return errors will be lost. 589 + */ 590 + if (WARN_ON(ret > 0)) 591 + return -EINVAL; 592 + 593 + ret = count; 594 + out: 595 + return ret; 596 + } 597 + static DEVICE_ATTR_WO(trigger_config); 598 + 599 + /* 600 + * XXX: move to kstrncpy() once merged. 601 + * 602 + * Users should use kfree_const() when freeing these. 603 + */ 604 + static int __kstrncpy(char **dst, const char *name, size_t count, gfp_t gfp) 605 + { 606 + *dst = kstrndup(name, count, gfp); 607 + if (!*dst) 608 + return -ENOSPC; 609 + return count; 610 + } 611 + 612 + static int config_copy_test_driver_name(struct test_config *config, 613 + const char *name, 614 + size_t count) 615 + { 616 + return __kstrncpy(&config->test_driver, name, count, GFP_KERNEL); 617 + } 618 + 619 + 620 + static int config_copy_test_fs(struct test_config *config, const char *name, 621 + size_t count) 622 + { 623 + return __kstrncpy(&config->test_fs, name, count, GFP_KERNEL); 624 + } 625 + 626 + static void __kmod_config_free(struct test_config *config) 627 + { 628 + if (!config) 629 + return; 630 + 631 + kfree_const(config->test_driver); 632 + config->test_driver = NULL; 633 + 634 + kfree_const(config->test_fs); 635 + config->test_driver = NULL; 636 + } 637 + 638 + static void kmod_config_free(struct kmod_test_device *test_dev) 639 + { 640 + struct test_config *config; 641 + 642 + if (!test_dev) 643 + return; 644 + 645 + config = &test_dev->config; 646 + 647 + mutex_lock(&test_dev->config_mutex); 648 + __kmod_config_free(config); 649 + mutex_unlock(&test_dev->config_mutex); 650 + } 651 + 652 + static ssize_t config_test_driver_store(struct device *dev, 653 + struct device_attribute *attr, 654 + const char *buf, size_t count) 655 + { 656 + struct kmod_test_device *test_dev = dev_to_test_dev(dev); 657 + struct test_config *config = &test_dev->config; 658 + int copied; 659 + 660 + mutex_lock(&test_dev->config_mutex); 661 + 662 + kfree_const(config->test_driver); 663 + config->test_driver = NULL; 664 + 665 + copied = config_copy_test_driver_name(config, buf, count); 666 + mutex_unlock(&test_dev->config_mutex); 667 + 668 + return copied; 669 + } 670 + 671 + /* 672 + * As per sysfs_kf_seq_show() the buf is max PAGE_SIZE. 673 + */ 674 + static ssize_t config_test_show_str(struct mutex *config_mutex, 675 + char *dst, 676 + char *src) 677 + { 678 + int len; 679 + 680 + mutex_lock(config_mutex); 681 + len = snprintf(dst, PAGE_SIZE, "%s\n", src); 682 + mutex_unlock(config_mutex); 683 + 684 + return len; 685 + } 686 + 687 + static ssize_t config_test_driver_show(struct device *dev, 688 + struct device_attribute *attr, 689 + char *buf) 690 + { 691 + struct kmod_test_device *test_dev = dev_to_test_dev(dev); 692 + struct test_config *config = &test_dev->config; 693 + 694 + return config_test_show_str(&test_dev->config_mutex, buf, 695 + config->test_driver); 696 + } 697 + static DEVICE_ATTR(config_test_driver, 0644, config_test_driver_show, 698 + config_test_driver_store); 699 + 700 + static ssize_t config_test_fs_store(struct device *dev, 701 + struct device_attribute *attr, 702 + const char *buf, size_t count) 703 + { 704 + struct kmod_test_device *test_dev = dev_to_test_dev(dev); 705 + struct test_config *config = &test_dev->config; 706 + int copied; 707 + 708 + mutex_lock(&test_dev->config_mutex); 709 + 710 + kfree_const(config->test_fs); 711 + config->test_fs = NULL; 712 + 713 + copied = config_copy_test_fs(config, buf, count); 714 + mutex_unlock(&test_dev->config_mutex); 715 + 716 + return copied; 717 + } 718 + 719 + static ssize_t config_test_fs_show(struct device *dev, 720 + struct device_attribute *attr, 721 + char *buf) 722 + { 723 + struct kmod_test_device *test_dev = dev_to_test_dev(dev); 724 + struct test_config *config = &test_dev->config; 725 + 726 + return config_test_show_str(&test_dev->config_mutex, buf, 727 + config->test_fs); 728 + } 729 + static DEVICE_ATTR(config_test_fs, 0644, config_test_fs_show, 730 + config_test_fs_store); 731 + 732 + static int trigger_config_run_type(struct kmod_test_device *test_dev, 733 + enum kmod_test_case test_case, 734 + const char *test_str) 735 + { 736 + int copied = 0; 737 + struct test_config *config = &test_dev->config; 738 + 739 + mutex_lock(&test_dev->config_mutex); 740 + 741 + switch (test_case) { 742 + case TEST_KMOD_DRIVER: 743 + kfree_const(config->test_driver); 744 + config->test_driver = NULL; 745 + copied = config_copy_test_driver_name(config, test_str, 746 + strlen(test_str)); 747 + break; 748 + case TEST_KMOD_FS_TYPE: 749 + break; 750 + kfree_const(config->test_fs); 751 + config->test_driver = NULL; 752 + copied = config_copy_test_fs(config, test_str, 753 + strlen(test_str)); 754 + default: 755 + mutex_unlock(&test_dev->config_mutex); 756 + return -EINVAL; 757 + } 758 + 759 + config->test_case = test_case; 760 + 761 + mutex_unlock(&test_dev->config_mutex); 762 + 763 + if (copied <= 0 || copied != strlen(test_str)) { 764 + test_dev->test_is_oom = true; 765 + return -ENOMEM; 766 + } 767 + 768 + test_dev->test_is_oom = false; 769 + 770 + return trigger_config_run(test_dev); 771 + } 772 + 773 + static void free_test_dev_info(struct kmod_test_device *test_dev) 774 + { 775 + vfree(test_dev->info); 776 + test_dev->info = NULL; 777 + } 778 + 779 + static int kmod_config_sync_info(struct kmod_test_device *test_dev) 780 + { 781 + struct test_config *config = &test_dev->config; 782 + 783 + free_test_dev_info(test_dev); 784 + test_dev->info = vzalloc(config->num_threads * 785 + sizeof(struct kmod_test_device_info)); 786 + if (!test_dev->info) { 787 + dev_err(test_dev->dev, "Cannot alloc test_dev info\n"); 788 + return -ENOMEM; 789 + } 790 + 791 + return 0; 792 + } 793 + 794 + /* 795 + * Old kernels may not have this, if you want to port this code to 796 + * test it on older kernels. 797 + */ 798 + #ifdef get_kmod_umh_limit 799 + static unsigned int kmod_init_test_thread_limit(void) 800 + { 801 + return get_kmod_umh_limit(); 802 + } 803 + #else 804 + static unsigned int kmod_init_test_thread_limit(void) 805 + { 806 + return TEST_START_NUM_THREADS; 807 + } 808 + #endif 809 + 810 + static int __kmod_config_init(struct kmod_test_device *test_dev) 811 + { 812 + struct test_config *config = &test_dev->config; 813 + int ret = -ENOMEM, copied; 814 + 815 + __kmod_config_free(config); 816 + 817 + copied = config_copy_test_driver_name(config, TEST_START_DRIVER, 818 + strlen(TEST_START_DRIVER)); 819 + if (copied != strlen(TEST_START_DRIVER)) 820 + goto err_out; 821 + 822 + copied = config_copy_test_fs(config, TEST_START_TEST_FS, 823 + strlen(TEST_START_TEST_FS)); 824 + if (copied != strlen(TEST_START_TEST_FS)) 825 + goto err_out; 826 + 827 + config->num_threads = kmod_init_test_thread_limit(); 828 + config->test_result = 0; 829 + config->test_case = TEST_START_TEST_CASE; 830 + 831 + ret = kmod_config_sync_info(test_dev); 832 + if (ret) 833 + goto err_out; 834 + 835 + test_dev->test_is_oom = false; 836 + 837 + return 0; 838 + 839 + err_out: 840 + test_dev->test_is_oom = true; 841 + WARN_ON(test_dev->test_is_oom); 842 + 843 + __kmod_config_free(config); 844 + 845 + return ret; 846 + } 847 + 848 + static ssize_t reset_store(struct device *dev, 849 + struct device_attribute *attr, 850 + const char *buf, size_t count) 851 + { 852 + struct kmod_test_device *test_dev = dev_to_test_dev(dev); 853 + int ret; 854 + 855 + mutex_lock(&test_dev->trigger_mutex); 856 + mutex_lock(&test_dev->config_mutex); 857 + 858 + ret = __kmod_config_init(test_dev); 859 + if (ret < 0) { 860 + ret = -ENOMEM; 861 + dev_err(dev, "could not alloc settings for config trigger: %d\n", 862 + ret); 863 + goto out; 864 + } 865 + 866 + dev_info(dev, "reset\n"); 867 + ret = count; 868 + 869 + out: 870 + mutex_unlock(&test_dev->config_mutex); 871 + mutex_unlock(&test_dev->trigger_mutex); 872 + 873 + return ret; 874 + } 875 + static DEVICE_ATTR_WO(reset); 876 + 877 + static int test_dev_config_update_uint_sync(struct kmod_test_device *test_dev, 878 + const char *buf, size_t size, 879 + unsigned int *config, 880 + int (*test_sync)(struct kmod_test_device *test_dev)) 881 + { 882 + int ret; 883 + long new; 884 + unsigned int old_val; 885 + 886 + ret = kstrtol(buf, 10, &new); 887 + if (ret) 888 + return ret; 889 + 890 + if (new > UINT_MAX) 891 + return -EINVAL; 892 + 893 + mutex_lock(&test_dev->config_mutex); 894 + 895 + old_val = *config; 896 + *(unsigned int *)config = new; 897 + 898 + ret = test_sync(test_dev); 899 + if (ret) { 900 + *(unsigned int *)config = old_val; 901 + 902 + ret = test_sync(test_dev); 903 + WARN_ON(ret); 904 + 905 + mutex_unlock(&test_dev->config_mutex); 906 + return -EINVAL; 907 + } 908 + 909 + mutex_unlock(&test_dev->config_mutex); 910 + /* Always return full write size even if we didn't consume all */ 911 + return size; 912 + } 913 + 914 + static int test_dev_config_update_uint_range(struct kmod_test_device *test_dev, 915 + const char *buf, size_t size, 916 + unsigned int *config, 917 + unsigned int min, 918 + unsigned int max) 919 + { 920 + int ret; 921 + long new; 922 + 923 + ret = kstrtol(buf, 10, &new); 924 + if (ret) 925 + return ret; 926 + 927 + if (new < min || new > max || new > UINT_MAX) 928 + return -EINVAL; 929 + 930 + mutex_lock(&test_dev->config_mutex); 931 + *config = new; 932 + mutex_unlock(&test_dev->config_mutex); 933 + 934 + /* Always return full write size even if we didn't consume all */ 935 + return size; 936 + } 937 + 938 + static int test_dev_config_update_int(struct kmod_test_device *test_dev, 939 + const char *buf, size_t size, 940 + int *config) 941 + { 942 + int ret; 943 + long new; 944 + 945 + ret = kstrtol(buf, 10, &new); 946 + if (ret) 947 + return ret; 948 + 949 + if (new > INT_MAX || new < INT_MIN) 950 + return -EINVAL; 951 + 952 + mutex_lock(&test_dev->config_mutex); 953 + *config = new; 954 + mutex_unlock(&test_dev->config_mutex); 955 + /* Always return full write size even if we didn't consume all */ 956 + return size; 957 + } 958 + 959 + static ssize_t test_dev_config_show_int(struct kmod_test_device *test_dev, 960 + char *buf, 961 + int config) 962 + { 963 + int val; 964 + 965 + mutex_lock(&test_dev->config_mutex); 966 + val = config; 967 + mutex_unlock(&test_dev->config_mutex); 968 + 969 + return snprintf(buf, PAGE_SIZE, "%d\n", val); 970 + } 971 + 972 + static ssize_t test_dev_config_show_uint(struct kmod_test_device *test_dev, 973 + char *buf, 974 + unsigned int config) 975 + { 976 + unsigned int val; 977 + 978 + mutex_lock(&test_dev->config_mutex); 979 + val = config; 980 + mutex_unlock(&test_dev->config_mutex); 981 + 982 + return snprintf(buf, PAGE_SIZE, "%u\n", val); 983 + } 984 + 985 + static ssize_t test_result_store(struct device *dev, 986 + struct device_attribute *attr, 987 + const char *buf, size_t count) 988 + { 989 + struct kmod_test_device *test_dev = dev_to_test_dev(dev); 990 + struct test_config *config = &test_dev->config; 991 + 992 + return test_dev_config_update_int(test_dev, buf, count, 993 + &config->test_result); 994 + } 995 + 996 + static ssize_t config_num_threads_store(struct device *dev, 997 + struct device_attribute *attr, 998 + const char *buf, size_t count) 999 + { 1000 + struct kmod_test_device *test_dev = dev_to_test_dev(dev); 1001 + struct test_config *config = &test_dev->config; 1002 + 1003 + return test_dev_config_update_uint_sync(test_dev, buf, count, 1004 + &config->num_threads, 1005 + kmod_config_sync_info); 1006 + } 1007 + 1008 + static ssize_t config_num_threads_show(struct device *dev, 1009 + struct device_attribute *attr, 1010 + char *buf) 1011 + { 1012 + struct kmod_test_device *test_dev = dev_to_test_dev(dev); 1013 + struct test_config *config = &test_dev->config; 1014 + 1015 + return test_dev_config_show_int(test_dev, buf, config->num_threads); 1016 + } 1017 + static DEVICE_ATTR(config_num_threads, 0644, config_num_threads_show, 1018 + config_num_threads_store); 1019 + 1020 + static ssize_t config_test_case_store(struct device *dev, 1021 + struct device_attribute *attr, 1022 + const char *buf, size_t count) 1023 + { 1024 + struct kmod_test_device *test_dev = dev_to_test_dev(dev); 1025 + struct test_config *config = &test_dev->config; 1026 + 1027 + return test_dev_config_update_uint_range(test_dev, buf, count, 1028 + &config->test_case, 1029 + __TEST_KMOD_INVALID + 1, 1030 + __TEST_KMOD_MAX - 1); 1031 + } 1032 + 1033 + static ssize_t config_test_case_show(struct device *dev, 1034 + struct device_attribute *attr, 1035 + char *buf) 1036 + { 1037 + struct kmod_test_device *test_dev = dev_to_test_dev(dev); 1038 + struct test_config *config = &test_dev->config; 1039 + 1040 + return test_dev_config_show_uint(test_dev, buf, config->test_case); 1041 + } 1042 + static DEVICE_ATTR(config_test_case, 0644, config_test_case_show, 1043 + config_test_case_store); 1044 + 1045 + static ssize_t test_result_show(struct device *dev, 1046 + struct device_attribute *attr, 1047 + char *buf) 1048 + { 1049 + struct kmod_test_device *test_dev = dev_to_test_dev(dev); 1050 + struct test_config *config = &test_dev->config; 1051 + 1052 + return test_dev_config_show_int(test_dev, buf, config->test_result); 1053 + } 1054 + static DEVICE_ATTR(test_result, 0644, test_result_show, test_result_store); 1055 + 1056 + #define TEST_KMOD_DEV_ATTR(name) &dev_attr_##name.attr 1057 + 1058 + static struct attribute *test_dev_attrs[] = { 1059 + TEST_KMOD_DEV_ATTR(trigger_config), 1060 + TEST_KMOD_DEV_ATTR(config), 1061 + TEST_KMOD_DEV_ATTR(reset), 1062 + 1063 + TEST_KMOD_DEV_ATTR(config_test_driver), 1064 + TEST_KMOD_DEV_ATTR(config_test_fs), 1065 + TEST_KMOD_DEV_ATTR(config_num_threads), 1066 + TEST_KMOD_DEV_ATTR(config_test_case), 1067 + TEST_KMOD_DEV_ATTR(test_result), 1068 + 1069 + NULL, 1070 + }; 1071 + 1072 + ATTRIBUTE_GROUPS(test_dev); 1073 + 1074 + static int kmod_config_init(struct kmod_test_device *test_dev) 1075 + { 1076 + int ret; 1077 + 1078 + mutex_lock(&test_dev->config_mutex); 1079 + ret = __kmod_config_init(test_dev); 1080 + mutex_unlock(&test_dev->config_mutex); 1081 + 1082 + return ret; 1083 + } 1084 + 1085 + static struct kmod_test_device *alloc_test_dev_kmod(int idx) 1086 + { 1087 + int ret; 1088 + struct kmod_test_device *test_dev; 1089 + struct miscdevice *misc_dev; 1090 + 1091 + test_dev = vzalloc(sizeof(struct kmod_test_device)); 1092 + if (!test_dev) { 1093 + pr_err("Cannot alloc test_dev\n"); 1094 + goto err_out; 1095 + } 1096 + 1097 + mutex_init(&test_dev->config_mutex); 1098 + mutex_init(&test_dev->trigger_mutex); 1099 + mutex_init(&test_dev->thread_mutex); 1100 + 1101 + init_completion(&test_dev->kthreads_done); 1102 + 1103 + ret = kmod_config_init(test_dev); 1104 + if (ret < 0) { 1105 + pr_err("Cannot alloc kmod_config_init()\n"); 1106 + goto err_out_free; 1107 + } 1108 + 1109 + test_dev->dev_idx = idx; 1110 + misc_dev = &test_dev->misc_dev; 1111 + 1112 + misc_dev->minor = MISC_DYNAMIC_MINOR; 1113 + misc_dev->name = kasprintf(GFP_KERNEL, "test_kmod%d", idx); 1114 + if (!misc_dev->name) { 1115 + pr_err("Cannot alloc misc_dev->name\n"); 1116 + goto err_out_free_config; 1117 + } 1118 + misc_dev->groups = test_dev_groups; 1119 + 1120 + return test_dev; 1121 + 1122 + err_out_free_config: 1123 + free_test_dev_info(test_dev); 1124 + kmod_config_free(test_dev); 1125 + err_out_free: 1126 + vfree(test_dev); 1127 + test_dev = NULL; 1128 + err_out: 1129 + return NULL; 1130 + } 1131 + 1132 + static void free_test_dev_kmod(struct kmod_test_device *test_dev) 1133 + { 1134 + if (test_dev) { 1135 + kfree_const(test_dev->misc_dev.name); 1136 + test_dev->misc_dev.name = NULL; 1137 + free_test_dev_info(test_dev); 1138 + kmod_config_free(test_dev); 1139 + vfree(test_dev); 1140 + test_dev = NULL; 1141 + } 1142 + } 1143 + 1144 + static struct kmod_test_device *register_test_dev_kmod(void) 1145 + { 1146 + struct kmod_test_device *test_dev = NULL; 1147 + int ret; 1148 + 1149 + mutex_unlock(&reg_dev_mutex); 1150 + 1151 + /* int should suffice for number of devices, test for wrap */ 1152 + if (unlikely(num_test_devs + 1) < 0) { 1153 + pr_err("reached limit of number of test devices\n"); 1154 + goto out; 1155 + } 1156 + 1157 + test_dev = alloc_test_dev_kmod(num_test_devs); 1158 + if (!test_dev) 1159 + goto out; 1160 + 1161 + ret = misc_register(&test_dev->misc_dev); 1162 + if (ret) { 1163 + pr_err("could not register misc device: %d\n", ret); 1164 + free_test_dev_kmod(test_dev); 1165 + goto out; 1166 + } 1167 + 1168 + test_dev->dev = test_dev->misc_dev.this_device; 1169 + list_add_tail(&test_dev->list, &reg_test_devs); 1170 + dev_info(test_dev->dev, "interface ready\n"); 1171 + 1172 + num_test_devs++; 1173 + 1174 + out: 1175 + mutex_unlock(&reg_dev_mutex); 1176 + 1177 + return test_dev; 1178 + 1179 + } 1180 + 1181 + static int __init test_kmod_init(void) 1182 + { 1183 + struct kmod_test_device *test_dev; 1184 + int ret; 1185 + 1186 + test_dev = register_test_dev_kmod(); 1187 + if (!test_dev) { 1188 + pr_err("Cannot add first test kmod device\n"); 1189 + return -ENODEV; 1190 + } 1191 + 1192 + /* 1193 + * With some work we might be able to gracefully enable 1194 + * testing with this driver built-in, for now this seems 1195 + * rather risky. For those willing to try have at it, 1196 + * and enable the below. Good luck! If that works, try 1197 + * lowering the init level for more fun. 1198 + */ 1199 + if (force_init_test) { 1200 + ret = trigger_config_run_type(test_dev, 1201 + TEST_KMOD_DRIVER, "tun"); 1202 + if (WARN_ON(ret)) 1203 + return ret; 1204 + ret = trigger_config_run_type(test_dev, 1205 + TEST_KMOD_FS_TYPE, "btrfs"); 1206 + if (WARN_ON(ret)) 1207 + return ret; 1208 + } 1209 + 1210 + return 0; 1211 + } 1212 + late_initcall(test_kmod_init); 1213 + 1214 + static 1215 + void unregister_test_dev_kmod(struct kmod_test_device *test_dev) 1216 + { 1217 + mutex_lock(&test_dev->trigger_mutex); 1218 + mutex_lock(&test_dev->config_mutex); 1219 + 1220 + test_dev_kmod_stop_tests(test_dev); 1221 + 1222 + dev_info(test_dev->dev, "removing interface\n"); 1223 + misc_deregister(&test_dev->misc_dev); 1224 + kfree(&test_dev->misc_dev.name); 1225 + 1226 + mutex_unlock(&test_dev->config_mutex); 1227 + mutex_unlock(&test_dev->trigger_mutex); 1228 + 1229 + free_test_dev_kmod(test_dev); 1230 + } 1231 + 1232 + static void __exit test_kmod_exit(void) 1233 + { 1234 + struct kmod_test_device *test_dev, *tmp; 1235 + 1236 + mutex_lock(&reg_dev_mutex); 1237 + list_for_each_entry_safe(test_dev, tmp, &reg_test_devs, list) { 1238 + list_del(&test_dev->list); 1239 + unregister_test_dev_kmod(test_dev); 1240 + } 1241 + mutex_unlock(&reg_dev_mutex); 1242 + } 1243 + module_exit(test_kmod_exit); 1244 + 1245 + MODULE_AUTHOR("Luis R. Rodriguez <mcgrof@kernel.org>"); 1246 + MODULE_LICENSE("GPL");
+1 -1
mm/mmap.c
··· 2231 2231 2232 2232 /* Guard against exceeding limits of the address space. */ 2233 2233 address &= PAGE_MASK; 2234 - if (address >= TASK_SIZE) 2234 + if (address >= (TASK_SIZE & PAGE_MASK)) 2235 2235 return -ENOMEM; 2236 2236 address += PAGE_SIZE; 2237 2237
+11
tools/testing/selftests/kmod/Makefile
··· 1 + # Makefile for kmod loading selftests 2 + 3 + # No binaries, but make sure arg-less "make" doesn't trigger "run_tests" 4 + all: 5 + 6 + TEST_PROGS := kmod.sh 7 + 8 + include ../lib.mk 9 + 10 + # Nothing to clean up. 11 + clean:
+7
tools/testing/selftests/kmod/config
··· 1 + CONFIG_TEST_KMOD=m 2 + CONFIG_TEST_LKM=m 3 + CONFIG_XFS_FS=m 4 + 5 + # For the module parameter force_init_test is used 6 + CONFIG_TUN=m 7 + CONFIG_BTRFS_FS=m
+615
tools/testing/selftests/kmod/kmod.sh
··· 1 + #!/bin/bash 2 + # 3 + # Copyright (C) 2017 Luis R. Rodriguez <mcgrof@kernel.org> 4 + # 5 + # This program is free software; you can redistribute it and/or modify it 6 + # under the terms of the GNU General Public License as published by the Free 7 + # Software Foundation; either version 2 of the License, or at your option any 8 + # later version; or, when distributed separately from the Linux kernel or 9 + # when incorporated into other software packages, subject to the following 10 + # license: 11 + # 12 + # This program is free software; you can redistribute it and/or modify it 13 + # under the terms of copyleft-next (version 0.3.1 or later) as published 14 + # at http://copyleft-next.org/. 15 + 16 + # This is a stress test script for kmod, the kernel module loader. It uses 17 + # test_kmod which exposes a series of knobs for the API for us so we can 18 + # tweak each test in userspace rather than in kernelspace. 19 + # 20 + # The way kmod works is it uses the kernel's usermode helper API to eventually 21 + # call /sbin/modprobe. It has a limit of the number of concurrent calls 22 + # possible. The kernel interface to load modules is request_module(), however 23 + # mount uses get_fs_type(). Both behave slightly differently, but the 24 + # differences are important enough to test each call separately. For this 25 + # reason test_kmod starts by providing tests for both calls. 26 + # 27 + # The test driver test_kmod assumes a series of defaults which you can 28 + # override by exporting to your environment prior running this script. 29 + # For instance this script assumes you do not have xfs loaded upon boot. 30 + # If this is false, export DEFAULT_KMOD_FS="ext4" prior to running this 31 + # script if the filesyste module you don't have loaded upon bootup 32 + # is ext4 instead. Refer to allow_user_defaults() for a list of user 33 + # override variables possible. 34 + # 35 + # You'll want at least 4 GiB of RAM to expect to run these tests 36 + # without running out of memory on them. For other requirements refer 37 + # to test_reqs() 38 + 39 + set -e 40 + 41 + TEST_NAME="kmod" 42 + TEST_DRIVER="test_${TEST_NAME}" 43 + TEST_DIR=$(dirname $0) 44 + 45 + # This represents 46 + # 47 + # TEST_ID:TEST_COUNT:ENABLED 48 + # 49 + # TEST_ID: is the test id number 50 + # TEST_COUNT: number of times we should run the test 51 + # ENABLED: 1 if enabled, 0 otherwise 52 + # 53 + # Once these are enabled please leave them as-is. Write your own test, 54 + # we have tons of space. 55 + ALL_TESTS="0001:3:1" 56 + ALL_TESTS="$ALL_TESTS 0002:3:1" 57 + ALL_TESTS="$ALL_TESTS 0003:1:1" 58 + ALL_TESTS="$ALL_TESTS 0004:1:1" 59 + ALL_TESTS="$ALL_TESTS 0005:10:1" 60 + ALL_TESTS="$ALL_TESTS 0006:10:1" 61 + ALL_TESTS="$ALL_TESTS 0007:5:1" 62 + ALL_TESTS="$ALL_TESTS 0008:150:1" 63 + ALL_TESTS="$ALL_TESTS 0009:150:1" 64 + 65 + test_modprobe() 66 + { 67 + if [ ! -d $DIR ]; then 68 + echo "$0: $DIR not present" >&2 69 + echo "You must have the following enabled in your kernel:" >&2 70 + cat $TEST_DIR/config >&2 71 + exit 1 72 + fi 73 + } 74 + 75 + function allow_user_defaults() 76 + { 77 + if [ -z $DEFAULT_KMOD_DRIVER ]; then 78 + DEFAULT_KMOD_DRIVER="test_module" 79 + fi 80 + 81 + if [ -z $DEFAULT_KMOD_FS ]; then 82 + DEFAULT_KMOD_FS="xfs" 83 + fi 84 + 85 + if [ -z $PROC_DIR ]; then 86 + PROC_DIR="/proc/sys/kernel/" 87 + fi 88 + 89 + if [ -z $MODPROBE_LIMIT ]; then 90 + MODPROBE_LIMIT=50 91 + fi 92 + 93 + if [ -z $DIR ]; then 94 + DIR="/sys/devices/virtual/misc/${TEST_DRIVER}0/" 95 + fi 96 + 97 + if [ -z $DEFAULT_NUM_TESTS ]; then 98 + DEFAULT_NUM_TESTS=150 99 + fi 100 + 101 + MODPROBE_LIMIT_FILE="${PROC_DIR}/kmod-limit" 102 + } 103 + 104 + test_reqs() 105 + { 106 + if ! which modprobe 2> /dev/null > /dev/null; then 107 + echo "$0: You need modprobe installed" >&2 108 + exit 1 109 + fi 110 + 111 + if ! which kmod 2> /dev/null > /dev/null; then 112 + echo "$0: You need kmod installed" >&2 113 + exit 1 114 + fi 115 + 116 + # kmod 19 has a bad bug where it returns 0 when modprobe 117 + # gets called *even* if the module was not loaded due to 118 + # some bad heuristics. For details see: 119 + # 120 + # A work around is possible in-kernel but its rather 121 + # complex. 122 + KMOD_VERSION=$(kmod --version | awk '{print $3}') 123 + if [[ $KMOD_VERSION -le 19 ]]; then 124 + echo "$0: You need at least kmod 20" >&2 125 + echo "kmod <= 19 is buggy, for details see:" >&2 126 + echo "http://git.kernel.org/cgit/utils/kernel/kmod/kmod.git/commit/libkmod/libkmod-module.c?id=fd44a98ae2eb5eb32161088954ab21e58e19dfc4" >&2 127 + exit 1 128 + fi 129 + 130 + uid=$(id -u) 131 + if [ $uid -ne 0 ]; then 132 + echo $msg must be run as root >&2 133 + exit 0 134 + fi 135 + } 136 + 137 + function load_req_mod() 138 + { 139 + trap "test_modprobe" EXIT 140 + 141 + if [ ! -d $DIR ]; then 142 + # Alanis: "Oh isn't it ironic?" 143 + modprobe $TEST_DRIVER 144 + fi 145 + } 146 + 147 + test_finish() 148 + { 149 + echo "Test completed" 150 + } 151 + 152 + errno_name_to_val() 153 + { 154 + case "$1" in 155 + # kmod calls modprobe and upon of a module not found 156 + # modprobe returns just 1... However in the kernel we 157 + # *sometimes* see 256... 158 + MODULE_NOT_FOUND) 159 + echo 256;; 160 + SUCCESS) 161 + echo 0;; 162 + -EPERM) 163 + echo -1;; 164 + -ENOENT) 165 + echo -2;; 166 + -EINVAL) 167 + echo -22;; 168 + -ERR_ANY) 169 + echo -123456;; 170 + *) 171 + echo invalid;; 172 + esac 173 + } 174 + 175 + errno_val_to_name() 176 + case "$1" in 177 + 256) 178 + echo MODULE_NOT_FOUND;; 179 + 0) 180 + echo SUCCESS;; 181 + -1) 182 + echo -EPERM;; 183 + -2) 184 + echo -ENOENT;; 185 + -22) 186 + echo -EINVAL;; 187 + -123456) 188 + echo -ERR_ANY;; 189 + *) 190 + echo invalid;; 191 + esac 192 + 193 + config_set_test_case_driver() 194 + { 195 + if ! echo -n 1 >$DIR/config_test_case; then 196 + echo "$0: Unable to set to test case to driver" >&2 197 + exit 1 198 + fi 199 + } 200 + 201 + config_set_test_case_fs() 202 + { 203 + if ! echo -n 2 >$DIR/config_test_case; then 204 + echo "$0: Unable to set to test case to fs" >&2 205 + exit 1 206 + fi 207 + } 208 + 209 + config_num_threads() 210 + { 211 + if ! echo -n $1 >$DIR/config_num_threads; then 212 + echo "$0: Unable to set to number of threads" >&2 213 + exit 1 214 + fi 215 + } 216 + 217 + config_get_modprobe_limit() 218 + { 219 + if [[ -f ${MODPROBE_LIMIT_FILE} ]] ; then 220 + MODPROBE_LIMIT=$(cat $MODPROBE_LIMIT_FILE) 221 + fi 222 + echo $MODPROBE_LIMIT 223 + } 224 + 225 + config_num_thread_limit_extra() 226 + { 227 + MODPROBE_LIMIT=$(config_get_modprobe_limit) 228 + let EXTRA_LIMIT=$MODPROBE_LIMIT+$1 229 + config_num_threads $EXTRA_LIMIT 230 + } 231 + 232 + # For special characters use printf directly, 233 + # refer to kmod_test_0001 234 + config_set_driver() 235 + { 236 + if ! echo -n $1 >$DIR/config_test_driver; then 237 + echo "$0: Unable to set driver" >&2 238 + exit 1 239 + fi 240 + } 241 + 242 + config_set_fs() 243 + { 244 + if ! echo -n $1 >$DIR/config_test_fs; then 245 + echo "$0: Unable to set driver" >&2 246 + exit 1 247 + fi 248 + } 249 + 250 + config_get_driver() 251 + { 252 + cat $DIR/config_test_driver 253 + } 254 + 255 + config_get_test_result() 256 + { 257 + cat $DIR/test_result 258 + } 259 + 260 + config_reset() 261 + { 262 + if ! echo -n "1" >"$DIR"/reset; then 263 + echo "$0: reset shuld have worked" >&2 264 + exit 1 265 + fi 266 + } 267 + 268 + config_show_config() 269 + { 270 + echo "----------------------------------------------------" 271 + cat "$DIR"/config 272 + echo "----------------------------------------------------" 273 + } 274 + 275 + config_trigger() 276 + { 277 + if ! echo -n "1" >"$DIR"/trigger_config 2>/dev/null; then 278 + echo "$1: FAIL - loading should have worked" 279 + config_show_config 280 + exit 1 281 + fi 282 + echo "$1: OK! - loading kmod test" 283 + } 284 + 285 + config_trigger_want_fail() 286 + { 287 + if echo "1" > $DIR/trigger_config 2>/dev/null; then 288 + echo "$1: FAIL - test case was expected to fail" 289 + config_show_config 290 + exit 1 291 + fi 292 + echo "$1: OK! - kmod test case failed as expected" 293 + } 294 + 295 + config_expect_result() 296 + { 297 + RC=$(config_get_test_result) 298 + RC_NAME=$(errno_val_to_name $RC) 299 + 300 + ERRNO_NAME=$2 301 + ERRNO=$(errno_name_to_val $ERRNO_NAME) 302 + 303 + if [[ $ERRNO_NAME = "-ERR_ANY" ]]; then 304 + if [[ $RC -ge 0 ]]; then 305 + echo "$1: FAIL, test expects $ERRNO_NAME - got $RC_NAME ($RC)" >&2 306 + config_show_config 307 + exit 1 308 + fi 309 + elif [[ $RC != $ERRNO ]]; then 310 + echo "$1: FAIL, test expects $ERRNO_NAME ($ERRNO) - got $RC_NAME ($RC)" >&2 311 + config_show_config 312 + exit 1 313 + fi 314 + echo "$1: OK! - Return value: $RC ($RC_NAME), expected $ERRNO_NAME" 315 + } 316 + 317 + kmod_defaults_driver() 318 + { 319 + config_reset 320 + modprobe -r $DEFAULT_KMOD_DRIVER 321 + config_set_driver $DEFAULT_KMOD_DRIVER 322 + } 323 + 324 + kmod_defaults_fs() 325 + { 326 + config_reset 327 + modprobe -r $DEFAULT_KMOD_FS 328 + config_set_fs $DEFAULT_KMOD_FS 329 + config_set_test_case_fs 330 + } 331 + 332 + kmod_test_0001_driver() 333 + { 334 + NAME='\000' 335 + 336 + kmod_defaults_driver 337 + config_num_threads 1 338 + printf '\000' >"$DIR"/config_test_driver 339 + config_trigger ${FUNCNAME[0]} 340 + config_expect_result ${FUNCNAME[0]} MODULE_NOT_FOUND 341 + } 342 + 343 + kmod_test_0001_fs() 344 + { 345 + NAME='\000' 346 + 347 + kmod_defaults_fs 348 + config_num_threads 1 349 + printf '\000' >"$DIR"/config_test_fs 350 + config_trigger ${FUNCNAME[0]} 351 + config_expect_result ${FUNCNAME[0]} -EINVAL 352 + } 353 + 354 + kmod_test_0001() 355 + { 356 + kmod_test_0001_driver 357 + kmod_test_0001_fs 358 + } 359 + 360 + kmod_test_0002_driver() 361 + { 362 + NAME="nope-$DEFAULT_KMOD_DRIVER" 363 + 364 + kmod_defaults_driver 365 + config_set_driver $NAME 366 + config_num_threads 1 367 + config_trigger ${FUNCNAME[0]} 368 + config_expect_result ${FUNCNAME[0]} MODULE_NOT_FOUND 369 + } 370 + 371 + kmod_test_0002_fs() 372 + { 373 + NAME="nope-$DEFAULT_KMOD_FS" 374 + 375 + kmod_defaults_fs 376 + config_set_fs $NAME 377 + config_trigger ${FUNCNAME[0]} 378 + config_expect_result ${FUNCNAME[0]} -EINVAL 379 + } 380 + 381 + kmod_test_0002() 382 + { 383 + kmod_test_0002_driver 384 + kmod_test_0002_fs 385 + } 386 + 387 + kmod_test_0003() 388 + { 389 + kmod_defaults_fs 390 + config_num_threads 1 391 + config_trigger ${FUNCNAME[0]} 392 + config_expect_result ${FUNCNAME[0]} SUCCESS 393 + } 394 + 395 + kmod_test_0004() 396 + { 397 + kmod_defaults_fs 398 + config_num_threads 2 399 + config_trigger ${FUNCNAME[0]} 400 + config_expect_result ${FUNCNAME[0]} SUCCESS 401 + } 402 + 403 + kmod_test_0005() 404 + { 405 + kmod_defaults_driver 406 + config_trigger ${FUNCNAME[0]} 407 + config_expect_result ${FUNCNAME[0]} SUCCESS 408 + } 409 + 410 + kmod_test_0006() 411 + { 412 + kmod_defaults_fs 413 + config_trigger ${FUNCNAME[0]} 414 + config_expect_result ${FUNCNAME[0]} SUCCESS 415 + } 416 + 417 + kmod_test_0007() 418 + { 419 + kmod_test_0005 420 + kmod_test_0006 421 + } 422 + 423 + kmod_test_0008() 424 + { 425 + kmod_defaults_driver 426 + MODPROBE_LIMIT=$(config_get_modprobe_limit) 427 + let EXTRA=$MODPROBE_LIMIT/6 428 + config_num_thread_limit_extra $EXTRA 429 + config_trigger ${FUNCNAME[0]} 430 + config_expect_result ${FUNCNAME[0]} SUCCESS 431 + } 432 + 433 + kmod_test_0009() 434 + { 435 + kmod_defaults_fs 436 + MODPROBE_LIMIT=$(config_get_modprobe_limit) 437 + let EXTRA=$MODPROBE_LIMIT/4 438 + config_num_thread_limit_extra $EXTRA 439 + config_trigger ${FUNCNAME[0]} 440 + config_expect_result ${FUNCNAME[0]} SUCCESS 441 + } 442 + 443 + list_tests() 444 + { 445 + echo "Test ID list:" 446 + echo 447 + echo "TEST_ID x NUM_TEST" 448 + echo "TEST_ID: Test ID" 449 + echo "NUM_TESTS: Number of recommended times to run the test" 450 + echo 451 + echo "0001 x $(get_test_count 0001) - Simple test - 1 thread for empty string" 452 + echo "0002 x $(get_test_count 0002) - Simple test - 1 thread for modules/filesystems that do not exist" 453 + echo "0003 x $(get_test_count 0003) - Simple test - 1 thread for get_fs_type() only" 454 + echo "0004 x $(get_test_count 0004) - Simple test - 2 threads for get_fs_type() only" 455 + echo "0005 x $(get_test_count 0005) - multithreaded tests with default setup - request_module() only" 456 + echo "0006 x $(get_test_count 0006) - multithreaded tests with default setup - get_fs_type() only" 457 + echo "0007 x $(get_test_count 0007) - multithreaded tests with default setup test request_module() and get_fs_type()" 458 + echo "0008 x $(get_test_count 0008) - multithreaded - push kmod_concurrent over max_modprobes for request_module()" 459 + echo "0009 x $(get_test_count 0009) - multithreaded - push kmod_concurrent over max_modprobes for get_fs_type()" 460 + } 461 + 462 + usage() 463 + { 464 + NUM_TESTS=$(grep -o ' ' <<<"$ALL_TESTS" | grep -c .) 465 + let NUM_TESTS=$NUM_TESTS+1 466 + MAX_TEST=$(printf "%04d\n" $NUM_TESTS) 467 + echo "Usage: $0 [ -t <4-number-digit> ] | [ -w <4-number-digit> ] |" 468 + echo " [ -s <4-number-digit> ] | [ -c <4-number-digit> <test- count>" 469 + echo " [ all ] [ -h | --help ] [ -l ]" 470 + echo "" 471 + echo "Valid tests: 0001-$MAX_TEST" 472 + echo "" 473 + echo " all Runs all tests (default)" 474 + echo " -t Run test ID the number amount of times is recommended" 475 + echo " -w Watch test ID run until it runs into an error" 476 + echo " -c Run test ID once" 477 + echo " -s Run test ID x test-count number of times" 478 + echo " -l List all test ID list" 479 + echo " -h|--help Help" 480 + echo 481 + echo "If an error every occurs execution will immediately terminate." 482 + echo "If you are adding a new test try using -w <test-ID> first to" 483 + echo "make sure the test passes a series of tests." 484 + echo 485 + echo Example uses: 486 + echo 487 + echo "${TEST_NAME}.sh -- executes all tests" 488 + echo "${TEST_NAME}.sh -t 0008 -- Executes test ID 0008 number of times is recomended" 489 + echo "${TEST_NAME}.sh -w 0008 -- Watch test ID 0008 run until an error occurs" 490 + echo "${TEST_NAME}.sh -s 0008 -- Run test ID 0008 once" 491 + echo "${TEST_NAME}.sh -c 0008 3 -- Run test ID 0008 three times" 492 + echo 493 + list_tests 494 + exit 1 495 + } 496 + 497 + function test_num() 498 + { 499 + re='^[0-9]+$' 500 + if ! [[ $1 =~ $re ]]; then 501 + usage 502 + fi 503 + } 504 + 505 + function get_test_count() 506 + { 507 + test_num $1 508 + TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$1'}') 509 + LAST_TWO=${TEST_DATA#*:*} 510 + echo ${LAST_TWO%:*} 511 + } 512 + 513 + function get_test_enabled() 514 + { 515 + test_num $1 516 + TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$1'}') 517 + echo ${TEST_DATA#*:*:} 518 + } 519 + 520 + function run_all_tests() 521 + { 522 + for i in $ALL_TESTS ; do 523 + TEST_ID=${i%:*:*} 524 + ENABLED=$(get_test_enabled $TEST_ID) 525 + TEST_COUNT=$(get_test_count $TEST_ID) 526 + if [[ $ENABLED -eq "1" ]]; then 527 + test_case $TEST_ID $TEST_COUNT 528 + fi 529 + done 530 + } 531 + 532 + function watch_log() 533 + { 534 + if [ $# -ne 3 ]; then 535 + clear 536 + fi 537 + date 538 + echo "Running test: $2 - run #$1" 539 + } 540 + 541 + function watch_case() 542 + { 543 + i=0 544 + while [ 1 ]; do 545 + 546 + if [ $# -eq 1 ]; then 547 + test_num $1 548 + watch_log $i ${TEST_NAME}_test_$1 549 + ${TEST_NAME}_test_$1 550 + else 551 + watch_log $i all 552 + run_all_tests 553 + fi 554 + let i=$i+1 555 + done 556 + } 557 + 558 + function test_case() 559 + { 560 + NUM_TESTS=$DEFAULT_NUM_TESTS 561 + if [ $# -eq 2 ]; then 562 + NUM_TESTS=$2 563 + fi 564 + 565 + i=0 566 + while [ $i -lt $NUM_TESTS ]; do 567 + test_num $1 568 + watch_log $i ${TEST_NAME}_test_$1 noclear 569 + RUN_TEST=${TEST_NAME}_test_$1 570 + $RUN_TEST 571 + let i=$i+1 572 + done 573 + } 574 + 575 + function parse_args() 576 + { 577 + if [ $# -eq 0 ]; then 578 + run_all_tests 579 + else 580 + if [[ "$1" = "all" ]]; then 581 + run_all_tests 582 + elif [[ "$1" = "-w" ]]; then 583 + shift 584 + watch_case $@ 585 + elif [[ "$1" = "-t" ]]; then 586 + shift 587 + test_num $1 588 + test_case $1 $(get_test_count $1) 589 + elif [[ "$1" = "-c" ]]; then 590 + shift 591 + test_num $1 592 + test_num $2 593 + test_case $1 $2 594 + elif [[ "$1" = "-s" ]]; then 595 + shift 596 + test_case $1 1 597 + elif [[ "$1" = "-l" ]]; then 598 + list_tests 599 + elif [[ "$1" = "-h" || "$1" = "--help" ]]; then 600 + usage 601 + else 602 + usage 603 + fi 604 + fi 605 + } 606 + 607 + test_reqs 608 + allow_user_defaults 609 + load_req_mod 610 + 611 + trap "test_finish" EXIT 612 + 613 + parse_args $@ 614 + 615 + exit 0