23 #include <linux/kernel.h> 29 #include <linux/debugfs.h> 30 #include <linux/kernel.h> 31 #include <linux/module.h> 32 #include <linux/seq_file.h> 33 #include <linux/uaccess.h> 34 #include <linux/string.h> 35 #include <linux/ctype.h> 36 #include <linux/slab.h> 101 static struct dentry *fi_dir;
102 static const char fi_dir_name[] =
"finject";
103 static bool fi_ctl_is_opened =
false;
106 static void *fi_stat_start(
struct seq_file *
seq, loff_t *pos)
109 return SEQ_START_TOKEN;
118 static void *fi_stat_next(
struct seq_file *
seq,
void *v, loff_t *pos)
120 loff_t cur_pos = (*pos)++;
129 static void fi_stat_stop(
struct seq_file *
seq,
void *v)
133 static int fi_stat_show(
struct seq_file *
seq,
void *v)
139 if (SEQ_START_TOKEN == v) {
153 si.si_idx,
si.si_enb,
si.si_total_hit_cnt,
154 si.si_total_trigger_cnt,
si.si_hit_cnt,
155 si.si_trigger_cnt,
si.si_type,
si.si_data,
156 si.si_module,
si.si_file,
si.si_line_num,
157 si.si_func,
si.si_tag);
162 static const struct seq_operations fi_stat_sops = {
163 .start = fi_stat_start,
164 .stop = fi_stat_stop,
165 .next = fi_stat_next,
166 .show = fi_stat_show,
169 static int fi_stat_open(
struct inode *
i,
struct file *
f)
173 rc = seq_open(
f, &fi_stat_sops);
176 struct seq_file *sf =
f->private_data;
177 sf->private =
i->i_private;
183 static const struct file_operations fi_stat_fops = {
184 .owner = THIS_MODULE,
185 .open = fi_stat_open,
188 .release = seq_release,
191 static int fi_ctl_open(
struct inode *
i,
struct file *
f)
193 if (fi_ctl_is_opened)
196 fi_ctl_is_opened =
true;
201 static int fi_ctl_release(
struct inode *
i,
struct file *
f)
203 fi_ctl_is_opened =
false;
207 static int fi_ctl_process_cmd(
int argc,
char *argv[])
211 pr_err(KBUILD_MODNAME
": finject_ctl too few arguments\n");
215 if (strcmp(argv[0],
"enable") == 0) {
222 pr_err(KBUILD_MODNAME
": finject_ctl too few arguments" 223 " for command '%s'\n", argv[0]);
247 if (strcmp(argv[3],
"always") == 0) {
249 pr_err(KBUILD_MODNAME
": finject_ctl too many" 250 " arguments for command '%s'\n", argv[0]);
254 }
else if (strcmp(argv[3],
"oneshot") == 0) {
256 pr_err(KBUILD_MODNAME
": finject_ctl too many" 257 " arguments for command '%s'\n", argv[0]);
261 }
else if (strcmp(argv[3],
"random") == 0) {
264 pr_err(KBUILD_MODNAME
": finject_ctl incorrect" 265 " number of arguments for FP type '%s'\n",
269 rc = kstrtoul(argv[4], 0, &
p);
273 }
else if (strcmp(argv[3],
"off_n_on_m") == 0) {
277 pr_err(KBUILD_MODNAME
": finject_ctl incorrect" 278 " number of arguments for FP type '%s'\n",
282 rc = kstrtoul(argv[4], 0, &
n);
285 rc = kstrtoul(argv[5], 0, &
m);
290 pr_err(KBUILD_MODNAME
": finject_ctl: invalid or not" 291 " allowed FP type '%s'\n", argv[3]);
294 }
else if (strcmp(argv[0],
"disable") == 0) {
297 pr_err(KBUILD_MODNAME
": finject_ctl: invalid action '%s'\n",
306 size_t size, loff_t *ppos)
310 ssize_t ret_size =
size;
339 if (!isprint(
buf[
i]))
342 pr_info(KBUILD_MODNAME
": finject_ctl command '%s'\n",
buf);
344 argv = argv_split(GFP_KERNEL,
buf, &argc);
348 rc = fi_ctl_process_cmd(argc, argv);
359 static const struct file_operations fi_ctl_fops = {
360 .owner = THIS_MODULE,
362 .release = fi_ctl_release,
363 .write = fi_ctl_write,
369 static const char stat_name[] =
"stat";
371 static const char ctl_name[] =
"ctl";
375 if (fi_dir ==
NULL) {
376 pr_err(KBUILD_MODNAME
": can't create debugfs dir '%s/%s'\n",
382 stat_file = debugfs_create_file(stat_name, S_IRUSR, fi_dir,
NULL,
384 if (stat_file ==
NULL) {
385 pr_err(KBUILD_MODNAME
": failed to create debugfs file" 391 ctl_file = debugfs_create_file(ctl_name, S_IWUSR, fi_dir,
NULL,
393 if (ctl_file ==
NULL) {
394 pr_err(KBUILD_MODNAME
": failed to create debugfs file" 402 debugfs_remove_recursive(fi_dir);
409 debugfs_remove_recursive(fi_dir);
418 pr_warning(KBUILD_MODNAME
": fault injection is not available, because it" 419 " was disabled during build\n");
static struct m0_addb2_philter p
static struct m0_addb2_mach * m
static uint64_t tag(uint8_t code, uint64_t id)
static char * user_buf[NR]
M0_INTERNAL const struct m0_fi_fpoint_state * m0_fi_states_get(void)
struct dentry * dfs_root_dir
static void m0_fi_enable_random(const char *func, const char *tag, uint32_t p)
void fi_dfs_cleanup(void)
M0_INTERNAL void m0_fi_disable(const char *fp_func, const char *fp_tag)
static void m0_fi_enable(const char *func, const char *tag)
static int struct dentry * dentry
M0_INTERNAL int m0_fi_add_dyn_id(char *str)
const char m0_fi_states_print_format[]
const char dfs_root_name[]
static void m0_fi_enable_off_n_on_m(const char *func, const char *tag, uint32_t n, uint32_t m)
M0_INTERNAL uint32_t m0_fi_states_get_free_idx(void)
static void m0_fi_enable_once(const char *func, const char *tag)
M0_INTERNAL void m0_fi_states_get_state_info(const struct m0_fi_fpoint_state *s, struct m0_fi_fpoint_state_info *si)
const char * m0_fi_states_headline[]
static struct sync_interactions si