[Fault-injection-developer] make one-to-multi relationship between trigger and code segment
Status: Alpha
Brought to you by:
rustyl
From: Zhuang, L. <lou...@in...> - 2003-01-08 05:21:37
|
Dear all, As we agreed previous email, I make multi code-segments attach to one trigger. You can see it in /sys/fault-injection/trigger/<tri_name>/opcode. - Louis You can import this changeset into BK by piping this whole message to: '| bk receive [path to repository]' or apply the patch as usual. =================================================================== ChangeSet@1.977.1.1, 2003-01-08 12:59:15+08:00, lo...@ha... make one-to-multi relationship between trigger and code segment drivers/fi/fi_core.c | 89 +++++++++++++++++++++++++++++++++++---------------- include/linux/fi.h | 3 + 2 files changed, 64 insertions(+), 28 deletions(-) diff -Nru a/drivers/fi/fi_core.c b/drivers/fi/fi_core.c --- a/drivers/fi/fi_core.c Wed Jan 8 13:06:52 2003 +++ b/drivers/fi/fi_core.c Wed Jan 8 13:06:52 2003 @@ -152,6 +152,7 @@ if (!n) return -ENOMEM; memset(n,0,sizeof(struct trigger)); + INIT_LIST_HEAD(&n->cs_list); strncpy(n->kobj.name, t->kobj.name, KOBJ_NAME_LEN); n->kobj.subsys = &trigger_subsys; @@ -186,19 +187,38 @@ return 0; } -static inline ssize_t del_trigger(struct trigger *t) +static inline void del_code_segment(struct code_segment *cs) +{ + struct trigger *t = cs->tri; + + list_del(&cs->list); + cs->tri = NULL; + kobject_put(&cs->kobj); + kobject_put(&t->kobj); +} + +static inline void del_cs_list(struct list_head *head) { + struct list_head *pos; + struct list_head *tmp; + list_for_each_safe(pos, tmp, head) { + del_code_segment(list_entry(pos, struct code_segment, list)); + } +} + +static inline ssize_t del_trigger(const char *tri_name) { struct trigger * n; - n = find_trigger_by_name(t->kobj.name); + n = find_trigger_by_name(tri_name); if (n) { unarm_trigger(n); remove_trigger_files(n); + del_cs_list(&n->cs_list); kobject_unregister(&n->kobj); return 0; } - err("trigger %s does not exist", t->kobj.name); + err("trigger %s does not exist", tri_name); return -EINVAL; } @@ -214,22 +234,12 @@ sysfs_remove_file(&cs->kobj, &code_segment_attr_trigger.attr); } -static inline void arm_code_segment(struct code_segment *cs, struct trigger *t) +static inline void add_code_segment(struct code_segment *cs, struct trigger *t) { kobject_get(&t->kobj); kobject_get(&cs->kobj); + list_add(&cs->list, &t->cs_list); cs->tri = t; - t->cs = cs; -} - -static inline void unarm_code_segment(struct code_segment *cs) -{ - struct trigger *t = cs->tri; - - t->cs = NULL; - cs->tri = NULL; - kobject_put(&cs->kobj); - kobject_put(&t->kobj); } /* @@ -480,17 +490,33 @@ .show = trigger_intcpt_read, }; +static inline ssize_t print_cs_list(struct list_head *head, + char *page, int count) +{ + int i = 0; + struct code_segment *pos; + list_for_each_entry(pos, head, list) { + i += snprintf(page+i, count-i, + "code segment name: %s\n", + pos->kobj.name); + } + return i; +} + static ssize_t trigger_opcode_read(struct trigger * p, char * page, size_t count, loff_t off) { dbg("opcode = %i", p->opcode); if (off) return 0; - if (p->cs) { - return snprintf(page,count,"cs name: %s\n",p->cs->kobj.name); - } else { + if (list_empty(&p->cs_list)) { return snprintf(page,count,"op code: %i\n",p->opcode); + } else { + int i; + i = print_cs_list(&p->cs_list, page, count); + return i; } } + static struct trigger_attribute trigger_attr_opcode = { .attr = { .name = "opcode", .mode = S_IRUGO }, .show = trigger_opcode_read, @@ -501,12 +527,13 @@ { dbg("operand = %i", p->operand); if (off) return 0; - if (p->cs) { - return snprintf(page,count,"(no used)\n"); - } else { + if (list_empty(&p->cs_list)) { return snprintf(page,count,"%i\n",p->operand); + } else { + return snprintf(page,count,"(no used)\n"); } } + static struct trigger_attribute trigger_attr_operand = { .attr = { .name = "operand", .mode = S_IRUGO }, .show = trigger_operand_read, @@ -517,6 +544,7 @@ { return 0; } + static ssize_t trigger_ctl_store(struct subsystem * s, const char * page, size_t count, loff_t off) { @@ -556,7 +584,7 @@ dbg("intcpt = '%s'", intcpt); ret = add_trigger(&tmp, intcpt); } else if (!strcmp(ctl,"del") && num == 2) { - ret = del_trigger(&tmp); + ret = del_trigger(tmp.kobj.name); } else { err("Invalid command format: %s, %i tokens found",ctl,num); ret = -EINVAL; @@ -647,11 +675,15 @@ sscanf(page, "%s", tri_name); - if (cs->tri) unarm_code_segment(cs); + if (cs->tri) del_code_segment(cs); dbg("Try to find %s trigger", tri_name); t = find_trigger_by_name(tri_name); - if(t) arm_code_segment(cs, t); + if (t) { + add_code_segment(cs, t); + } else { + err("Unable to find trigger %s", tri_name); + } return count; } @@ -725,8 +757,11 @@ dbg("count=%d, skip=%d, min=%d, max=%d, val=%d", atomic_read(&t->count), t->skip, t->min, t->max, val); - if (t->cs) { - t->cs->execute_trigger(t, i, val, len, type, data); + if (!list_empty(&t->cs_list)) { + struct code_segment *pos; + list_for_each_entry (pos, &t->cs_list, list) { + pos->execute_trigger(t, i, val, len, type, data); + } return; } @@ -812,7 +847,7 @@ void fi_unregister_code_segment(struct code_segment *cs) { - if (cs->tri) unarm_code_segment(cs); + if (cs->tri) del_code_segment(cs); remove_code_segment_files(cs); kobject_unregister(&cs->kobj); } diff -Nru a/include/linux/fi.h b/include/linux/fi.h --- a/include/linux/fi.h Wed Jan 8 13:06:52 2003 +++ b/include/linux/fi.h Wed Jan 8 13:06:52 2003 @@ -56,6 +56,7 @@ struct trigger; struct interceptor; struct code_segment { + struct list_head list; void (*execute_trigger) (struct trigger *t, struct interceptor *i, __u32 val, @@ -76,7 +77,7 @@ int protection; int hertz; int registered; - struct code_segment *cs; + struct list_head cs_list; struct interceptor *intcpt; atomic_t count; /* opaque data struct for register */ Yours truly, Louis Zhuang --------------- Fault Injection Test Harness Project BK tree: http://fault-injection.bkbits.net/linux-2.5 Home Page: http://sf.net/projects/fault-injection |