1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
5 * Copyright (C) 2016 Red Hat Inc.
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License version
9 * 2.1, as published by the Free Software Foundation. See file
26 static void dashes_to_underscores(const char *input
, char *output
) {
29 const char *i
= input
;
30 // first two characters are copied as-is
37 for (; ((c
= *i
)); ++i
) {
50 static int va_ceph_argparse_witharg(std::vector
<const char*> &args
,
51 std::vector
<const char*>::iterator
&i
, std::string
*ret
,
52 std::ostream
&oss
, va_list ap
) {
53 const char *first
= *i
;
54 char tmp
[strlen(first
)+1];
55 dashes_to_underscores(first
, tmp
);
58 // does this argument match any of the possibilities?
60 const char *a
= va_arg(ap
, char*);
63 int strlen_a
= strlen(a
);
65 dashes_to_underscores(a
, a2
);
66 if (strncmp(a2
, first
, strlen(a2
)) == 0) {
67 if (first
[strlen_a
] == '=') {
68 *ret
= first
+ strlen_a
+ 1;
72 else if (first
[strlen_a
] == '\0') {
73 // find second part (or not)
74 if (i
+1 == args
.end()) {
75 oss
<< "Option " << *i
<< " requires an argument." << std::endl
;
88 bool crimson::qos_simulation::ceph_argparse_witharg(std::vector
<const char*> &args
,
89 std::vector
<const char*>::iterator
&i
, std::string
*ret
, ...) {
93 r
= va_ceph_argparse_witharg(args
, i
, ret
, std::cerr
, ap
);
100 void crimson::qos_simulation::ceph_argparse_early_args(std::vector
<const char*>& args
, std::string
*conf_file_list
) {
103 std::vector
<const char *> orig_args
= args
;
105 for (std::vector
<const char*>::iterator i
= args
.begin(); i
!= args
.end(); ) {
106 if (ceph_argparse_witharg(args
, i
, &val
, "--conf", "-c", (char*)NULL
)) {
107 *conf_file_list
= val
;
117 static bool stobool(const std::string
& v
) {
118 return !v
.empty () &&
119 (strcasecmp (v
.c_str (), "true") == 0 ||
120 atoi (v
.c_str ()) != 0);
123 int crimson::qos_simulation::parse_config_file(const std::string
&fname
, sim_config_t
&g_conf
) {
125 std::deque
<std::string
> err
;
126 std::ostringstream warn
;
127 int ret
= cf
.parse_file(fname
.c_str(), &err
, &warn
);
134 if (!cf
.read("global", "server_groups", val
))
135 g_conf
.server_groups
= std::stoul(val
);
136 if (!cf
.read("global", "client_groups", val
))
137 g_conf
.client_groups
= std::stoul(val
);
138 if (!cf
.read("global", "server_random_selection", val
))
139 g_conf
.server_random_selection
= stobool(val
);
140 if (!cf
.read("global", "server_soft_limit", val
))
141 g_conf
.server_soft_limit
= stobool(val
);
142 if (!cf
.read("global", "anticipation_timeout", val
))
143 g_conf
.anticipation_timeout
= stod(val
);
145 for (unsigned i
= 0; i
< g_conf
.server_groups
; i
++) {
147 std::string section
= "server." + std::to_string(i
);
148 if (!cf
.read(section
, "server_count", val
))
149 st
.server_count
= std::stoul(val
);
150 if (!cf
.read(section
, "server_iops", val
))
151 st
.server_iops
= std::stoul(val
);
152 if (!cf
.read(section
, "server_threads", val
))
153 st
.server_threads
= std::stoul(val
);
154 g_conf
.srv_group
.push_back(st
);
157 for (unsigned i
= 0; i
< g_conf
.client_groups
; i
++) {
159 std::string section
= "client." + std::to_string(i
);
160 if (!cf
.read(section
, "client_count", val
))
161 ct
.client_count
= std::stoul(val
);
162 if (!cf
.read(section
, "client_wait", val
))
163 ct
.client_wait
= std::chrono::seconds(std::stoul(val
));
164 if (!cf
.read(section
, "client_total_ops", val
))
165 ct
.client_total_ops
= std::stoul(val
);
166 if (!cf
.read(section
, "client_server_select_range", val
))
167 ct
.client_server_select_range
= std::stoul(val
);
168 if (!cf
.read(section
, "client_iops_goal", val
))
169 ct
.client_iops_goal
= std::stoul(val
);
170 if (!cf
.read(section
, "client_outstanding_ops", val
))
171 ct
.client_outstanding_ops
= std::stoul(val
);
172 if (!cf
.read(section
, "client_reservation", val
))
173 ct
.client_reservation
= std::stod(val
);
174 if (!cf
.read(section
, "client_limit", val
))
175 ct
.client_limit
= std::stod(val
);
176 if (!cf
.read(section
, "client_weight", val
))
177 ct
.client_weight
= std::stod(val
);
178 if (!cf
.read(section
, "client_req_cost", val
))
179 ct
.client_req_cost
= std::stoul(val
);
180 g_conf
.cli_group
.push_back(ct
);