1#include "fio.h" 2#include "profile.h" 3#include "debug.h" 4#include "flist.h" 5#include "options.h" 6 7static FLIST_HEAD(profile_list); 8 9struct 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 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); 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 45static 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 64int 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 81void 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 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 100 if (ops->io_ops) { 101 td->prof_io_ops = *ops->io_ops; 102 td->flags |= TD_F_PROFILE_OPS; 103 } 104} 105 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} 123