Added --verbose option to commands
[distributed.git] / src / server / beacon.cxx
blob2bca5b58bd59ae5c3ae22800a6e542f21ddb560f
1 //
2 // Copyright (C) 2008 Francesco Salvestrini
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License along
15 // with this program; if not, write to the Free Software Foundation, Inc.,
16 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include "config.h"
21 #include <unistd.h>
22 #include <getopt.h>
23 #include <cstdlib>
24 #include <string>
25 #include <vector>
26 #include <iostream>
28 #include "libs/misc/debug.h"
29 #include "libs/misc/constant.h"
30 #include "libs/misc/environment.h"
31 #include "libs/misc/utility.h"
32 #include "libs/conf/configuration.h"
33 #include "libs/vm/vm.h"
34 #ifdef HAVE_LUA
35 #include "libs/vm/lua.h"
36 #endif
37 #include "libs/net/uuid.h"
39 #define PROGRAM_NAME "beacon"
41 void version(void)
43 std::cout
44 << PROGRAM_NAME << " (" << PACKAGE_NAME << ") " << PACKAGE_VERSION << std::endl
45 << std::endl
46 << "Copyright (C) 2008 Francesco Salvestrini" << std::endl
47 << std::endl
48 << "This is free software. You may redistribute copies of it under the terms of" << std::endl
49 << "the GNU General Public License <http://www.gnu.org/licenses/gpl.html>." << std::endl
50 << "There is NO WARRANTY, to the extent permitted by law." << std::endl;
54 #define DEFAULT_MAX_MEM 16 * KB
55 #define DEFAULT_MAX_JOBS 8
57 void help(void)
59 std::cout
60 << "Usage: " << PROGRAM_NAME << " [OPTION]... " << std::endl
61 << std::endl
62 << "Options: " << std::endl
63 << " -m, --max-mem maximum usable memory in KB (default " << DEFAULT_MAX_MEM / KB << " KB)" << std::endl
64 << " -j, --max-jobs maximum number of parallel jobs (default " << DEFAULT_MAX_JOBS << ")" << std::endl
65 << " -d, --debug enable debugging traces" << std::endl
66 << " -h, --help print this help, then exit" << std::endl
67 << " -V, --version print version number, then exit" << std::endl
68 << std::endl
69 << "Report bugs to <" << PACKAGE_BUGREPORT << ">" << std::endl;
72 void hint(const std::string & message)
74 BUG_ON(message.size() == 0);
76 std::cout
77 << message << std::endl
78 << "Try `" << PROGRAM_NAME << " -h' for more information." << std::endl;
81 int main(int argc, char * argv[])
83 TR_CONFIG_LVL(TR_LVL_DEFAULT);
84 TR_CONFIG_PFX(PROGRAM_NAME);
86 try {
87 std::string conffile = "";
89 int max_mem = DEFAULT_MAX_MEM;
90 bool max_mem_set = false;
91 int max_jobs = DEFAULT_MAX_JOBS;
92 bool max_jobs_set = false;
94 int c;
95 //int digit_optind = 0;
96 while (1) {
97 //int this_option_optind = optind ? optind : 1;
98 int option_index = 0;
100 static struct option long_options[] = {
101 { "config", 1, 0, 'c' },
102 { "max-mem", 1, 0, 'm' },
103 { "max-jobs", 1, 0, 'j' },
104 { "debug", 0, 0, 'd' },
105 { "verbose", 0, 0, 'v' },
106 { "version", 0, 0, 'V' },
107 { "help", 0, 0, 'h' },
108 { 0, 0, 0, 0 }
111 c = getopt_long(argc, argv, "c:m:j:dvVh",
112 long_options, &option_index);
113 if (c == -1) {
114 break;
117 switch (c) {
118 case 'c':
119 conffile = optarg;
120 break;
121 case 'm':
123 // XXX FIXME:
124 // The current solution is ugly.
125 // Add modifiers (KB, MB, GB) to
126 // this option in order to use
127 // different memory granularity.
129 max_mem = atoi(optarg);
130 if (max_mem <= 0) {
131 hint("Wrong max memory value");
132 return 1;
134 max_mem = max_mem * 1024;
135 max_mem_set = true;
136 break;
137 case 'j':
138 max_jobs = atoi(optarg);
139 if (max_jobs <= 0) {
140 hint("Wrong max jobs value");
141 return 1;
143 max_jobs_set = true;
144 break;
145 case 'd':
146 TR_CONFIG_LVL(TR_LVL_DEBUG);
147 break;
148 case 'v':
149 TR_CONFIG_LVL(TR_LVL_VERBOSE);
150 break;
151 case 'V':
152 version();
153 return 0;
154 case 'h':
155 help();
156 return 0;
157 case '?':
158 hint("Unrecognized option");
159 return 1;
161 default:
162 BUG();
163 return 1;
167 // Options related checks
168 BUG_ON(max_mem <= 0);
169 BUG_ON(max_jobs <= 0);
171 // Build configuration file path
172 if (conffile.size() == 0) {
173 std::string homedir = Environment::get("HOME");
174 std::string confdir =
175 homedir +
176 std::string("/") +
177 std::string(".") +
178 std::string(PACKAGE_TARNAME);
179 conffile =
180 confdir +
181 std::string("/") +
182 std::string(PROGRAM_NAME);
183 } else {
184 TR_DBG("Configuration file overridden\n");
187 BUG_ON(conffile.size() == 0);
189 TR_DBG("Initial (configuration file) values:\n");
190 TR_DBG(" Max mem: '%d'\n", max_mem);
191 TR_DBG(" Max jobs: '%d'\n", max_jobs);
193 // Read configuration file (if available)
194 try {
195 TR_DBG("Reading configuration file from '%s'\n",
196 conffile.c_str());
198 Configuration::File config;
199 std::ifstream instream(conffile.c_str());
201 instream >> config;
203 int conf_max_mem;
204 if (config.get<int>(conf_max_mem, "max-mem")) {
205 TR_DBG("Found 'max-mem' key, value '%d'\n",
206 conf_max_mem);
208 // Check gathered configuration
209 if (conf_max_mem < 0) {
210 TR_ERR("Wrong max-mem value in "
211 "configuration file");
212 return 1;
215 if (!max_mem_set) {
216 TR_DBG("Updating 'max-mem' key\n");
218 // Configuration value not specified
219 // in command line ...
220 max_mem = conf_max_mem;
224 int conf_max_jobs;
225 if (config.get<int>(conf_max_jobs, "max-jobs")) {
226 TR_DBG("Found 'max-jobs' key, value '%d'\n",
227 conf_max_mem);
229 // Check gathered configuration
230 if (conf_max_jobs < 0) {
231 TR_ERR("Wrong max-jobs value in "
232 "configuration file");
233 return 1;
236 if (!max_jobs_set) {
237 TR_DBG("Updating 'max-jobs' key\n");
239 // Configuration value not specified
240 // in command line ...
241 max_jobs = conf_max_jobs;
244 } catch (std::exception & e) {
245 TR_ERR("%s\n", e.what());
246 } catch (...) {
247 BUG();
250 // Options related checks
251 BUG_ON(max_mem <= 0);
252 BUG_ON(max_jobs <= 0);
254 TR_DBG("Final (configuration file) values:\n");
255 TR_DBG(" Max mem: '%d'\n", max_mem);
256 TR_DBG(" Max jobs: '%d'\n", max_jobs);
258 size_t mem_for_vm = max_mem / max_jobs;
260 // Dump (acquired and derived) infos
261 TR_DBG("Max mem: '%d'\n", max_mem);
262 TR_DBG("Max jobs '%d'\n", max_jobs);
263 TR_DBG("Mem for VM '%d'\n", mem_for_vm);
264 TR_DBG("Configuration file: '%s'\n", conffile.c_str());
266 if (mem_for_vm < MIN_MEM_FOR_VM) {
267 TR_CRT("Memory for single VM is too small "
268 "(%d byte%s each, %d minimum)\n",
269 mem_for_vm, PLURAL(mem_for_vm), MIN_MEM_FOR_VM);
270 return 1;
273 TR_DBG("Building %d VM%s\n", max_jobs, PLURAL(max_jobs));
275 std::vector<VM::VM *> vms;
276 vms.resize(max_jobs);
278 std::vector<VM::VM *>::iterator iter;
279 for (iter = vms.begin(); iter != vms.end(); iter++) {
280 try {
281 #ifdef HAVE_LUA
282 (*iter) = new VM::Lua(mem_for_vm);
283 #endif
284 } catch (...) {
285 TR_CRT("Cannot create VM\n");
286 return 1;
288 TR_DBG("VM %p initialized\n", (*iter));
291 size_t slack = max_mem - max_jobs * mem_for_vm;
292 TR_DBG("Memory slack is %d byte%s\n", slack, PLURAL(slack));
294 // Do the main loop here
295 try {
296 std::string t1("550e8400-e29b-41d4-a716-123456782122");
297 std::string t2;
299 std::cout << t1 << std::endl;
301 Net::UUID uuid(t1);
303 t2 = std::string(uuid);
305 std::cout << t2 << std::endl;
307 BUG_ON(t1 != t2);
309 } catch (std::exception & e) {
310 TR_DBG("Got exception '%s'\n", e.what());
311 throw e;
313 MISSING_CODE();
314 } catch (...) {
315 BUG();
318 return 0;