Fixed compilation issues
[distributed.git] / src / server / beacon.cxx
blobb6bf1a5bc95e12503cf226015c0e690777eeb6c9
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 <cstdlib>
23 #include <string>
24 #include <vector>
25 #include <iostream>
27 #include "getopt.h"
29 #include "libs/misc/debug.h"
30 #include "libs/misc/constant.h"
31 #include "libs/misc/environment.h"
32 #include "libs/misc/utility.h"
33 #include "libs/conf/configuration.h"
34 #include "libs/vm/vm.h"
35 #ifdef HAVE_LUA
36 #include "libs/vm/lua.h"
37 #endif
38 #include "libs/net/uuid.h"
40 #define PROGRAM_NAME "beacon"
42 void version(void)
44 std::cout
45 << PROGRAM_NAME << " (" << PACKAGE_NAME << ") " << PACKAGE_VERSION << std::endl
46 << std::endl
47 << "Copyright (C) 2008 Francesco Salvestrini" << std::endl
48 << std::endl
49 << "This is free software. You may redistribute copies of it under the terms of" << std::endl
50 << "the GNU General Public License <http://www.gnu.org/licenses/gpl.html>." << std::endl
51 << "There is NO WARRANTY, to the extent permitted by law." << std::endl;
55 #define DEFAULT_MAX_MEM 16 * KB
56 #define DEFAULT_MAX_JOBS 8
58 void help(void)
60 std::cout
61 << "Usage: " << PROGRAM_NAME << " [OPTION]... " << std::endl
62 << std::endl
63 << "Options: " << std::endl
64 << " -m, --max-mem maximum usable memory in KB (default " << DEFAULT_MAX_MEM / KB << " KB)" << std::endl
65 << " -j, --max-jobs maximum number of parallel jobs (default " << DEFAULT_MAX_JOBS << ")" << std::endl
66 << " -d, --debug enable debugging traces" << std::endl
67 << " -h, --help print this help, then exit" << std::endl
68 << " -V, --version print version number, then exit" << std::endl
69 << std::endl
70 << "Report bugs to <" << PACKAGE_BUGREPORT << ">" << std::endl;
73 void hint(const std::string & message)
75 BUG_ON(message.size() == 0);
77 std::cout
78 << message << std::endl
79 << "Try `" << PROGRAM_NAME << " -h' for more information." << std::endl;
82 int main(int argc, char * argv[])
84 TR_CONFIG_LVL(TR_LVL_DEFAULT);
85 TR_CONFIG_PFX(PROGRAM_NAME);
87 try {
88 std::string conffile = "";
90 int max_mem = DEFAULT_MAX_MEM;
91 bool max_mem_set = false;
92 int max_jobs = DEFAULT_MAX_JOBS;
93 bool max_jobs_set = false;
95 int c;
96 //int digit_optind = 0;
97 while (1) {
98 //int this_option_optind = optind ? optind : 1;
99 int option_index = 0;
101 static struct option long_options[] = {
102 { "config", 1, 0, 'c' },
103 { "max-mem", 1, 0, 'm' },
104 { "max-jobs", 1, 0, 'j' },
105 { "debug", 0, 0, 'd' },
106 { "verbose", 0, 0, 'v' },
107 { "version", 0, 0, 'V' },
108 { "help", 0, 0, 'h' },
109 { 0, 0, 0, 0 }
112 c = getopt_long(argc, argv, "c:m:j:dvVh",
113 long_options, &option_index);
114 if (c == -1) {
115 break;
118 switch (c) {
119 case 'c':
120 conffile = optarg;
121 break;
122 case 'm':
124 // XXX FIXME:
125 // The current solution is ugly.
126 // Add modifiers (KB, MB, GB) to
127 // this option in order to use
128 // different memory granularity.
130 max_mem = atoi(optarg);
131 if (max_mem <= 0) {
132 hint("Wrong max memory value");
133 return 1;
135 max_mem = max_mem * 1024;
136 max_mem_set = true;
137 break;
138 case 'j':
139 max_jobs = atoi(optarg);
140 if (max_jobs <= 0) {
141 hint("Wrong max jobs value");
142 return 1;
144 max_jobs_set = true;
145 break;
146 case 'd':
147 TR_CONFIG_LVL(TR_LVL_DEBUG);
148 break;
149 case 'v':
150 TR_CONFIG_LVL(TR_LVL_VERBOSE);
151 break;
152 case 'V':
153 version();
154 return 0;
155 case 'h':
156 help();
157 return 0;
158 case '?':
159 hint("Unrecognized option");
160 return 1;
162 default:
163 BUG();
164 return 1;
168 // Options related checks
169 BUG_ON(max_mem <= 0);
170 BUG_ON(max_jobs <= 0);
172 // Build configuration file path
173 if (conffile.size() == 0) {
174 std::string homedir = Environment::get("HOME");
175 std::string confdir =
176 homedir +
177 std::string("/") +
178 std::string(".") +
179 std::string(PACKAGE_TARNAME);
180 conffile =
181 confdir +
182 std::string("/") +
183 std::string(PROGRAM_NAME);
184 } else {
185 TR_DBG("Configuration file overridden\n");
188 BUG_ON(conffile.size() == 0);
190 TR_DBG("Initial (configuration file) values:\n");
191 TR_DBG(" Max mem: '%d'\n", max_mem);
192 TR_DBG(" Max jobs: '%d'\n", max_jobs);
194 // Read configuration file (if available)
195 try {
196 TR_DBG("Reading configuration file from '%s'\n",
197 conffile.c_str());
199 Configuration::File config;
200 std::ifstream instream(conffile.c_str());
202 instream >> config;
204 int conf_max_mem;
205 if (config.get<int>(conf_max_mem, "max-mem")) {
206 TR_DBG("Found 'max-mem' key, value '%d'\n",
207 conf_max_mem);
209 // Check gathered configuration
210 if (conf_max_mem < 0) {
211 TR_ERR("Wrong max-mem value in "
212 "configuration file");
213 return 1;
216 if (!max_mem_set) {
217 TR_DBG("Updating 'max-mem' key\n");
219 // Configuration value not specified
220 // in command line ...
221 max_mem = conf_max_mem;
225 int conf_max_jobs;
226 if (config.get<int>(conf_max_jobs, "max-jobs")) {
227 TR_DBG("Found 'max-jobs' key, value '%d'\n",
228 conf_max_mem);
230 // Check gathered configuration
231 if (conf_max_jobs < 0) {
232 TR_ERR("Wrong max-jobs value in "
233 "configuration file");
234 return 1;
237 if (!max_jobs_set) {
238 TR_DBG("Updating 'max-jobs' key\n");
240 // Configuration value not specified
241 // in command line ...
242 max_jobs = conf_max_jobs;
245 } catch (std::exception & e) {
246 TR_ERR("%s\n", e.what());
247 } catch (...) {
248 BUG();
251 // Options related checks
252 BUG_ON(max_mem <= 0);
253 BUG_ON(max_jobs <= 0);
255 TR_DBG("Final (configuration file) values:\n");
256 TR_DBG(" Max mem: '%d'\n", max_mem);
257 TR_DBG(" Max jobs: '%d'\n", max_jobs);
259 size_t mem_for_vm = max_mem / max_jobs;
261 // Dump (acquired and derived) infos
262 TR_DBG("Max mem: '%d'\n", max_mem);
263 TR_DBG("Max jobs '%d'\n", max_jobs);
264 TR_DBG("Mem for VM '%d'\n", mem_for_vm);
265 TR_DBG("Configuration file: '%s'\n", conffile.c_str());
267 if (mem_for_vm < MIN_MEM_FOR_VM) {
268 TR_CRT("Memory for single VM is too small "
269 "(%d byte%s each, %d minimum)\n",
270 mem_for_vm, PLURAL(mem_for_vm), MIN_MEM_FOR_VM);
271 return 1;
274 TR_DBG("Building %d VM%s\n", max_jobs, PLURAL(max_jobs));
276 std::vector<VM::VM *> vms;
277 vms.resize(max_jobs);
279 std::vector<VM::VM *>::iterator iter;
280 for (iter = vms.begin(); iter != vms.end(); iter++) {
281 try {
282 #ifdef HAVE_LUA
283 (*iter) = new VM::Lua(mem_for_vm);
284 #endif
285 } catch (...) {
286 TR_CRT("Cannot create VM\n");
287 return 1;
289 TR_DBG("VM %p initialized\n", (*iter));
292 size_t slack = max_mem - max_jobs * mem_for_vm;
293 TR_DBG("Memory slack is %d byte%s\n", slack, PLURAL(slack));
295 // Do the main loop here
296 try {
297 std::string t0("7d444840-9dc0-11d1-b245-5ffdce74fad2");
298 std::string t1("e902893a-9d22-3c7e-a7b8-d6e313b71d9f");
299 std::string t2;
301 std::cout << t1 << std::endl;
303 Net::UUID uuid0(t0);
305 t2 = std::string(uuid0);
307 Net::UUID uuid1(t1);
309 t2 = std::string(uuid1);
311 std::cout << t2 << std::endl;
313 BUG_ON(t1 != t2);
315 for (size_t i = 0; i < 5; i++) {
316 Net::UUID uuidRand(Net::UUID::IETF_RFC4122_RANDOM);
318 t2 = std::string(uuidRand);
320 std::cout
321 << "--- RANDOM #" << i
322 << ":" << t2 << std::endl;
325 Net::UUID uuidTB(Net::UUID::UNKNOWN/*IETF_RFC4122_TIMEBASED*/);
327 } catch (Net::UUID::invalid_version & e) {
328 TR_ERR("Got Net::UUID::invalid_version "
329 "exception 'Version 0x%x %s'\n",
330 e.version,
331 e.what());
332 throw e;
333 } catch (Net::UUID::formatting_problem & e) {
334 TR_ERR("Got Net::UUID::formatting_problem "
335 "exception 'Version 0x%x %s %d'\n",
336 e.version,
337 e.what(),
338 e.field);
339 throw e;
340 } catch (Net::UUID::invalid_hexfield & e) {
341 TR_ERR("Got Net::UUID::invalid_hexfield "
342 "exception '%s'\n",
343 e.what());
344 throw e;
345 } catch (Net::UUID::generic_problem & e) {
346 TR_ERR("Got Net::UUID::generic_problem "
347 "exception '%s'\n",
348 e.what());
349 throw e;
350 } catch (std::exception & e) {
351 TR_ERR("Got exception '%s'\n", e.what());
352 throw e;
355 MISSING_CODE();
356 } catch (...) {
357 BUG();
360 return 0;