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 
find_profile(const char * profile)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 
load_profile(const char * profile)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 
add_profile_options(struct profile_ops * ops)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 
register_profile(struct profile_ops * ops)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 
unregister_profile(struct profile_ops * ops)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 
profile_add_hooks(struct thread_data * td)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 
profile_td_init(struct thread_data * td)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 
profile_td_exit(struct thread_data * td)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 }
123