diff options
Diffstat (limited to 'lib/fault-inject.c')
| -rw-r--r-- | lib/fault-inject.c | 156 |
1 files changed, 44 insertions, 112 deletions
diff --git a/lib/fault-inject.c b/lib/fault-inject.c index 7e65af70635e..f193b7796449 100644 --- a/lib/fault-inject.c +++ b/lib/fault-inject.c | |||
| @@ -8,7 +8,6 @@ | |||
| 8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
| 9 | #include <linux/interrupt.h> | 9 | #include <linux/interrupt.h> |
| 10 | #include <linux/stacktrace.h> | 10 | #include <linux/stacktrace.h> |
| 11 | #include <linux/kallsyms.h> | ||
| 12 | #include <linux/fault-inject.h> | 11 | #include <linux/fault-inject.h> |
| 13 | 12 | ||
| 14 | /* | 13 | /* |
| @@ -140,16 +139,6 @@ static int debugfs_ul_set(void *data, u64 val) | |||
| 140 | return 0; | 139 | return 0; |
| 141 | } | 140 | } |
| 142 | 141 | ||
| 143 | #ifdef CONFIG_FAULT_INJECTION_STACKTRACE_FILTER | ||
| 144 | static int debugfs_ul_set_MAX_STACK_TRACE_DEPTH(void *data, u64 val) | ||
| 145 | { | ||
| 146 | *(unsigned long *)data = | ||
| 147 | val < MAX_STACK_TRACE_DEPTH ? | ||
| 148 | val : MAX_STACK_TRACE_DEPTH; | ||
| 149 | return 0; | ||
| 150 | } | ||
| 151 | #endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */ | ||
| 152 | |||
| 153 | static int debugfs_ul_get(void *data, u64 *val) | 142 | static int debugfs_ul_get(void *data, u64 *val) |
| 154 | { | 143 | { |
| 155 | *val = *(unsigned long *)data; | 144 | *val = *(unsigned long *)data; |
| @@ -165,16 +154,26 @@ static struct dentry *debugfs_create_ul(const char *name, mode_t mode, | |||
| 165 | } | 154 | } |
| 166 | 155 | ||
| 167 | #ifdef CONFIG_FAULT_INJECTION_STACKTRACE_FILTER | 156 | #ifdef CONFIG_FAULT_INJECTION_STACKTRACE_FILTER |
| 168 | DEFINE_SIMPLE_ATTRIBUTE(fops_ul_MAX_STACK_TRACE_DEPTH, debugfs_ul_get, | ||
| 169 | debugfs_ul_set_MAX_STACK_TRACE_DEPTH, "%llu\n"); | ||
| 170 | 157 | ||
| 171 | static struct dentry *debugfs_create_ul_MAX_STACK_TRACE_DEPTH( | 158 | static int debugfs_stacktrace_depth_set(void *data, u64 val) |
| 159 | { | ||
| 160 | *(unsigned long *)data = | ||
| 161 | min_t(unsigned long, val, MAX_STACK_TRACE_DEPTH); | ||
| 162 | |||
| 163 | return 0; | ||
| 164 | } | ||
| 165 | |||
| 166 | DEFINE_SIMPLE_ATTRIBUTE(fops_stacktrace_depth, debugfs_ul_get, | ||
| 167 | debugfs_stacktrace_depth_set, "%llu\n"); | ||
| 168 | |||
| 169 | static struct dentry *debugfs_create_stacktrace_depth( | ||
| 172 | const char *name, mode_t mode, | 170 | const char *name, mode_t mode, |
| 173 | struct dentry *parent, unsigned long *value) | 171 | struct dentry *parent, unsigned long *value) |
| 174 | { | 172 | { |
| 175 | return debugfs_create_file(name, mode, parent, value, | 173 | return debugfs_create_file(name, mode, parent, value, |
| 176 | &fops_ul_MAX_STACK_TRACE_DEPTH); | 174 | &fops_stacktrace_depth); |
| 177 | } | 175 | } |
| 176 | |||
| 178 | #endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */ | 177 | #endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */ |
| 179 | 178 | ||
| 180 | static int debugfs_atomic_t_set(void *data, u64 val) | 179 | static int debugfs_atomic_t_set(void *data, u64 val) |
| @@ -198,118 +197,51 @@ static struct dentry *debugfs_create_atomic_t(const char *name, mode_t mode, | |||
| 198 | return debugfs_create_file(name, mode, parent, value, &fops_atomic_t); | 197 | return debugfs_create_file(name, mode, parent, value, &fops_atomic_t); |
| 199 | } | 198 | } |
| 200 | 199 | ||
| 201 | void cleanup_fault_attr_dentries(struct fault_attr *attr) | 200 | struct dentry *fault_create_debugfs_attr(const char *name, |
| 202 | { | 201 | struct dentry *parent, struct fault_attr *attr) |
| 203 | debugfs_remove(attr->dentries.probability_file); | ||
| 204 | attr->dentries.probability_file = NULL; | ||
| 205 | |||
| 206 | debugfs_remove(attr->dentries.interval_file); | ||
| 207 | attr->dentries.interval_file = NULL; | ||
| 208 | |||
| 209 | debugfs_remove(attr->dentries.times_file); | ||
| 210 | attr->dentries.times_file = NULL; | ||
| 211 | |||
| 212 | debugfs_remove(attr->dentries.space_file); | ||
| 213 | attr->dentries.space_file = NULL; | ||
| 214 | |||
| 215 | debugfs_remove(attr->dentries.verbose_file); | ||
| 216 | attr->dentries.verbose_file = NULL; | ||
| 217 | |||
| 218 | debugfs_remove(attr->dentries.task_filter_file); | ||
| 219 | attr->dentries.task_filter_file = NULL; | ||
| 220 | |||
| 221 | #ifdef CONFIG_FAULT_INJECTION_STACKTRACE_FILTER | ||
| 222 | |||
| 223 | debugfs_remove(attr->dentries.stacktrace_depth_file); | ||
| 224 | attr->dentries.stacktrace_depth_file = NULL; | ||
| 225 | |||
| 226 | debugfs_remove(attr->dentries.require_start_file); | ||
| 227 | attr->dentries.require_start_file = NULL; | ||
| 228 | |||
| 229 | debugfs_remove(attr->dentries.require_end_file); | ||
| 230 | attr->dentries.require_end_file = NULL; | ||
| 231 | |||
| 232 | debugfs_remove(attr->dentries.reject_start_file); | ||
| 233 | attr->dentries.reject_start_file = NULL; | ||
| 234 | |||
| 235 | debugfs_remove(attr->dentries.reject_end_file); | ||
| 236 | attr->dentries.reject_end_file = NULL; | ||
| 237 | |||
| 238 | #endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */ | ||
| 239 | |||
| 240 | if (attr->dentries.dir) | ||
| 241 | WARN_ON(!simple_empty(attr->dentries.dir)); | ||
| 242 | |||
| 243 | debugfs_remove(attr->dentries.dir); | ||
| 244 | attr->dentries.dir = NULL; | ||
| 245 | } | ||
| 246 | |||
| 247 | int init_fault_attr_dentries(struct fault_attr *attr, const char *name) | ||
| 248 | { | 202 | { |
| 249 | mode_t mode = S_IFREG | S_IRUSR | S_IWUSR; | 203 | mode_t mode = S_IFREG | S_IRUSR | S_IWUSR; |
| 250 | struct dentry *dir; | 204 | struct dentry *dir; |
| 251 | 205 | ||
| 252 | memset(&attr->dentries, 0, sizeof(attr->dentries)); | 206 | dir = debugfs_create_dir(name, parent); |
| 253 | |||
| 254 | dir = debugfs_create_dir(name, NULL); | ||
| 255 | if (!dir) | 207 | if (!dir) |
| 256 | goto fail; | 208 | return ERR_PTR(-ENOMEM); |
| 257 | attr->dentries.dir = dir; | ||
| 258 | |||
| 259 | attr->dentries.probability_file = | ||
| 260 | debugfs_create_ul("probability", mode, dir, &attr->probability); | ||
| 261 | 209 | ||
| 262 | attr->dentries.interval_file = | 210 | if (!debugfs_create_ul("probability", mode, dir, &attr->probability)) |
| 263 | debugfs_create_ul("interval", mode, dir, &attr->interval); | 211 | goto fail; |
| 264 | 212 | if (!debugfs_create_ul("interval", mode, dir, &attr->interval)) | |
| 265 | attr->dentries.times_file = | 213 | goto fail; |
| 266 | debugfs_create_atomic_t("times", mode, dir, &attr->times); | 214 | if (!debugfs_create_atomic_t("times", mode, dir, &attr->times)) |
| 267 | 215 | goto fail; | |
| 268 | attr->dentries.space_file = | 216 | if (!debugfs_create_atomic_t("space", mode, dir, &attr->space)) |
| 269 | debugfs_create_atomic_t("space", mode, dir, &attr->space); | 217 | goto fail; |
| 270 | 218 | if (!debugfs_create_ul("verbose", mode, dir, &attr->verbose)) | |
| 271 | attr->dentries.verbose_file = | 219 | goto fail; |
| 272 | debugfs_create_ul("verbose", mode, dir, &attr->verbose); | 220 | if (!debugfs_create_bool("task-filter", mode, dir, &attr->task_filter)) |
| 273 | |||
| 274 | attr->dentries.task_filter_file = debugfs_create_bool("task-filter", | ||
| 275 | mode, dir, &attr->task_filter); | ||
| 276 | |||
| 277 | if (!attr->dentries.probability_file || !attr->dentries.interval_file || | ||
| 278 | !attr->dentries.times_file || !attr->dentries.space_file || | ||
| 279 | !attr->dentries.verbose_file || !attr->dentries.task_filter_file) | ||
| 280 | goto fail; | 221 | goto fail; |
| 281 | 222 | ||
| 282 | #ifdef CONFIG_FAULT_INJECTION_STACKTRACE_FILTER | 223 | #ifdef CONFIG_FAULT_INJECTION_STACKTRACE_FILTER |
| 283 | 224 | ||
| 284 | attr->dentries.stacktrace_depth_file = | 225 | if (!debugfs_create_stacktrace_depth("stacktrace-depth", mode, dir, |
| 285 | debugfs_create_ul_MAX_STACK_TRACE_DEPTH( | 226 | &attr->stacktrace_depth)) |
| 286 | "stacktrace-depth", mode, dir, &attr->stacktrace_depth); | 227 | goto fail; |
| 287 | 228 | if (!debugfs_create_ul("require-start", mode, dir, | |
| 288 | attr->dentries.require_start_file = | 229 | &attr->require_start)) |
| 289 | debugfs_create_ul("require-start", mode, dir, &attr->require_start); | 230 | goto fail; |
| 290 | 231 | if (!debugfs_create_ul("require-end", mode, dir, &attr->require_end)) | |
| 291 | attr->dentries.require_end_file = | 232 | goto fail; |
| 292 | debugfs_create_ul("require-end", mode, dir, &attr->require_end); | 233 | if (!debugfs_create_ul("reject-start", mode, dir, &attr->reject_start)) |
| 293 | 234 | goto fail; | |
| 294 | attr->dentries.reject_start_file = | 235 | if (!debugfs_create_ul("reject-end", mode, dir, &attr->reject_end)) |
| 295 | debugfs_create_ul("reject-start", mode, dir, &attr->reject_start); | ||
| 296 | |||
| 297 | attr->dentries.reject_end_file = | ||
| 298 | debugfs_create_ul("reject-end", mode, dir, &attr->reject_end); | ||
| 299 | |||
| 300 | if (!attr->dentries.stacktrace_depth_file || | ||
| 301 | !attr->dentries.require_start_file || | ||
| 302 | !attr->dentries.require_end_file || | ||
| 303 | !attr->dentries.reject_start_file || | ||
| 304 | !attr->dentries.reject_end_file) | ||
| 305 | goto fail; | 236 | goto fail; |
| 306 | 237 | ||
| 307 | #endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */ | 238 | #endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */ |
| 308 | 239 | ||
| 309 | return 0; | 240 | return dir; |
| 310 | fail: | 241 | fail: |
| 311 | cleanup_fault_attr_dentries(attr); | 242 | debugfs_remove_recursive(dir); |
| 312 | return -ENOMEM; | 243 | |
| 244 | return ERR_PTR(-ENOMEM); | ||
| 313 | } | 245 | } |
| 314 | 246 | ||
| 315 | #endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */ | 247 | #endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */ |
