// start the cache thread // return 0 on success // return -1 if we failed to start the thread int md_cache_start( struct md_syndicate_cache* cache ) { // start the thread up struct md_syndicate_cache_thread_args* args = SG_CALLOC( struct md_syndicate_cache_thread_args, 1 ); args->cache = cache; cache->running = true; cache->thread = md_start_thread( md_cache_main_loop, (void*)args, false ); if( cache->thread == (pthread_t)(-1) ) { SG_error("md_start_thread rc = %d\n", (int)cache->thread ); return -1; } return 0; }
// entry point int main( int argc, char** argv ) { int rc = 0; int exit_code = 0; struct AG_state* ag = NULL; pthread_t crawl_thread; // setup... ag = AG_init( argc, argv ); if( ag == NULL ) { SG_error("%s", "AG_init failed\n" ); exit(1); } // start crawler rc = md_start_thread( &crawl_thread, AG_crawl_loop, ag, false ); if( rc != 0 ) { SG_error("md_start_thread rc = %d\n", rc ); exit(1); } // run gateway rc = AG_main( ag ); if( rc != 0 ) { SG_error("AG_main rc = %d\n", rc ); exit_code = 1; } // stop crawler g_running = false; pthread_cancel( crawl_thread ); pthread_join( crawl_thread, NULL ); // stop gateway rc = AG_shutdown( ag ); if( rc != 0 ) { SG_error("AG_shutdown rc = %d\n", rc ); } SG_safe_free( ag ); exit(exit_code); }
// program execution starts here! int main( int argc, char** argv ) { curl_global_init(CURL_GLOBAL_ALL); // start up protocol buffers GOOGLE_PROTOBUF_VERIFY_VERSION; g_config_file = strdup( METADATA_DEFAULT_CONFIG ); // process command-line options int c; int rc; bool make_daemon = true; bool good_input = true; char* mc_root = NULL; char* logfile = NULL; char* pidfile = NULL; int portnum = 0; int reload_pid = 0; while((c = getopt(argc, argv, "fc:m:p:u:l:P:k:")) != -1) { switch( c ) { case 'f': { make_daemon = false; break; } case '?': { usage( argv[0], 1 ); } case 'c': { g_config_file = realpath( optarg, NULL ); break; } case 'm': { mc_root = realpath( optarg, NULL ); break; } case 'P': { portnum = strtol( optarg, NULL, 10 ); if( portnum <= 0 ) good_input = false; break; } case 'u': { g_secrets_file = realpath( optarg, NULL ); break; } case 'l': { logfile = strdup( optarg ); break; } case 'p': { pidfile = realpath( optarg, NULL ); break; } case 'k': { reload_pid = strtol( optarg, NULL, 10 ); if( reload_pid <= 0 ) good_input = false; break; } default: { fprintf(stderr, "Ignoring unrecognized option %c\n", c); good_input = false; break; } } } if( !good_input ) { usage( argv[0], 1 ); } if( reload_pid > 0 ) { // all we're doing is telling a running metadata server to reload kill( reload_pid, SIGUSR1 ); exit(0); } // read the config struct md_syndicate_conf conf; g_conf = &conf; dbprintf("reading config %s\n", g_config_file); if( md_read_conf( g_config_file, &conf ) != 0 ) { errorf("Could not read config at %s\n", g_config_file); usage( argv[0], 1 ); } // user-given portnum? if( portnum > 0 ) { conf.portnum = portnum; } if( conf.portnum == 0 ) { errorf("Invalid port number %d. Specify PORTNUM in the config file or pass -p\n", conf.portnum); exit(1); } // master copy supplied in args? if( mc_root ) { if( conf.master_copy_root ) { free( conf.master_copy_root ); } conf.master_copy_root = mc_root; } // secrets file supplied in args? if( g_secrets_file ) { if( conf.secrets_file ) { free( conf.secrets_file ); } conf.secrets_file = g_secrets_file; } else if( conf.secrets_file ) { g_secrets_file = strdup( conf.secrets_file ); } // pidfile supplied in args? if( pidfile ) { if( conf.md_pidfile_path ) { free( conf.md_pidfile_path ); } conf.md_pidfile_path = pidfile; } dbprintf("%s", "initializing libsyndicate\n"); // set the config if( md_init( &conf, NULL ) != 0 ) exit(1); md_connect_timeout( conf.query_timeout ); md_signals( 0 ); // no signals dbprintf("reading users file %s\n", conf.secrets_file ); // read the users file struct md_user_entry **users = NULL; if( conf.secrets_file ) { users = md_parse_secrets_file( conf.secrets_file ); if( users == NULL ) { exit(1); } } else { errorf("No secrets file given. Pass -u or specify a value for %s in the config\n", SECRETS_FILE_KEY ); usage( argv[0], 1 ); } // need to daemonize? if( make_daemon ) { FILE* log = NULL; rc = md_daemonize( logfile, conf.md_pidfile_path, &log ); if( rc < 0 ) { errorf("md_daemonize rc = %d\n", rc ); exit(1); } if( log ) conf.md_logfile = log; } // setup the reload semaphore sem_init( &reload_sem, 0, 0 ); reload_thread = md_start_thread( reloader, NULL, true ); // start HTTP rc = http_init( &http, &conf, users ); if( rc != 0 ) { exit(1); } // start validator rc = validator_init( &conf ); if( rc != 0 ) { exit(1); } setup_signals(); while( 1 ) { sleep(1); } // we never reach this point--the signal handler cleans up return 0; }