int main(int argc, char **argv) { cerebro_err_init(argv[0]); cerebro_err_set_flags(CEREBRO_ERROR_STDERR | CEREBRO_ERROR_SYSLOG); cerebrod_config_setup(argc, argv); #if CEREBRO_DEBUG if (!conf.debug) { cerebrod_daemon_init(); cerebro_err_set_flags(CEREBRO_ERROR_SYSLOG); } else cerebro_err_set_flags(CEREBRO_ERROR_STDERR); #else /* !CEREBRO_DEBUG */ cerebrod_daemon_init(); cerebro_err_set_flags(CEREBRO_ERROR_SYSLOG); #endif /* !CEREBRO_DEBUG */ /* Call after daemonization, since daemonization closes currently * open fds */ openlog(argv[0], LOG_ODELAY | LOG_PID, LOG_DAEMON); #if !WITH_CEREBROD_SPEAKER_ONLY /* Start metric server before the listener begins receiving data. */ if (conf.metric_server) { pthread_t thread; pthread_attr_t attr; Pthread_attr_init(&attr); Pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); Pthread_attr_setstacksize(&attr, CEREBROD_THREAD_STACKSIZE); Pthread_create(&thread, &attr, cerebrod_metric_server, NULL); Pthread_attr_destroy(&attr); /* Wait for initialization to complete */ Pthread_mutex_lock(&metric_server_init_lock); while (!metric_server_init) Pthread_cond_wait(&metric_server_init_cond, &metric_server_init_lock); Pthread_mutex_unlock(&metric_server_init_lock); } /* Start listening server before speaker so that listener * can receive packets from a later created speaker */ if (conf.listen) { int i; for (i = 0; i < conf.listen_threads; i++) { pthread_t thread; pthread_attr_t attr; Pthread_attr_init(&attr); Pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); Pthread_attr_setstacksize(&attr, CEREBROD_THREAD_STACKSIZE); Pthread_create(&thread, &attr, cerebrod_listener, NULL); Pthread_attr_destroy(&attr); } /* Wait for initialization to complete */ Pthread_mutex_lock(&listener_init_lock); while (!listener_init) Pthread_cond_wait(&listener_init_cond, &listener_init_lock); Pthread_mutex_unlock(&listener_init_lock); } /* Start all the event server, queue monitor, and node timeout * threads after the listener thread, since they use data created by * the listener thread. */ if (conf.event_server) { pthread_t thread; pthread_attr_t attr; Pthread_attr_init(&attr); Pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); Pthread_attr_setstacksize(&attr, CEREBROD_THREAD_STACKSIZE); Pthread_create(&thread, &attr, cerebrod_event_queue_monitor, NULL); Pthread_attr_destroy(&attr); /* Wait for initialization to complete */ Pthread_mutex_lock(&event_queue_monitor_init_lock); while (!event_queue_monitor_init) Pthread_cond_wait(&event_queue_monitor_init_cond, &event_queue_monitor_init_lock); Pthread_mutex_unlock(&event_queue_monitor_init_lock); Pthread_attr_init(&attr); Pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); Pthread_attr_setstacksize(&attr, CEREBROD_THREAD_STACKSIZE); Pthread_create(&thread, &attr, cerebrod_event_server, NULL); Pthread_attr_destroy(&attr); /* Wait for initialization to complete */ Pthread_mutex_lock(&event_server_init_lock); while (!event_server_init) Pthread_cond_wait(&event_server_init_cond, &event_server_init_lock); Pthread_mutex_unlock(&event_server_init_lock); Pthread_attr_init(&attr); Pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); Pthread_attr_setstacksize(&attr, CEREBROD_THREAD_STACKSIZE); Pthread_create(&thread, &attr, cerebrod_event_node_timeout_monitor, NULL); Pthread_attr_destroy(&attr); /* Wait for initialization to complete */ Pthread_mutex_lock(&event_node_timeout_monitor_init_lock); while (!event_node_timeout_monitor_init) Pthread_cond_wait(&event_node_timeout_monitor_init_cond, &event_node_timeout_monitor_init_lock); Pthread_mutex_unlock(&event_node_timeout_monitor_init_lock); } /* Start metric controller - see comments at speaker below */ if (conf.metric_controller) { pthread_t thread; pthread_attr_t attr; Pthread_attr_init(&attr); Pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); Pthread_attr_setstacksize(&attr, CEREBROD_THREAD_STACKSIZE); Pthread_create(&thread, &attr, cerebrod_metric_controller, NULL); Pthread_attr_destroy(&attr); /* Wait for initialization to complete */ Pthread_mutex_lock(&metric_controller_init_lock); while (!metric_controller_init) Pthread_cond_wait(&metric_controller_init_cond, &metric_controller_init_lock); Pthread_mutex_unlock(&metric_controller_init_lock); } #endif /* !WITH_CEREBROD_SPEAKER_ONLY */ /* Start speaker * * It may make more logical sense to start the metric controller * after the speaker since metric data cannot be propogated until * after the speaker has finished being setup. We run the speaker * last b/c it is the common case. Most machines (particularly * compute nodes in a cluster) will only speak, and do nothing else. * By having the speaker last, it does not need to run in a thread. * We run it out of "main" instead to minimize memory usage by * not needing to start the speaker in a thread. */ if (conf.speak) cerebrod_speaker(NULL); /* If speak is set, we do not reach this point */ for (;;) sleep(INT_MAX); return 0; /* NOT REACHED */ }
/* * _cmdline_parse * * parse all cmdline input */ static void _cmdline_parse(int argc, char **argv) { const char *func = __FUNCTION__; char options[1024]; char *ptr; int c; #if HAVE_GETOPT_LONG struct option loptions[] = { {"help", 0, NULL, 'h'}, {"version", 0, NULL, 'v'}, {"hostname", 1, NULL, 'o'}, {"port", 1, NULL, 'p'}, {"metric", 1, NULL, 'm'}, {"metric-list", 0, NULL, 'l'}, {"up-only", 0, NULL, 'U'}, {"none-if-down", 0, NULL, 'D'}, {"none-if-not-monitored", 0, NULL, 'N'}, {"newline", 0, NULL, 'n'}, {"hostrange", 0, NULL, 'q'}, {"metric-received-time", 0, NULL, 't'}, {"event", 1, NULL, 'e'}, {"event-list", 0, NULL, 'z'}, #if CEREBRO_DEBUG {"debug", 0, NULL, 'd'}, #endif /* CEREBRO_DEBUG */ {0, 0, 0, 0}, }; #endif /* HAVE_GETOPT_LONG */ assert(argv); strcpy(options, "hvo:p:ze:lm:UDNnqt"); #if CEREBRO_DEBUG strcat(options, "d"); #endif /* CEREBRO_DEBUG */ /* turn off output messages printed by getopt_long */ opterr = 0; #if HAVE_GETOPT_LONG while ((c = getopt_long(argc, argv, options, loptions, NULL)) != -1) #else while ((c = getopt(argc, argv, options)) != -1) #endif { switch(c) { case 'h': _usage(); case 'v': _version(); case 'o': hostname = optarg; if (cerebro_set_hostname(handle, hostname) < 0) { char *msg = cerebro_strerror(cerebro_errnum(handle)); err_exit("%s: cerebro_set_hostname: %s", func, msg); } break; case 'p': port = strtol(optarg, &ptr, 10); if (ptr != (optarg + strlen(optarg))) err_exit("invalid port specified"); if (cerebro_set_port(handle, port) < 0) { char *msg = cerebro_strerror(cerebro_errnum(handle)); err_exit("%s: cerebro_set_port: %s", func, msg); } break; case 'm': metric_name = optarg; break; case 'l': metric_list_flag++; break; case 'U': _cerebro_set_flags(CEREBRO_METRIC_DATA_FLAGS_UP_ONLY); break; case 'D': _cerebro_set_flags(CEREBRO_METRIC_DATA_FLAGS_NONE_IF_DOWN); break; case 'N': _cerebro_set_flags(CEREBRO_METRIC_DATA_FLAGS_NONE_IF_NOT_MONITORED); break; case 'n': output_type = CEREBRO_STAT_NEWLINE; break; case 'q': output_type = CEREBRO_STAT_HOSTRANGE; break; case 't': metric_received_time_flag++; break; case 'e': event_name = optarg; break; case 'z': event_list_flag++; break; #if CEREBRO_DEBUG case 'd': cerebro_err_set_flags(CEREBRO_ERROR_STDERR); break; #endif /* CEREBRO_DEBUG */ default: case '?': fprintf(stderr, "command line option error\n"); _usage(); } } if (((metric_list_flag ? 1 : 0) + (metric_name ? 1 : 0) + (event_name ? 1 : 0) + (event_list_flag ? 1 : 0)) > 1) err_exit("Specify one of --event-list, --event, --metric-list, and --metric options"); if (!event_name && !event_list_flag && !metric_list_flag && !metric_name) _usage(); }
/* * _cmdline_parse * * parse all cmdline input */ static void _cmdline_parse(int argc, char **argv) { char options[1024]; char *ptr; int c; #if HAVE_GETOPT_LONG struct option loptions[] = { {"help", 0, NULL, 'h'}, {"version", 0, NULL, 'v'}, {"metric", 1, NULL, 'm'}, {"register", 0, NULL, 'r'}, {"unregister", 0, NULL, 'u'}, {"update", 0, NULL, 'p'}, {"resend", 0, NULL, 's'}, {"flush", 0, NULL, 'f'}, {"metric-value-type", 1, NULL, 't'}, {"metric-value", 1, NULL, 'l'}, {"send-now", 0, NULL, 'N'}, #if CEREBRO_DEBUG {"debug", 0, NULL, 'd'}, #endif /* CEREBRO_DEBUG */ {0, 0, 0, 0}, }; #endif /* HAVE_GETOPT_LONG */ assert(argv); strcpy(options, "hvm:rupsft:l:N"); #if CEREBRO_DEBUG strcat(options, "d"); #endif /* CEREBRO_DEBUG */ /* turn off output messages printed by getopt_long */ opterr = 0; #if HAVE_GETOPT_LONG while ((c = getopt_long(argc, argv, options, loptions, NULL)) != -1) #else while ((c = getopt(argc, argv, options)) != -1) #endif { switch(c) { case 'h': _usage(); case 'v': _version(); case 'm': metric_name = optarg; break; case 'r': operation = CEREBRO_ADMIN_REGISTER; break; case 'u': operation = CEREBRO_ADMIN_UNREGISTER; break; case 'p': operation = CEREBRO_ADMIN_UPDATE; break; case 's': operation = CEREBRO_ADMIN_RESEND; break; case 'f': operation = CEREBRO_ADMIN_FLUSH; break; case 't': metric_value_type = strtol(optarg, &ptr, 10); if ((ptr != (optarg + strlen(optarg))) || !(metric_value_type >= CEREBRO_DATA_VALUE_TYPE_NONE && metric_value_type <= CEREBRO_DATA_VALUE_TYPE_U_INT64)) err_exit("invalid metric value type specified"); break; case 'l': metric_value = optarg; break; case 'N': _cerebro_set_flags(CEREBRO_METRIC_CONTROL_FLAGS_SEND_NOW); break; #if CEREBRO_DEBUG case 'd': cerebro_err_set_flags(CEREBRO_ERROR_STDERR); break; #endif /* CEREBRO_DEBUG */ default: case '?': fprintf(stderr, "command line option error\n"); _usage(); } } if (!metric_name || operation < 0) _usage(); if (metric_value_type != CEREBRO_DATA_VALUE_TYPE_NONE && !metric_value) err_exit("invalid metric value specified"); if (metric_value_type == CEREBRO_DATA_VALUE_TYPE_NONE) { metric_value_len = 0; metric_value_ptr = NULL; } else if (metric_value_type == CEREBRO_DATA_VALUE_TYPE_INT32) { metric_value_int32 = (int32_t)strtol(metric_value, &ptr, 10); if (ptr != (metric_value + strlen(metric_value))) err_exit("invalid metric value specified"); metric_value_len = sizeof(int32_t); metric_value_ptr = &metric_value_int32; } else if (metric_value_type == CEREBRO_DATA_VALUE_TYPE_U_INT32) { metric_value_u_int32 = (u_int32_t)strtoul(metric_value, &ptr, 10); if (ptr != (metric_value + strlen(metric_value))) err_exit("invalid metric value specified"); metric_value_len = sizeof(u_int32_t); metric_value_ptr = &metric_value_u_int32; } else if (metric_value_type == CEREBRO_DATA_VALUE_TYPE_FLOAT) { metric_value_float = (float)strtod(metric_value, &ptr); if (ptr != (metric_value + strlen(metric_value))) err_exit("invalid metric value specified"); metric_value_len = sizeof(float); metric_value_ptr = &metric_value_float; } else if (metric_value_type == CEREBRO_DATA_VALUE_TYPE_DOUBLE) { metric_value_double = strtod(metric_value, &ptr); if (ptr != (metric_value + strlen(metric_value))) err_exit("invalid metric value specified"); metric_value_len = sizeof(double); metric_value_ptr = &metric_value_double; } else if (metric_value_type == CEREBRO_DATA_VALUE_TYPE_STRING) { metric_value_string = metric_value; metric_value_len = strlen(metric_value_string); if (metric_value_len > CEREBRO_MAX_DATA_STRING_LEN) err_exit("string metric value too long"); metric_value_ptr = metric_value_string; } else if (metric_value_type == CEREBRO_DATA_VALUE_TYPE_INT64) { metric_value_int64 = (int64_t)strtoll(metric_value, &ptr, 10); if (ptr != (metric_value + strlen(metric_value))) err_exit("invalid metric value specified"); metric_value_len = sizeof(int64_t); metric_value_ptr = &metric_value_int64; } else if (metric_value_type == CEREBRO_DATA_VALUE_TYPE_U_INT64) { metric_value_u_int64 = (u_int64_t)strtoull(metric_value, &ptr, 10); if (ptr != (metric_value + strlen(metric_value))) err_exit("invalid metric value specified"); metric_value_len = sizeof(u_int64_t); metric_value_ptr = &metric_value_u_int64; } }