genfio: Splitting gen_template in 2 parts
[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                 if (add_option(o))
56                         return 1;
57                 o++;
58         }
59
60         return 0;
61 }
62
63 int register_profile(struct profile_ops *ops)
64 {
65         int ret;
66
67         dprint(FD_PROFILE, "register profile '%s'\n", ops->name);
68
69         ret = add_profile_options(ops);
70         if (!ret) {
71                 flist_add_tail(&ops->list, &profile_list);
72                 add_opt_posval("profile", ops->name, ops->desc);
73                 return 0;
74         }
75
76         invalidate_profile_options(ops->name);
77         return ret;
78 }
79
80 void unregister_profile(struct profile_ops *ops)
81 {
82         dprint(FD_PROFILE, "unregister profile '%s'\n", ops->name);
83         flist_del(&ops->list);
84         invalidate_profile_options(ops->name);
85         del_opt_posval("profile", ops->name);
86 }
87
88 void profile_add_hooks(struct thread_data *td)
89 {
90         struct profile_ops *ops;
91
92         if (!exec_profile)
93                 return;
94
95         ops = find_profile(exec_profile);
96         if (!ops)
97                 return;
98
99         if (ops->io_ops) {
100                 td->prof_io_ops = *ops->io_ops;
101                 td->flags |= TD_F_PROFILE_OPS;
102         }
103 }
104
105 int profile_td_init(struct thread_data *td)
106 {
107         struct prof_io_ops *ops = &td->prof_io_ops;
108
109         if (ops->td_init)
110                 return ops->td_init(td);
111
112         return 0;
113 }
114
115 void profile_td_exit(struct thread_data *td)
116 {
117         struct prof_io_ops *ops = &td->prof_io_ops;
118
119         if (ops->td_exit)
120                 ops->td_exit(td);
121 }