blob: 90c9ea8d14eb6c4d52c5a94bef7eab3e32fc0a0e [file] [log] [blame]
Jens Axboe79d16312010-03-04 12:43:20 +01001#include "fio.h"
2#include "profile.h"
3#include "debug.h"
4#include "flist.h"
Jens Axboee2de69d2010-03-04 14:05:48 +01005#include "options.h"
Jens Axboe79d16312010-03-04 12:43:20 +01006
7static FLIST_HEAD(profile_list);
8
Jens Axboe15dc1932010-03-05 10:59:06 +01009struct profile_ops *find_profile(const char *profile)
Jens Axboe79d16312010-03-04 12:43:20 +010010{
Jens Axboe15dc1932010-03-05 10:59:06 +010011 struct profile_ops *ops = NULL;
Jens Axboe79d16312010-03-04 12:43:20 +010012 struct flist_head *n;
13
Jens Axboe79d16312010-03-04 12:43:20 +010014 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
Jens Axboe15dc1932010-03-05 10:59:06 +010022 return ops;
23}
24
25int 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);
Jens Axboe79d16312010-03-04 12:43:20 +010032 if (ops) {
Jens Axboed4afedf2013-05-22 22:21:29 +020033 if (ops->prep_cmd()) {
Jens Axboe90777552013-05-24 09:09:39 +020034 log_err("fio: profile %s prep failed\n", profile);
Jens Axboed4afedf2013-05-22 22:21:29 +020035 return 1;
36 }
Jens Axboe46bcd492012-03-14 11:31:21 +010037 add_job_opts(ops->cmdline, FIO_CLIENT_TYPE_CLI);
Jens Axboe79d16312010-03-04 12:43:20 +010038 return 0;
39 }
40
41 log_err("fio: profile '%s' not found\n", profile);
42 return 1;
43}
44
Jens Axboe07b32322010-03-05 09:48:44 +010045static int add_profile_options(struct profile_ops *ops)
Jens Axboee2de69d2010-03-04 14:05:48 +010046{
Jens Axboe07b32322010-03-05 09:48:44 +010047 struct fio_option *o;
Jens Axboe3c3ed072012-03-27 09:12:39 +020048
Jens Axboee2de69d2010-03-04 14:05:48 +010049 if (!ops->options)
Jens Axboe07b32322010-03-05 09:48:44 +010050 return 0;
Jens Axboee2de69d2010-03-04 14:05:48 +010051
Jens Axboe07b32322010-03-05 09:48:44 +010052 o = ops->options;
53 while (o->name) {
54 o->prof_name = ops->name;
Jens Axboe7b504ed2014-02-11 14:19:38 -070055 o->prof_opts = ops->opt_data;
Jens Axboe07b32322010-03-05 09:48:44 +010056 if (add_option(o))
57 return 1;
58 o++;
Jens Axboee2de69d2010-03-04 14:05:48 +010059 }
Jens Axboe07b32322010-03-05 09:48:44 +010060
61 return 0;
Jens Axboee2de69d2010-03-04 14:05:48 +010062}
63
Jens Axboe07b32322010-03-05 09:48:44 +010064int register_profile(struct profile_ops *ops)
Jens Axboe79d16312010-03-04 12:43:20 +010065{
Jens Axboe07b32322010-03-05 09:48:44 +010066 int ret;
67
Jens Axboe79d16312010-03-04 12:43:20 +010068 dprint(FD_PROFILE, "register profile '%s'\n", ops->name);
Jens Axboe07b32322010-03-05 09:48:44 +010069
Jens Axboef5b6bb82010-03-05 10:09:59 +010070 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);
Jens Axboe07b32322010-03-05 09:48:44 +010078 return ret;
Jens Axboe79d16312010-03-04 12:43:20 +010079}
80
81void unregister_profile(struct profile_ops *ops)
82{
83 dprint(FD_PROFILE, "unregister profile '%s'\n", ops->name);
84 flist_del(&ops->list);
Jens Axboe07b32322010-03-05 09:48:44 +010085 invalidate_profile_options(ops->name);
Jens Axboef5b6bb82010-03-05 10:09:59 +010086 del_opt_posval("profile", ops->name);
Jens Axboe79d16312010-03-04 12:43:20 +010087}
Jens Axboe15dc1932010-03-05 10:59:06 +010088
89void 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
Jens Axboed72be542012-11-30 19:37:46 +0100100 if (ops->io_ops) {
Jens Axboe7eb36572010-03-08 13:58:49 +0100101 td->prof_io_ops = *ops->io_ops;
Jens Axboed72be542012-11-30 19:37:46 +0100102 td->flags |= TD_F_PROFILE_OPS;
103 }
Jens Axboe15dc1932010-03-05 10:59:06 +0100104}
Jens Axboe58c55ba2010-03-09 12:20:08 +0100105
106int 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
116void 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}