Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / dmclock / sim / src / config.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4
5 #include <unistd.h>
6 #include <string.h>
7 #include <stdarg.h>
8
9 #include <iostream>
10 #include <vector>
11 #include <list>
12
13 #include "config.h"
14 #include "str_list.h"
15
16
17 static void dashes_to_underscores(const char *input, char *output) {
18   char c = 0;
19   char *o = output;
20   const char *i = input;
21   // first two characters are copied as-is
22   *o = *i++;
23   if (*o++ == '\0')
24     return;
25   *o = *i++;
26   if (*o++ == '\0')
27     return;
28   for (; ((c = *i)); ++i) {
29     if (c == '=') {
30       strcpy(o, i);
31       return;
32     }
33     if (c == '-')
34       *o++ = '_';
35     else
36       *o++ = c;
37   }
38   *o++ = '\0';
39 }
40
41 static int va_ceph_argparse_witharg(std::vector<const char*> &args,
42         std::vector<const char*>::iterator &i, std::string *ret,
43         std::ostream &oss, va_list ap) {
44   const char *first = *i;
45   char tmp[strlen(first)+1];
46   dashes_to_underscores(first, tmp);
47   first = tmp;
48
49   // does this argument match any of the possibilities?
50   while (1) {
51     const char *a = va_arg(ap, char*);
52     if (a == NULL)
53       return 0;
54     int strlen_a = strlen(a);
55     char a2[strlen_a+1];
56     dashes_to_underscores(a, a2);
57     if (strncmp(a2, first, strlen(a2)) == 0) {
58       if (first[strlen_a] == '=') {
59         *ret = first + strlen_a + 1;
60         i = args.erase(i);
61         return 1;
62       }
63       else if (first[strlen_a] == '\0') {
64         // find second part (or not)
65         if (i+1 == args.end()) {
66           oss << "Option " << *i << " requires an argument." << std::endl;
67           i = args.erase(i);
68           return -EINVAL;
69         }
70         i = args.erase(i);
71         *ret = *i;
72         i = args.erase(i);
73         return 1;
74       }
75     }
76   }
77 }
78
79 bool crimson::qos_simulation::ceph_argparse_witharg(std::vector<const char*> &args,
80         std::vector<const char*>::iterator &i, std::string *ret, ...) {
81   int r;
82   va_list ap;
83   va_start(ap, ret);
84   r = va_ceph_argparse_witharg(args, i, ret, std::cerr, ap);
85   va_end(ap);
86   if (r < 0)
87     _exit(1);
88   return r != 0;
89 }
90
91 void crimson::qos_simulation::ceph_argparse_early_args(std::vector<const char*>& args, std::string *conf_file_list) {
92   std::string val;
93
94   std::vector<const char *> orig_args = args;
95
96   for (std::vector<const char*>::iterator i = args.begin(); i != args.end(); ) {
97     if (ceph_argparse_witharg(args, i, &val, "--conf", "-c", (char*)NULL)) {
98       *conf_file_list = val;
99     }
100     else {
101       // ignore
102       ++i;
103     }
104   }
105   return;
106 }
107
108 static bool stobool(const std::string & v) {
109     return !v.empty () &&
110            (strcasecmp (v.c_str (), "true") == 0 ||
111            atoi (v.c_str ()) != 0);
112 }
113
114 int crimson::qos_simulation::parse_config_file(const std::string &fname, sim_config_t &g_conf) {
115   ConfFile cf;
116   std::deque<std::string> err;
117   std::ostringstream warn;
118   int ret = cf.parse_file(fname.c_str(), &err, &warn);
119   if (ret) {
120     // error
121     return ret;
122   }
123
124   std::string val;
125   if (!cf.read("global", "server_groups", val))
126     g_conf.server_groups = std::stoul(val);
127   if (!cf.read("global", "client_groups", val))
128     g_conf.client_groups = std::stoul(val);
129   if (!cf.read("global", "server_random_selection", val))
130     g_conf.server_random_selection = stobool(val);
131   if (!cf.read("global", "server_soft_limit", val))
132     g_conf.server_soft_limit = stobool(val);
133
134   for (uint i = 0; i < g_conf.server_groups; i++) {
135     srv_group_t st;
136     std::string section = "server." + std::to_string(i);
137     if (!cf.read(section, "server_count", val))
138       st.server_count = std::stoul(val);
139     if (!cf.read(section, "server_iops", val))
140       st.server_iops = std::stoul(val);
141     if (!cf.read(section, "server_threads", val))
142       st.server_threads = std::stoul(val);
143     g_conf.srv_group.push_back(st);
144   }
145
146   for (uint i = 0; i < g_conf.client_groups; i++) {
147     cli_group_t ct;
148     std::string section = "client." + std::to_string(i);
149     if (!cf.read(section, "client_count", val))
150       ct.client_count = std::stoul(val);
151     if (!cf.read(section, "client_wait", val))
152       ct.client_wait = std::chrono::seconds(std::stoul(val));
153     if (!cf.read(section, "client_total_ops", val))
154       ct.client_total_ops = std::stoul(val);
155     if (!cf.read(section, "client_server_select_range", val))
156       ct.client_server_select_range = std::stoul(val);
157     if (!cf.read(section, "client_iops_goal", val))
158       ct.client_iops_goal = std::stoul(val);
159     if (!cf.read(section, "client_outstanding_ops", val))
160       ct.client_outstanding_ops = std::stoul(val);
161     if (!cf.read(section, "client_reservation", val))
162       ct.client_reservation = std::stod(val);
163     if (!cf.read(section, "client_limit", val))
164       ct.client_limit = std::stod(val);
165     if (!cf.read(section, "client_weight", val))
166       ct.client_weight = std::stod(val);
167     g_conf.cli_group.push_back(ct);
168   }
169
170   return 0;
171 }