Verify: Tighten header length check in verify_header()
[fio.git] / profile.c
1 #include "fio.h"
2 #include "profile.h"
3 #include "debug.h"
4 #include "flist.h"
5 #include "options.h"
6
7 static FLIST_HEAD(profile_list);
8
9 struct profile_ops *find_profile(const char *profile)
10 {
11         struct profile_ops *ops = NULL;
12         struct flist_head *n;
13
14         flist_for_each(n, &profile_list) {
15                 ops = flist_entry(n, struct profile_ops, list);
16                 if (!strcmp(profile, ops->name))
17                         break;
18
19                 ops = NULL;
20         }
21
22         return ops;
23 }
24
25 int load_profile(const char *profile)
26 {
27         struct profile_ops *ops;
28
29         dprint(FD_PROFILE, "loading profile '%s'\n", profile);
30
31         ops = find_profile(profile);
32         if (ops) {
33                 if (ops->prep_cmd()) {
34                         log_err("fio: profile %s prep failed\n", profile);
35                         return 1;
36                 }
37                 add_job_opts(ops->cmdline, FIO_CLIENT_TYPE_CLI);
38                 return 0;
39         }
40
41         log_err("fio: profile '%s' not found\n", profile);
42         return 1;
43 }
44
45 static int add_profile_options(struct profile_ops *ops)
46 {
47         struct fio_option *o;
48
49         if (!ops->options)
50                 return 0;
51
52         o = ops->options;
53         while (o->name) {
54                 o->prof_name = ops->name;
55                 o->prof_opts = ops->opt_data;
56                 if (add_option(o))
57                         return 1;
58                 o++;
59         }
60
61         return 0;
62 }
63
64 int register_profile(struct profile_ops *ops)
65 {
66         int ret;
67
68         dprint(FD_PROFILE, "register profile '%s'\n", ops->name);
69
70         ret = add_profile_options(ops);
71         if (!ret) {
72                 flist_add_tail(&ops->list, &profile_list);
73                 add_opt_posval("profile", ops->name, ops->desc);
74                 return 0;
75         }
76
77         invalidate_profile_options(ops->name);
78         return ret;
79 }
80
81 void unregister_profile(struct profile_ops *ops)
82 {
83         dprint(FD_PROFILE, "unregister profile '%s'\n", ops->name);
84         flist_del(&ops->list);
85         invalidate_profile_options(ops->name);
86         del_opt_posval("profile", ops->name);
87 }
88
89 void profile_add_hooks(struct thread_data *td)
90 {
91         struct profile_ops *ops;
92
93         if (!exec_profile)
94                 return;
95
96         ops = find_profile(exec_profile);
97         if (!ops)
98                 return;
99
100         if (ops->io_ops) {
101                 td->prof_io_ops = *ops->io_ops;
102                 td->flags |= TD_F_PROFILE_OPS;
103         }
104 }
105
106 int profile_td_init(struct thread_data *td)
107 {
108         struct prof_io_ops *ops = &td->prof_io_ops;
109
110         if (ops->td_init)
111                 return ops->td_init(td);
112
113         return 0;
114 }
115
116 void profile_td_exit(struct thread_data *td)
117 {
118         struct prof_io_ops *ops = &td->prof_io_ops;
119
120         if (ops->td_exit)
121                 ops->td_exit(td);
122 }