int main(int argc, char *argv[]) { time_t start; int ch, reps, ret; const char *config, *home; config = NULL; if ((g.progname = strrchr(argv[0], '/')) == NULL) g.progname = argv[0]; else ++g.progname; #if 0 /* Configure the GNU malloc for debugging. */ (void)setenv("MALLOC_CHECK_", "2", 1); #endif #if 0 /* Configure the FreeBSD malloc for debugging. */ (void)setenv("MALLOC_OPTIONS", "AJ", 1); #endif /* Track progress unless we're re-directing output to a file. */ g.track = isatty(1) ? 1 : 0; /* Set values from the command line. */ home = NULL; while ((ch = __wt_getopt( g.progname, argc, argv, "1C:c:H:h:Llqrt:")) != EOF) switch (ch) { case '1': /* One run */ g.c_runs = 1; break; case 'C': /* wiredtiger_open config */ g.config_open = __wt_optarg; break; case 'c': /* Configuration from a file */ config = __wt_optarg; break; case 'H': g.helium_mount = __wt_optarg; break; case 'h': home = __wt_optarg; break; case 'L': /* Re-direct output to a log */ /* * The -l option is a superset of -L, ignore -L if we * have already configured logging for operations. */ if (g.logging == 0) g.logging = LOG_FILE; break; case 'l': /* Turn on operation logging */ g.logging = LOG_OPS; break; case 'q': /* Quiet */ g.track = 0; break; case 'r': /* Replay a run */ g.replay = 1; break; default: usage(); } argc -= __wt_optind; argv += __wt_optind; /* Set up paths. */ path_setup(home); /* If it's a replay, use the home directory's CONFIG file. */ if (g.replay) { if (config != NULL) die(EINVAL, "-c incompatible with -r"); if (access(g.home_config, R_OK) != 0) die(ENOENT, "%s", g.home_config); config = g.home_config; } /* * If we weren't given a configuration file, set values from "CONFIG", * if it exists. * * Small hack to ignore any CONFIG file named ".", that just makes it * possible to ignore any local CONFIG file, used when running checks. */ if (config == NULL && access("CONFIG", R_OK) == 0) config = "CONFIG"; if (config != NULL && strcmp(config, ".") != 0) config_file(config); /* * The rest of the arguments are individual configurations that modify * the base configuration. */ for (; *argv != NULL; ++argv) config_single(*argv, 1); /* * Multithreaded runs can be replayed: it's useful and we'll get the * configuration correct. Obviously the order of operations changes, * warn the user. */ if (g.replay && !SINGLETHREADED) printf("Warning: replaying a threaded run\n"); /* * Single-threaded runs historically exited after a single replay, which * makes sense when you're debugging, leave that semantic in place. */ if (g.replay && SINGLETHREADED) g.c_runs = 1; /* Use line buffering on stdout so status updates aren't buffered. */ (void)setvbuf(stdout, NULL, _IOLBF, 32); /* * Initialize locks to single-thread named checkpoints and backups, and * to single-thread last-record updates. */ if ((ret = pthread_rwlock_init(&g.append_lock, NULL)) != 0) die(ret, "pthread_rwlock_init: append lock"); if ((ret = pthread_rwlock_init(&g.backup_lock, NULL)) != 0) die(ret, "pthread_rwlock_init: backup lock"); /* Seed the random number generator. */ srand((u_int)(0xdeadbeef ^ (u_int)time(NULL))); printf("%s: process %" PRIdMAX "\n", g.progname, (intmax_t)getpid()); while (++g.run_cnt <= g.c_runs || g.c_runs == 0 ) { startup(); /* Start a run */ config_setup(); /* Run configuration */ config_print(0); /* Dump run configuration */ key_len_setup(); /* Setup keys */ start = time(NULL); track("starting up", 0ULL, NULL); if (SINGLETHREADED) bdb_open(); /* Initial file config */ wts_open(g.home, 1, &g.wts_conn); wts_create(); wts_load(); /* Load initial records */ wts_verify("post-bulk verify"); /* Verify */ /* * If we're not doing any operations, scan the bulk-load, copy * the statistics and we're done. Otherwise, loop reading and * operations, with a verify after each set. */ if (g.c_timer == 0 && g.c_ops == 0) { wts_read_scan(); /* Read scan */ wts_stats(); /* Statistics */ } else for (reps = 1; reps <= FORMAT_OPERATION_REPS; ++reps) { wts_read_scan(); /* Read scan */ /* Operations */ wts_ops(reps == FORMAT_OPERATION_REPS); /* * Copy out the run's statistics after the last * set of operations. * * XXX * Verify closes the underlying handle and * discards the statistics, read them first. */ if (reps == FORMAT_OPERATION_REPS) wts_stats(); /* Verify */ wts_verify("post-ops verify"); } track("shutting down", 0ULL, NULL); if (SINGLETHREADED) bdb_close(); wts_close(); /* * If single-threaded, we can dump and compare the WiredTiger * and Berkeley DB data sets. */ if (SINGLETHREADED) wts_dump("standard", 1); /* * Salvage testing. */ wts_salvage(); /* Overwrite the progress line with a completion line. */ if (g.track) printf("\r%78s\r", " "); printf("%4d: %s, %s (%.0f seconds)\n", g.run_cnt, g.c_data_source, g.c_file_type, difftime(time(NULL), start)); } /* Flush/close any logging information. */ if (g.logfp != NULL) (void)fclose(g.logfp); if (g.rand_log != NULL) (void)fclose(g.rand_log); config_print(0); if ((ret = pthread_rwlock_destroy(&g.append_lock)) != 0) die(ret, "pthread_rwlock_destroy: append lock"); if ((ret = pthread_rwlock_destroy(&g.backup_lock)) != 0) die(ret, "pthread_rwlock_destroy: backup lock"); config_clear(); return (EXIT_SUCCESS); }
int main(int argc, char **argv) { char errbuf[PCAP_ERRBUF_SIZE]; bpf_u_int32 net = PCAP_NETMASK_UNKNOWN; char *filter_exp = "ip"; struct bpf_program fp; int i; int c; int opt_count = 0; int tmp_ret; char *ifile = NULL; unsigned int file_count = 0; char filename[MAX_FILENAME_LEN]; /* output file */ char pcap_filename[MAX_FILENAME_LEN*2]; /* output file */ char *cli_interface = NULL; char *cli_filename = NULL; char *config_file = NULL; struct interface ifl[IFL_MAX]; int num_interfaces; char *capture_if; unsigned int file_base_len = 0; unsigned int num_cmds = 0; unsigned int done_with_options = 0; struct stat sb; DIR *dir; struct dirent *ent; enum operating_mode mode = mode_none; /* sanity check sizeof() expectations */ if (data_sanity_check() != ok) { fprintf(stderr, "error: failed data size sanity check\n"); } /* sanity check arguments */ for (i=1; i<argc; i++) { if (strchr(argv[i], '=')) { if (done_with_options) { fprintf(stderr, "error: option (%s) found after filename (%s)\n", argv[i], argv[i-1]); exit(EXIT_FAILURE); } } else { done_with_options = 1; } } /* * set "info" to stderr; this output stream is used for * debug/info/warnings/errors. setting it here is actually * defensive coding, just in case some function that writes to * "info" gets invoked before info gets set below (if we are in * online mode, it will be set to a log file) */ info = stderr; /* in debug mode, turn off output buffering */ #if P2F_DEBUG setvbuf(stderr, NULL, _IONBF, 0); setbuf(stdout, NULL); #endif /* * set configuration from command line arguments that contain * LHS=RHS commands, then update argv/argc so that those arguments * are not subjected to any further processing */ num_cmds = config_set_from_argv(&config, argv, argc); argv += num_cmds; argc -= num_cmds; /* process command line options */ while (1) { int option_index = 0; struct option long_options[] = { {"help", no_argument, 0, 'h' }, {"xconfig", required_argument, 0, 'x' }, {0, 0, 0, 0 } }; c = getopt_long(argc, argv, "hx:", long_options, &option_index); if (c == -1) break; switch (c) { case 'x': config_file = optarg; opt_count++; break; case 'h': default: return usage(argv[0]); } opt_count++; } if (config_file) { /* * read in configuration from file; note that if we don't read in * a file, then the config structure will use the static defaults * set when it was declared */ config_set_from_file(&config, config_file); } if (config_file || (num_cmds != 0)) { /* * set global variables as needed, if we got some configuration * commands from the config_file or from command line arguments */ bidir = config.bidir; include_zeroes = config.include_zeroes; byte_distribution = config.byte_distribution; report_entropy = config.report_entropy; report_wht = config.report_wht; report_hd = config.report_hd; include_tls = config.include_tls; include_classifier = config.include_classifier; output_level = config.output_level; report_idp = config.idp; report_dns = config.dns; salt_algo = config.type; nfv9_capture_port = config.nfv9_capture_port; if (config.bpf_filter_exp) { filter_exp = config.bpf_filter_exp; } } /* * allow some command line variables to override the config file */ if (cli_filename) { /* * output filename provided on command line supersedes that * provided in the config file */ config.filename = cli_filename; } if (cli_interface) { /* * interface provided on command line supersedes that provided * in the config file */ config.interface = cli_interface; } if (config.filename) { strncpy(filename, config.filename, MAX_FILENAME_LEN); } /* * set the operating mode to online or offline */ if (config.interface != NULL && strcmp(config.interface, NULL_KEYWORD)) { mode = mode_online; } else { mode = mode_offline; } /* * if we are doing a live capture, get interface list, and set "info" * output stream to log file */ if (mode == mode_online) { if (config.logfile && strcmp(config.logfile, NULL_KEYWORD)) { info = fopen(config.logfile, "a"); if (info == NULL) { fprintf(stderr, "error: could not open log file %s\n", config.logfile); return -1; } fprintf(stderr, "writing errors/warnings/info/debug output to %s\n", config.logfile); } /* * cheerful message to indicate the start of a new run of the * daemon */ fprintf(info, "--- %s initialization ---\n", argv[0]); flocap_stats_output(info); num_interfaces = interface_list_get(ifl); if (num_interfaces == 0) { fprintf(info, "warning: could not obtain inferface information\n"); } else { for(i=0; i<num_interfaces; i++) { unsigned char *a = ifl[i].mac_addr; fprintf(info, "interface: %8s\tstatus: %s\t%02x%02x%02x%02x%02x%02x\n", ifl[i].name, (ifl[i].active ? "up" : "down"), a[0], a[1], a[2], a[3], a[4], a[5]); } } } else { info = stderr; } /* * report on running configuration (which may depend on the command * line, the config file, or both) */ config_print(info, &config); /* * configure labeled subnets (which uses a radix trie to identify * addresses that match subnets associated with labels) */ if (config.num_subnets > 0) { attr_flags subnet_flag; enum status err; rt = radix_trie_alloc(); if (rt == NULL) { fprintf(info, "could not allocate memory\n"); } err = radix_trie_init(rt); if (err != ok) { fprintf(stderr, "error: could not initialize subnet labels (radix_trie)\n"); } for (i=0; i<config.num_subnets; i++) { char label[LINEMAX], subnet_file[LINEMAX]; int num; num = sscanf(config.subnet[i], "%[^=:]:%[^=:\n#]", label, subnet_file); if (num != 2) { fprintf(info, "error: could not parse command \"%s\" into form label:subnet\n", config.subnet[i]); exit(1); } subnet_flag = radix_trie_add_attr_label(rt, label); if (subnet_flag == 0) { fprintf(info, "error: count not add subnet label %s to radix_trie\n", label); exit(1); } err = radix_trie_add_subnets_from_file(rt, subnet_file, subnet_flag, info); if (err != ok) { fprintf(info, "error: could not add labeled subnets from file %s\n", subnet_file); exit(1); } } fprintf(info, "configured labeled subnets (radix_trie), using %u bytes of memory\n", get_rt_mem_usage()); } if (config.anon_addrs_file != NULL) { if (anon_init(config.anon_addrs_file, info) == failure) { fprintf(info, "error: could not initialize anonymization subnets from file %s\n", config.anon_addrs_file); return -1; } } if (config.filename != NULL) { char *outputdir; /* * set output directory */ if (config.outputdir) { outputdir = config.outputdir; } else { outputdir = "."; } /* * generate an "auto" output file name, based on the MAC address * and the current time, if we are "auto" configured */ if (strncmp(config.filename, "auto", strlen("auto")) == 0) { if (mode == mode_online) { unsigned char *addr = ifl[0].mac_addr; time_t now = time(0); struct tm *t = localtime(&now); snprintf(filename, MAX_FILENAME_LEN, "%s/flocap-%02x%02x%02x%02x%02x%02x-h%d-m%d-s%d-D%d-M%d-Y%d-%s-", outputdir, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], t->tm_hour, t->tm_min, t->tm_sec, t->tm_mday, t->tm_mon, t->tm_year + 1900, t->tm_zone); } else { fprintf(info, "error: cannot use \"output = auto\" with no interface specified; use -o or -l options\n"); return usage(argv[0]); } fprintf(info, "auto generated output filename: %s\n", filename); } else { /* set output file based on command line or config file */ if (cli_filename) { strncpy(filename, config.filename, MAX_FILENAME_LEN); } else { char tmp_filename[MAX_FILENAME_LEN]; strncpy(tmp_filename, filename, MAX_FILENAME_LEN); snprintf(filename, MAX_FILENAME_LEN, "%s/%s", outputdir, tmp_filename); } } file_base_len = strlen(filename); if (config.max_records != 0) { snprintf(filename + file_base_len, MAX_FILENAME_LEN - file_base_len, "%d", file_count); } output = fopen(filename, "w"); if (output == NULL) { fprintf(info, "error: could not open output file %s (%s)\n", filename, strerror(errno)); return -1; } } else { output = stdout; } if (ifile != NULL) { opt_count--; argv[1+opt_count] = ifile; } if (mode == mode_online) { /* live capture */ int linktype; /* * sanity check: we can't be in both offline mode and online mode * simultaneously */ if ((argc-opt_count > 1) || (ifile != NULL)) { fprintf(info, "error: both interface (%s) and pcap input file (%s) specified\n", config.interface, argv[1+opt_count]); return usage(argv[0]); } anon_print_subnets(info); signal(SIGINT, sig_close); /* Ctl-C causes graceful shutdown */ signal(SIGTERM, sig_close); // signal(SIGHUP, sig_reload); // signal(SIGTSTP, sig_reload); signal(SIGQUIT, sig_reload); /* Ctl-\ causes an info dump */ /* * set capture interface as needed */ if (strncmp(config.interface, "auto", strlen("auto")) == 0) { capture_if = ifl[0].name; fprintf(info, "starting capture on interface %s\n", ifl[0].name); } else { capture_if = config.interface; } errbuf[0] = 0; handle = pcap_open_live(capture_if, 65535, config.promisc, 10000, errbuf); if (handle == NULL) { fprintf(info, "could not open device %s: %s\n", capture_if, errbuf); return -1; } if (errbuf[0] != 0) { fprintf(stderr, "warning: %s\n", errbuf); } /* verify that we can handle the link layer headers */ linktype = pcap_datalink(handle); if (linktype != DLT_EN10MB) { fprintf(info, "device %s has unsupported linktype (%d)\n", capture_if, linktype); return -2; } if (filter_exp) { /* compile the filter expression */ if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) { fprintf(info, "error: could not parse filter %s: %s\n", filter_exp, pcap_geterr(handle)); return -3; } /* apply the compiled filter */ if (pcap_setfilter(handle, &fp) == -1) { fprintf(info, "error: could not install filter %s: %s\n", filter_exp, pcap_geterr(handle)); return -4; } } /* * run as daemon, if so configured, without closing stderr and * stdout, and without changing the working directory */ if (config.daemon) { daemon(1, 1); } /* * flush "info" output stream to ensure log file accuracy */ fflush(info); /* * write out JSON preamble */ fprintf(output, "{\n"); config_print_json(output, &config); fprintf(output, "\"appflows\": [\n"); while(1) { struct timeval time_of_day, inactive_flow_cutoff; /* loop over packets captured from interface */ pcap_loop(handle, NUM_PACKETS_IN_LOOP, process_packet, NULL); if (output_level > none) { fprintf(output, "# pcap processing loop done\n"); } if (config.report_exe) { /* * periodically obtain host/process flow data */ if (get_host_flow_data() != 0) { fprintf(info, "warning: could not obtain host/process flow data\n"); } } /* * periodically report on progress */ if ((flocap_stats_get_num_packets() % NUM_PACKETS_BETWEEN_STATS_OUTPUT) == 0) { flocap_stats_output(info); } /* print out inactive flows */ gettimeofday(&time_of_day, NULL); timer_sub(&time_of_day, &time_window, &inactive_flow_cutoff); flow_record_list_print_json(&inactive_flow_cutoff); if (config.filename) { /* rotate output file if needed */ if (config.max_records && (records_in_file > config.max_records)) { /* * write JSON postamble */ fprintf(output, "\n] }\n"); fclose(output); if (config.upload_servername) { upload_file(filename, config.upload_servername, config.upload_key, config.retain_local); } // printf("records: %d\tmax_records: %d\n", records_in_file, config.max_records); file_count++; if (config.max_records != 0) { snprintf(filename + file_base_len, MAX_FILENAME_LEN - file_base_len, "%d", file_count); } output = fopen(filename, "w"); if (output == NULL) { perror("error: could not open output file"); return -1; } records_in_file = 0; fprintf(output, "{ \"appflows\": [\n"); } /* * flush out buffered debug/info/log messages on the "info" stream */ fflush(info); } // fflush(output); } fprintf(output, "\n] }\n"); if (filter_exp) { pcap_freecode(&fp); } pcap_close(handle); } else { /* mode = mode_offline */ if ((argc-opt_count <= 1) && (ifile == NULL)) { fprintf(stderr, "error: missing pcap file name(s)\n"); return usage(argv[0]); } fprintf(output, "{\n"); config_print_json(output, &config); fprintf(output, "\"appflows\": [\n"); flow_record_list_init(); flocap_stats_timer_init(); for (i=1+opt_count; i<argc; i++) { if (stat(argv[i], &sb) == 0 && S_ISDIR(sb.st_mode)) { if ((dir = opendir(argv[i])) != NULL) { while ((ent = readdir(dir)) != NULL) { if (strcmp(ent->d_name, ".") && strcmp(ent->d_name, "..")) { strcpy(pcap_filename, argv[i]); if (pcap_filename[strlen(pcap_filename)-1] != '/') { strcat(pcap_filename, "/"); } strcat(pcap_filename, ent->d_name); tmp_ret = process_pcap_file(pcap_filename, filter_exp, &net, &fp); if (tmp_ret < 0) { return tmp_ret; } } } closedir(dir); } else { /* error opening directory*/ printf("Error opening directory: %s\n", argv[i]); return -1; } } else { tmp_ret = process_pcap_file(argv[i], filter_exp, &net, &fp); if (tmp_ret < 0) { return tmp_ret; } } } fprintf(output, "\n]"); fprintf(output, "\n}\n"); } flocap_stats_output(info); // config_print(info, &config); return 0; }
int hpx_init(int *argc, char ***argv) { int status = HPX_SUCCESS; // Start the internal clock libhpx_time_start(); here = malloc(sizeof(*here)); if (!here) { status = log_error("failed to allocate a locality.\n"); goto unwind0; } here->rank = -1; here->ranks = 0; here->epoch = 0; sigset_t set; sigemptyset(&set); dbg_check(pthread_sigmask(SIG_BLOCK, &set, &here->mask)); here->config = config_new(argc, argv); if (!here->config) { status = log_error("failed to create a configuration.\n"); goto unwind1; } // check to see if everyone is waiting if (config_dbg_waitat_isset(here->config, HPX_LOCALITY_ALL)) { dbg_wait(); } // bootstrap here->boot = boot_new(here->config->boot); if (!here->boot) { status = log_error("failed to bootstrap.\n"); goto unwind1; } here->rank = boot_rank(here->boot); here->ranks = boot_n_ranks(here->boot); // initialize the debugging system // @todo We would like to do this earlier but MPI_init() for the bootstrap // network overwrites our segv handler. if (LIBHPX_OK != dbg_init(here->config)) { goto unwind1; } // Now that we know our rank, we can be more specific about waiting. if (config_dbg_waitat_isset(here->config, here->rank)) { // Don't wait twice. if (!config_dbg_waitat_isset(here->config, HPX_LOCALITY_ALL)) { dbg_wait(); } } // see if we're supposed to output the configuration, only do this at rank 0 if (config_log_level_isset(here->config, HPX_LOG_CONFIG)) { if (here->rank == 0) { config_print(here->config, stdout); } } // topology discovery and initialization here->topology = topology_new(here->config); if (!here->topology) { status = log_error("failed to discover topology.\n"); goto unwind1; } // Initialize our instrumentation. if (inst_init(here->config)) { log_dflt("error detected while initializing instrumentation\n"); } // Allocate the global heap. here->gas = gas_new(here->config, here->boot); if (!here->gas) { status = log_error("failed to create the global address space.\n"); goto unwind1; } HPX_HERE = HPX_THERE(here->rank); here->percolation = percolation_new(); if (!here->percolation) { status = log_error("failed to activate percolation.\n"); goto unwind1; } int cores = system_get_available_cores(); dbg_assert(cores > 0); if (!here->config->threads) { here->config->threads = cores; } log_dflt("HPX running %d worker threads on %d cores\n", here->config->threads, cores); here->net = network_new(here->config, here->boot, here->gas); if (!here->net) { status = log_error("failed to create network.\n"); goto unwind1; } // thread scheduler here->sched = scheduler_new(here->config); if (!here->sched) { status = log_error("failed to create scheduler.\n"); goto unwind1; } #ifdef HAVE_APEX // initialize APEX, give this main thread a name apex_init("HPX WORKER THREAD"); apex_set_node_id(here->rank); #endif action_registration_finalize(); inst_start(); // start the scheduler, this will return after scheduler_shutdown() if (scheduler_startup(here->sched, here->config) != LIBHPX_OK) { log_error("scheduler shut down with error.\n"); goto unwind1; } if ((here->ranks > 1 && here->config->gas != HPX_GAS_AGAS) || !here->config->opt_smp) { status = hpx_run(&_hpx_143_fix); } return status; unwind1: _stop(here); _cleanup(here); unwind0: return status; }
struct shear* shear_init(const char* config_file) { struct shear* shear = calloc(1, sizeof(struct shear)); if (shear == NULL) { printf("Failed to alloc shear struct\n"); exit(EXIT_FAILURE); } shear->config=config_read(config_file); struct config* config=shear->config; printf("config structure:\n"); config_print(config); // the temporary output file where we write everything locally, then copy // to the nfs file system after shear_open_output(shear); // now initialize the structures we need printf("Initalizing cosmo in flat universe\n"); int flat=1; double omega_k=0; shear->cosmo = cosmo_new(config->H0, flat, config->omega_m, 1-config->omega_m, omega_k); printf("cosmo structure:\n"); cosmo_print(shear->cosmo); printf("Initalizing healpix at nside: %ld\n", config->nside); shear->hpix = hpix_new(config->nside); // this is a growable stack for holding pixels printf("Creating pixel stack\n"); shear->pixstack = i64stack_new(0); //shear->pixstack->realloc_multval = 1.1; // finally read the data shear->lcat = lcat_read(config->lens_file); printf("Adding Dc to lenses\n"); lcat_add_da(shear->lcat, shear->cosmo); //lcat_print_firstlast(shear->lcat); lcat_print_one(shear->lcat, shear->lcat->size-1); shear->scat = scat_read(config->source_file); printf("Adding hpixid to sources\n"); scat_add_hpixid(shear->scat, shear->hpix); printf("Adding revind to scat\n"); scat_add_rev(shear->scat, shear->hpix); #ifdef WITH_TRUEZ scat_add_dc(shear->scat, shear->cosmo); #endif //scat_print_firstlast(shear->scat); scat_print_one(shear->scat, shear->scat->size-1); //sleep(1000); #ifdef NO_INCREMENTAL_WRITE // this holds the sums for each lens shear->lensums = lensums_new(shear->lcat->size, config->nbin); for (size_t i=0; i<shear->lensums->size; i++) { shear->lensums->data[i].zindex = shear->lcat->data[i].zindex; } #else shear->lensum = lensum_new(config->nbin); shear->lensum_tot = lensum_new(config->nbin); #endif return shear; }
int main(int argc, char *argv[]) { struct benchmark_config cfg; memset(&cfg, 0, sizeof(struct benchmark_config)); if (config_parse_args(argc, argv, &cfg) < 0) { usage(); } config_init_defaults(&cfg); log_level = cfg.debug; if (cfg.show_config) { fprintf(stderr, "============== Configuration values: ==============\n"); config_print(stdout, &cfg); fprintf(stderr, "===================================================\n"); } struct rlimit rlim; if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) { benchmark_error_log("error: getrlimit failed: %s\n", strerror(errno)); exit(1); } if (cfg.unix_socket != NULL && (cfg.server != NULL || cfg.port > 0)) { benchmark_error_log("error: UNIX domain socket and TCP cannot be used together.\n"); exit(1); } unsigned int fds_needed = (cfg.threads * cfg.clients) + (cfg.threads * 10) + 10; if (fds_needed > rlim.rlim_cur) { if (fds_needed > rlim.rlim_max && getuid() != 0) { benchmark_error_log("error: running the tool with this number of connections requires 'root' privilegs.\n"); exit(1); } rlim.rlim_cur = rlim.rlim_max = fds_needed; if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) { benchmark_error_log("error: setrlimit failed: %s\n", strerror(errno)); exit(1); } } // create and configure object generator object_generator* obj_gen = NULL; imported_keylist* keylist = NULL; if (!cfg.data_import) { if (cfg.data_verify) { fprintf(stderr, "error: use data-verify only with data-import\n"); exit(1); } if (cfg.no_expiry) { fprintf(stderr, "error: use no-expiry only with data-import\n"); exit(1); } obj_gen = new object_generator(); assert(obj_gen != NULL); } else { // check paramters if (cfg.data_size || cfg.data_size_list.is_defined() || cfg.data_size_range.is_defined()) { fprintf(stderr, "error: data size cannot be specified when importing.\n"); exit(1); } if (cfg.random_data) { fprintf(stderr, "error: random-data cannot be specified when importing.\n"); exit(1); } if (!cfg.generate_keys && (cfg.key_maximum || cfg.key_minimum || cfg.key_prefix)) { fprintf(stderr, "error: use key-minimum, key-maximum and key-prefix only with generate-keys.\n"); exit(1); } if (!cfg.generate_keys) { // read keys fprintf(stderr, "Reading keys from %s...", cfg.data_import); keylist = new imported_keylist(cfg.data_import); assert(keylist != NULL); if (!keylist->read_keys()) { fprintf(stderr, "\nerror: failed to read keys.\n"); exit(1); } else { fprintf(stderr, " %u keys read.\n", keylist->size()); } } obj_gen = new import_object_generator(cfg.data_import, keylist, cfg.no_expiry); assert(obj_gen != NULL); if (dynamic_cast<import_object_generator*>(obj_gen)->open_file() != true) { fprintf(stderr, "error: %s: failed to open.\n", cfg.data_import); exit(1); } } if (cfg.authenticate) { if (strcmp(cfg.protocol, "redis") != 0 && strcmp(cfg.protocol, "memcache_binary") != 0) { fprintf(stderr, "error: authenticate can only be used with redis or memcache_binary.\n"); usage(); } if (strcmp(cfg.protocol, "memcache_binary") == 0 && strchr(cfg.authenticate, ':') == NULL) { fprintf(stderr, "error: binary_memcache credentials must be in the form of USER:PASSWORD.\n"); usage(); } } if (cfg.select_db > 0 && strcmp(cfg.protocol, "redis")) { fprintf(stderr, "error: select-db can only be used with redis protocol.\n"); usage(); } if (cfg.data_offset > 0) { if (cfg.data_offset > (1<<29)-1) { fprintf(stderr, "error: data-offset too long\n"); usage(); } if (cfg.expiry_range.min || cfg.expiry_range.max || strcmp(cfg.protocol, "redis")) { fprintf(stderr, "error: data-offset can only be used with redis protocol, and cannot be used with expiry\n"); usage(); } } if (cfg.data_size) { if (cfg.data_size_list.is_defined() || cfg.data_size_range.is_defined()) { fprintf(stderr, "error: data-size cannot be used with data-size-list or data-size-range.\n"); usage(); } obj_gen->set_data_size_fixed(cfg.data_size); } else if (cfg.data_size_list.is_defined()) { if (cfg.data_size_range.is_defined()) { fprintf(stderr, "error: data-size-list cannot be used with data-size-range.\n"); usage(); } obj_gen->set_data_size_list(&cfg.data_size_list); } else if (cfg.data_size_range.is_defined()) { obj_gen->set_data_size_range(cfg.data_size_range.min, cfg.data_size_range.max); obj_gen->set_data_size_pattern(cfg.data_size_pattern); } else if (!cfg.data_import) { fprintf(stderr, "error: data-size, data-size-list or data-size-range must be specified.\n"); usage(); } if (!cfg.data_import) { obj_gen->set_random_data(cfg.random_data); } if (!cfg.data_import || cfg.generate_keys) { obj_gen->set_key_prefix(cfg.key_prefix); obj_gen->set_key_range(cfg.key_minimum, cfg.key_maximum); } if (cfg.key_stddev>0 || cfg.key_median>0) { if (cfg.key_pattern[0]!='G' && cfg.key_pattern[2]!='G') { fprintf(stderr, "error: key-stddev and key-median are only allowed together with key-pattern set to G.\n"); usage(); } if (cfg.key_median!=0 && (cfg.key_median<cfg.key_minimum || cfg.key_median>cfg.key_maximum)) { fprintf(stderr, "error: key-median must be between key-minimum and key-maximum.\n"); usage(); } obj_gen->set_key_distribution(cfg.key_stddev, cfg.key_median); } obj_gen->set_expiry_range(cfg.expiry_range.min, cfg.expiry_range.max); // Prepare output file FILE *outfile; if (cfg.out_file != NULL) { fprintf(stderr, "Writing results to %s...\n", cfg.out_file); outfile = fopen(cfg.out_file, "w"); if (!outfile) { perror(cfg.out_file); } } else { outfile = stdout; } if (!cfg.verify_only) { std::vector<run_stats> all_stats; for (unsigned int run_id = 1; run_id <= cfg.run_count; run_id++) { if (run_id > 1) sleep(1); // let connections settle run_stats stats = run_benchmark(run_id, &cfg, obj_gen); all_stats.push_back(stats); } // Print some run information fprintf(outfile, "%-9u Threads\n" "%-9u Connections per thread\n" "%-9u %s\n", cfg.threads, cfg.clients, cfg.requests > 0 ? cfg.requests : cfg.test_time, cfg.requests > 0 ? "Requests per thread" : "Seconds"); // If more than 1 run was used, compute best, worst and average if (cfg.run_count > 1) { unsigned int min_ops_sec = (unsigned int) -1; unsigned int max_ops_sec = 0; run_stats* worst = NULL; run_stats* best = NULL; for (std::vector<run_stats>::iterator i = all_stats.begin(); i != all_stats.end(); i++) { unsigned long usecs = i->get_duration_usec(); unsigned int ops_sec = (int)(((double)i->get_total_ops() / (usecs > 0 ? usecs : 1)) * 1000000); if (ops_sec < min_ops_sec || worst == NULL) { min_ops_sec = ops_sec; worst = &(*i); } if (ops_sec > max_ops_sec || best == NULL) { max_ops_sec = ops_sec; best = &(*i); } } fprintf(outfile, "\n\n" "BEST RUN RESULTS\n" "========================================================================\n"); best->print(outfile, !cfg.hide_histogram); fprintf(outfile, "\n\n" "WORST RUN RESULTS\n" "========================================================================\n"); worst->print(outfile, !cfg.hide_histogram); fprintf(outfile, "\n\n" "AGGREGATED AVERAGE RESULTS (%u runs)\n" "========================================================================\n", cfg.run_count); run_stats average; average.aggregate_average(all_stats); average.print(outfile, !cfg.hide_histogram); } else { all_stats.begin()->print(outfile, !cfg.hide_histogram); } } // If needed, data verification is done now... if (cfg.data_verify) { struct event_base *verify_event_base = event_base_new(); abstract_protocol *verify_protocol = protocol_factory(cfg.protocol); verify_client *client = new verify_client(verify_event_base, &cfg, verify_protocol, obj_gen); fprintf(outfile, "\n\nPerforming data verification...\n"); // Run client in verification mode client->prepare(); event_base_dispatch(verify_event_base); fprintf(outfile, "Data verification completed:\n" "%-10llu keys verified successfuly.\n" "%-10llu keys failed.\n", client->get_verified_keys(), client->get_errors()); // Clean up... delete client; delete verify_protocol; event_base_free(verify_event_base); } if (outfile != stdout) { fclose(outfile); } delete obj_gen; if (keylist != NULL) delete keylist; }
int main(int argc, char *argv[]) { char c; pool_conf_t *conf = NULL; const char *static_conf_loc; (void) getpname(argv[0]); (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); while ((c = getopt(argc, argv, "cdensx")) != EOF) { switch (c) { case 'c': /* Create (or modify) system configuration */ Cflag++; break; case 'd': /* Disable the pools facility */ Dflag++; break; case 'e': /* Enable the pools facility */ Eflag++; break; case 'n': /* Don't actually do anything */ Nflag++; break; case 's': /* Update the submitted configuration */ Sflag++; break; case 'x': /* Delete current system configuration */ Xflag++; break; case '?': default: usage(); /*NOTREACHED*/ } } /* * Not all flags can be used at the same time. */ if ((Cflag || Sflag || Dflag || Eflag) && Xflag) usage(); if ((Dflag || Eflag) && (Cflag || Sflag || Xflag)) usage(); if (Dflag && Eflag) usage(); argc -= optind; argv += optind; if (! (Cflag || Sflag)) { if (argc != 0) usage(); } else { if (argc == 0) static_conf_loc = pool_static_location(); else if (argc == 1) static_conf_loc = argv[0]; else usage(); } if (!Nflag && (Cflag + Dflag + Eflag + Xflag != 0) && !priv_ineffect(PRIV_SYS_RES_CONFIG)) die(gettext(ERR_PERMISSIONS)); if (Dflag) { if (pool_set_status(POOL_DISABLED) != PO_SUCCESS) die(gettext(ERR_DISABLE)); } else if (Eflag) { if (pool_set_status(POOL_ENABLED) != PO_SUCCESS) { if (errno == EEXIST) die(gettext(ERR_ENABLE ": System has active processor sets\n")); else die(gettext(ERR_ENABLE)); } } else { if ((conf = pool_conf_alloc()) == NULL) die(gettext(ERR_NOMEM)); if (Cflag + Sflag + Xflag == 0) { /* * No flags means print current system configuration */ config_print(conf); } else if (!Nflag && Xflag) { /* * Destroy active pools configuration and * remove the state file. */ config_destroy(conf); } else { /* * Commit a new configuration. */ if (Cflag) config_commit(conf, static_conf_loc); else { /* * Dump the dynamic state to the * specified location */ if (!Nflag && Sflag) { if (pool_conf_open(conf, pool_dynamic_location(), PO_RDONLY) != PO_SUCCESS) die(gettext(ERR_OPEN_DYNAMIC), get_errstr()); if (pool_conf_export(conf, static_conf_loc, POX_NATIVE) != PO_SUCCESS) die(gettext(ERR_EXPORT_DYNAMIC), static_conf_loc, get_errstr()); (void) pool_conf_close(conf); } } } pool_conf_free(conf); } return (E_PO_SUCCESS); }
static int cmd_config_print(struct re_printf *pf, void *unused) { (void)unused; return config_print(pf, conf_config()); }
int main(int argc, char *argv[]) { struct radclock_handle *handle; struct radclock_config *conf; int is_daemon = 0; /* File and command line reading */ int ch; /* Mask variable used to know which parameter to update */ uint32_t param_mask = 0; /* PID lock file for daemon */ int daemon_pid_fd = 0; /* Initialize PID lockfile to a default value */ const char *pid_lockfile = DAEMON_LOCK_FILE; /* Misc */ int err; /* turn off buffering to allow results to be seen immediately if JDEBUG*/ #ifdef WITH_JDEBUG setvbuf(stdout, (char *)NULL, _IONBF, 0); setvbuf(stderr, (char *)NULL, _IONBF, 0); #endif /* * Register Signal handlers. We use sigaction() instead of signal() to catch * signals. The main reason concerns the SIGHUP signal. In Linux, the * syscalls are restarted as soon as the signal handler returns. This * prevent pcap_breakloop() to do its job (see pcap man page). Using * sigaction() we can overwrite the default flag to prevent this behavior */ sigset_t block_mask; sigfillset (&block_mask); struct sigaction sig_struct; sig_struct.sa_handler = signal_handler; sig_struct.sa_mask = block_mask; sig_struct.sa_flags = 0; sigaction(SIGHUP, &sig_struct, NULL); /* hangup signal (1) */ sigaction(SIGTERM, &sig_struct, NULL); /* software termination signal (15) */ sigaction(SIGUSR1, &sig_struct, NULL); /* user signal 1 (30) */ sigaction(SIGUSR2, &sig_struct, NULL); /* user signal 2 (31) */ /* Initialise verbose data to defaults */ verbose_data.handle = NULL; verbose_data.is_daemon = 0; verbose_data.verbose_level = 0; verbose_data.fd = NULL; strcpy(verbose_data.logfile, ""); pthread_mutex_init(&(verbose_data.vmutex), NULL); /* Management of configuration options */ conf = (struct radclock_config *) malloc(sizeof(struct radclock_config)); JDEBUG_MEMORY(JDBG_MALLOC, conf); memset(conf, 0, sizeof(struct radclock_config)); /* * The command line arguments are given the priority and override possible * values of the configuration file But the configuration file is parsed * after the command line because we need to know if we are running a daemon * or not (configuration file is different if we run a daemon or not). Use * the param_mask variable to indicate which values have to be updated from * the config file */ /* Initialize the physical parameters, and other config parameters. */ config_init(conf); /* Init the mask we use to signal configuration updates */ param_mask = UPDMASK_NOUPD; /* Reading the command line arguments */ while ((ch = getopt(argc, argv, "dxvhc:i:l:n:t:r:w:s:a:o:p:P:U:D:V")) != -1) switch (ch) { case 'x': SET_UPDATE(param_mask, UPDMASK_SERVER_IPC); conf->server_ipc = BOOL_OFF; break; case 'c': strcpy(conf->conffile, optarg); break; case 'd': is_daemon = 1; break; case 'l': strcpy(conf->logfile, optarg); break; case 'n': if (strlen(optarg) > MAXLINE) { fprintf(stdout, "ERROR: parameter too long\n"); exit (1); } SET_UPDATE(param_mask, UPDMASK_HOSTNAME); strcpy(conf->hostname, optarg); break; case 'p': SET_UPDATE(param_mask, UPDMASK_POLLPERIOD); if ( atoi(optarg) < RAD_MINPOLL ) { conf->poll_period = RAD_MINPOLL; fprintf(stdout, "Warning: Poll period too small, set to %d\n", conf->poll_period); } else conf->poll_period = atoi(optarg); if ( conf->poll_period > RAD_MAXPOLL ) { conf->poll_period = RAD_MAXPOLL; fprintf(stdout, "Warning: Poll period too big, set to %d\n", conf->poll_period); } break; case 't': if (strlen(optarg) > MAXLINE) { fprintf(stdout, "ERROR: parameter too long\n"); exit (1); } SET_UPDATE(param_mask, UPDMASK_TIME_SERVER); strcpy(conf->time_server, optarg); break; case 'i': if (strlen(optarg) > MAXLINE) { fprintf(stdout, "ERROR: parameter too long\n"); exit (1); } SET_UPDATE(param_mask, UPDMASK_NETWORKDEV); strcpy(conf->network_device, optarg); break; case 'r': if (strlen(optarg) > MAXLINE) { fprintf(stdout, "ERROR: parameter too long\n"); exit (1); } SET_UPDATE(param_mask, UPDMASK_SYNC_IN_PCAP); strcpy(conf->sync_in_pcap, optarg); break; case 'w': if (strlen(optarg) > MAXLINE) { fprintf(stdout, "ERROR: parameter too long\n"); exit (1); } SET_UPDATE(param_mask, UPDMASK_SYNC_OUT_PCAP); strcpy(conf->sync_out_pcap, optarg); break; case 's': if (strlen(optarg) > MAXLINE) { fprintf(stdout, "ERROR: parameter too long\n"); exit (1); } SET_UPDATE(param_mask, UPDMASK_SYNC_IN_ASCII); strcpy(conf->sync_in_ascii, optarg); break; case 'a': if (strlen(optarg) > MAXLINE) { fprintf(stdout, "ERROR: parameter too long\n"); exit (1); } SET_UPDATE(param_mask, UPDMASK_SYNC_OUT_ASCII); strcpy(conf->sync_out_ascii, optarg); break; case 'o': if (strlen(optarg) > MAXLINE) { fprintf(stdout, "ERROR: parameter too long\n"); exit (1); } SET_UPDATE(param_mask, UPDMASK_CLOCK_OUT_ASCII); strcpy(conf->clock_out_ascii, optarg); break; case 'P': if (strlen(optarg) > MAXLINE) { fprintf(stdout, "ERROR: parameter too long\n"); exit (1); } SET_UPDATE(param_mask, UPDMASK_PID_FILE); pid_lockfile = optarg; break; case 'v': SET_UPDATE(param_mask, UPDMASK_VERBOSE); conf->verbose_level++; break; case 'U': SET_UPDATE(param_mask, UPD_NTP_UPSTREAM_PORT); conf->ntp_upstream_port = atoi(optarg); break; case 'D': SET_UPDATE(param_mask, UPD_NTP_DOWNSTREAM_PORT); conf->ntp_downstream_port = atoi(optarg); break; case 'V': fprintf(stdout, "%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION); case 'h': case '?': default: usage(); } argc -= optind; argv += optind; /* Little hack to deal with parsing of long options in the command line */ if (conf->verbose_level > 0) SET_UPDATE(param_mask, UPDMASK_VERBOSE); /* Create the radclock handle */ clock_handle = create_handle(conf, is_daemon); if (!clock_handle) { verbose(LOG_ERR, "Could not create clock handle"); return (-1); } handle = clock_handle; /* * Have not parsed the config file yet, so will have to do it again since it * may not be the right settings. Handles config parse messages in the right * log file though. So far clock has not been sent to init, no syscall * registered, pass a NULL pointer to verbose. */ set_verbose(handle, handle->conf->verbose_level, 0); set_logger(logger_verbose_bridge); /* Daemonize now, so that we can open the log files and close connection to * stdin since we parsed the command line */ if (handle->is_daemon) { struct stat sb; if (stat(RADCLOCK_RUN_DIRECTORY, &sb) < 0) { if (mkdir(RADCLOCK_RUN_DIRECTORY, 0755) < 0) { verbose(LOG_ERR, "Cannot create %s directory. Run as root or " "(!daemon && !server)", RADCLOCK_RUN_DIRECTORY); return (1); } } /* Check this everytime in case something happened */ chmod(RADCLOCK_RUN_DIRECTORY, 00755); if (!(daemonize(pid_lockfile, &daemon_pid_fd))) { fprintf(stderr, "Error: did not manage to create the daemon\n"); exit(EXIT_FAILURE); } } /* * Retrieve configuration from the config file (write it down if it does not * exist) That should be the only occasion when get_config() is called and * the param_mask is not positioned to UPDMASK_NOUPD !!! Only the * parameters not specified on the command line are updated */ if (!config_parse(handle->conf, ¶m_mask, handle->is_daemon)) return (0); /* * Now that we have the configuration to use (verbose level), let's * initialise the verbose level to correct value */ set_verbose(handle, handle->conf->verbose_level, 0); set_logger(logger_verbose_bridge); /* Check for incompatible configurations and correct them */ if (( handle->conf->synchro_type == SYNCTYPE_SPY ) || ( handle->conf->synchro_type == SYNCTYPE_PIGGY )) { if (handle->conf->server_ntp == BOOL_ON) { verbose(LOG_ERR, "Configuration error. Disabling NTP server " "(incompatible with spy or piggy mode)."); handle->conf->server_ntp = BOOL_OFF; } if ( handle->conf->adjust_sysclock == BOOL_ON ) { verbose(LOG_ERR, "Configuration error. Disabling adjust system " "clock (incompatible with spy or piggy mode)."); handle->conf->adjust_sysclock = BOOL_OFF; } } /* Diagnosis output for the configuration used */ config_print(LOG_NOTICE, handle->conf); /* Reinit the mask that counts updated values */ param_mask = UPDMASK_NOUPD; // TODO extract extra checks from is_live_source and make an input fix // function instead, would be clearer // TODO the conf->network_device business is way too messy /* * Need to know if we are replaying data or not. If not, no need to create * shared global data on the system or open a BPF. This define input to the * init of the radclock handle */ if (!is_live_source(handle)) handle->run_mode = RADCLOCK_SYNC_DEAD; else handle->run_mode = RADCLOCK_SYNC_LIVE; /* Init clock handle and private data */ if (handle->run_mode == RADCLOCK_SYNC_LIVE) { err = clock_init_live(handle->clock, &handle->rad_data); if (err) { verbose(LOG_ERR, "Could not initialise the RADclock"); return (1); } } /* Init radclock specific stuff */ err = init_handle(handle); if (err) { verbose(LOG_ERR, "Radclock process specific init failed."); return (1); } /* * Now 2 cases. Either we are running live or we are replaying some data. * If we run live, we will spawn some threads and do some smart things. If * we replay data, no need to do all of that, we access data and process it * in the same thread. */ if (handle->run_mode == RADCLOCK_SYNC_DEAD) { // TODO : manage peers better !! struct bidir_peer peer; /* Some basic initialisation which is required */ init_peer_stamp_queue(&peer); peer.stamp_i = 0; // TODO XXX Need to manage peers better !! /* Register active peer */ handle->active_peer = (void *)&peer; while (1) { err = process_rawdata(handle, &peer); if (err < 0) break; } destroy_peer_stamp_queue(&peer); } /* * We loop in here in case we are rehashed. Threads are (re-)created every * time we loop in */ else { while (err == 0) { err = start_live(handle); if (err == 0) { if (rehash_daemon(handle, param_mask)) verbose(LOG_ERR, "SIGHUP - Failed to rehash daemon !!."); } } } // TODO: look into making the stats a separate structure. Could be much // TODO: easier to manage long int n_stamp; unsigned int ref_count; n_stamp = ((struct bidir_output *)handle->algo_output)->n_stamps; ref_count = ((struct stampsource*)(handle->stamp_source))->ntp_stats.ref_count; verbose(LOG_NOTICE, "%u NTP packets captured", ref_count); verbose(LOG_NOTICE,"%ld missed NTP packets", ref_count - 2 * n_stamp); verbose(LOG_NOTICE, "%ld valid timestamp tuples extracted", n_stamp); /* Close output files */ close_output_stamp(handle); /* Print out last good phat value */ verbose(LOG_NOTICE, "Last estimate of the clock source period: %12.10lg", RAD_DATA(handle)->phat); /* Say bye and close syslog */ verbose(LOG_NOTICE, "RADclock stopped"); if (handle->is_daemon) closelog (); unset_verbose(); /* Free the lock file */ if (handle->is_daemon) { write(daemon_pid_fd, "", 0); lockf(daemon_pid_fd, F_ULOCK, 0); } // TODO: all the destructors have to be re-written destroy_source(handle, (struct stampsource *)(handle->stamp_source)); /* Clear thread stuff */ pthread_mutex_destroy(&(handle->globaldata_mutex)); pthread_mutex_destroy(&(handle->wakeup_mutex)); pthread_cond_destroy(&(handle->wakeup_cond)); /* Detach IPC shared memory if were running as IPC server. */ if (handle->conf->server_ipc == BOOL_ON) shm_detach(handle->clock); /* Free the clock structure. All done. */ pthread_mutex_destroy(&(handle->pcap_queue->rdb_mutex)); pthread_mutex_destroy(&(handle->ieee1588eq_queue->rdb_mutex)); free(handle->pcap_queue); free(handle->ieee1588eq_queue); free(handle); handle = NULL; clock_handle = NULL; exit(EXIT_SUCCESS); }
// TODO : Reload of individual physical parameters is not handled static int rehash_daemon(struct radclock_handle *handle, uint32_t param_mask) { struct radclock_config *conf; int err; JDEBUG conf = handle->conf; verbose(LOG_NOTICE, "Update of configuration parameters"); /* Parse the configuration file */ if (!(config_parse(conf, ¶m_mask, handle->is_daemon))) { verbose(LOG_ERR, "Error: Rehash of configuration file failed"); return (1); } if (HAS_UPDATE(param_mask, UPDMASK_SYNCHRO_TYPE)) verbose(LOG_WARNING, "It is not possible to change the type of client " "synchronisation on the fly!"); //XXX Should check we have only one input selected if (HAS_UPDATE(param_mask, UPDMASK_NETWORKDEV) || HAS_UPDATE(param_mask, UPDMASK_SYNC_IN_PCAP) || HAS_UPDATE(param_mask, UPDMASK_SYNC_IN_ASCII)) { verbose(LOG_WARNING, "It is not possible to change the type of input " "on the fly!"); verbose(LOG_WARNING, "Parameter is parsed and saved but not taken " "into account"); CLEAR_UPDATE(param_mask, UPDMASK_NETWORKDEV); CLEAR_UPDATE(param_mask, UPDMASK_SYNC_IN_PCAP); CLEAR_UPDATE(param_mask, UPDMASK_SYNC_IN_ASCII); } // TODO The old naming convention for server IPC could be changed for clarity. // Would require an update of config file parsing. if (HAS_UPDATE(param_mask, UPDMASK_SERVER_IPC)) { switch (conf->server_ipc) { case BOOL_ON: err = shm_init_writer(handle->clock); if (err) return (1); verbose(LOG_NOTICE, "IPC Shared Memory ready"); break; case BOOL_OFF: /* Detach for SHM segment, but do not destroy it */ shm_detach(handle->clock); break; } } if (HAS_UPDATE(param_mask, UPDMASK_SERVER_NTP)) { switch (conf->server_ntp) { case BOOL_ON: /* We start NTP server */ start_thread_NTP_SERV(handle); break; case BOOL_OFF: /* We stop the NTP server */ handle->pthread_flag_stop |= PTH_NTP_SERV_STOP; // TODO should we join the thread in here ... requires testing // pthread_join(handle->threads[PTH_NTP_SERV], &thread_status); break; } } if (HAS_UPDATE(param_mask, UPDMASK_SERVER_VM_UDP)) { switch (conf->server_vm_udp) { case BOOL_ON: /* We start NTP server */ start_thread_VM_UDP_SERV(handle); break; case BOOL_OFF: /* We stop the NTP server */ clock_handle->pthread_flag_stop |= PTH_VM_UDP_SERV_STOP; // TODO should we join the thread in here ... requires testing // pthread_join(clock_handle->threads[PTH_VM_UDP_SERV], &thread_status); break; } } /* Management of output files */ if (HAS_UPDATE(param_mask, UPDMASK_SYNC_OUT_ASCII)) { close_output_stamp(handle); open_output_stamp(handle); CLEAR_UPDATE(param_mask, UPDMASK_SYNC_OUT_ASCII); } if (HAS_UPDATE(param_mask, UPDMASK_CLOCK_OUT_ASCII)) { close_output_matlab(handle); open_output_matlab(handle); CLEAR_UPDATE(param_mask, UPDMASK_CLOCK_OUT_ASCII); } if (HAS_UPDATE(param_mask, UPDMASK_SYNC_OUT_PCAP)) { err = update_dumpout_source(handle, (struct stampsource *)handle->stamp_source); if (err != 0) { verbose(LOG_ERR, "Things are probably out of control. Bye !"); exit (1); } CLEAR_UPDATE(param_mask, UPDMASK_SYNC_OUT_PCAP); } /* Change the filter on the open BPF device */ if (HAS_UPDATE(param_mask, UPDMASK_SYNCHRO_TYPE) || HAS_UPDATE(param_mask, UPDMASK_SERVER_NTP) || HAS_UPDATE(param_mask, UPDMASK_TIME_SERVER) || HAS_UPDATE(param_mask, UPDMASK_HOSTNAME)) { err = update_filter_source(handle, (struct stampsource *)handle->stamp_source); if (err != 0) { verbose(LOG_ERR, "Things are probably out of control. Bye !"); exit (1); } CLEAR_UPDATE(param_mask, UPDMASK_TIME_SERVER); CLEAR_UPDATE(param_mask, UPDMASK_HOSTNAME); } /* Print configuration actually used */ config_print(LOG_NOTICE, conf); /* Reinit rehash flag */ // handle->unix_signal = 0; /* Push param_mask into the config so that the algo sees it, * since only algo related thing should be remaining */ conf->mask = param_mask; return (0); }