Exemple #1
0
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);
}
Exemple #2
0
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;
}
Exemple #3
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;
}
Exemple #4
0
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;
}
Exemple #6
0
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);
}
Exemple #7
0
static int cmd_config_print(struct re_printf *pf, void *unused)
{
	(void)unused;
	return config_print(pf, conf_config());
}
Exemple #8
0
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, &param_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);
}
Exemple #9
0
// 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, &param_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);
}