int main(int argc, char *argv[]) { char *conf_filename; int result; int wait_count; int sock; pthread_t schedule_tid; struct sigaction act; ScheduleEntry scheduleEntries[SCHEDULE_ENTRIES_COUNT]; ScheduleArray scheduleArray; char pidFilename[MAX_PATH_SIZE]; bool stop; if (argc < 2) { usage(argv[0]); return 1; } g_current_time = time(NULL); g_up_time = g_current_time; srand(g_up_time); log_init2(); //通过指定的conf文件,获取base path conf_filename = argv[1]; if ((result=get_base_path_from_conf_file(conf_filename, g_fdfs_base_path, sizeof(g_fdfs_base_path))) != 0) { log_destroy(); return result; } //启动程序,或者通过文件中的pid来kill掉之前的进程 snprintf(pidFilename, sizeof(pidFilename), "%s/data/fdfs_trackerd.pid", g_fdfs_base_path); if ((result=process_action(pidFilename, argv[2], &stop)) != 0) { if (result == EINVAL) { usage(argv[0]); } log_destroy(); return result; } if (stop) { log_destroy(); return 0; } #if defined(DEBUG_FLAG) && defined(OS_LINUX) if (getExeAbsoluteFilename(argv[0], g_exe_name, \ sizeof(g_exe_name)) == NULL) { logCrit("exit abnormally!\n"); log_destroy(); return errno != 0 ? errno : ENOENT; } #endif memset(bind_addr, 0, sizeof(bind_addr)); if ((result=tracker_load_from_conf_file(conf_filename, \ bind_addr, sizeof(bind_addr))) != 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } //g_tracker_last_status只记录了uptime和last check time作用未知 if ((result=tracker_load_status_from_file(&g_tracker_last_status)) != 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } base64_init_ex(&g_base64_context, 0, '-', '_', '.'); if ((result=set_rand_seed()) != 0) { logCrit("file: "__FILE__", line: %d, " \ "set_rand_seed fail, program exit!", __LINE__); return result; } //内存分配及历史group和storage载入 if ((result=tracker_mem_init()) != 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } sock = socketServer(bind_addr, g_server_port, &result); if (sock < 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } if ((result=tcpsetserveropt(sock, g_fdfs_network_timeout)) != 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } //后台运行 daemon_init(false); umask(0); //将pid记录到文件中 if ((result=write_to_pid_file(pidFilename)) != 0) { log_destroy(); return result; } //启动工作线程,这一块需要重点看 if ((result=tracker_service_init()) != 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } //注册信号处理函数 memset(&act, 0, sizeof(act)); sigemptyset(&act.sa_mask); act.sa_handler = sigUsrHandler; if(sigaction(SIGUSR1, &act, NULL) < 0 || \ sigaction(SIGUSR2, &act, NULL) < 0) { logCrit("file: "__FILE__", line: %d, " \ "call sigaction fail, errno: %d, error info: %s", \ __LINE__, errno, STRERROR(errno)); logCrit("exit abnormally!\n"); return errno; } act.sa_handler = sigHupHandler; if(sigaction(SIGHUP, &act, NULL) < 0) { logCrit("file: "__FILE__", line: %d, " \ "call sigaction fail, errno: %d, error info: %s", \ __LINE__, errno, STRERROR(errno)); logCrit("exit abnormally!\n"); return errno; } act.sa_handler = SIG_IGN; if(sigaction(SIGPIPE, &act, NULL) < 0) { logCrit("file: "__FILE__", line: %d, " \ "call sigaction fail, errno: %d, error info: %s", \ __LINE__, errno, STRERROR(errno)); logCrit("exit abnormally!\n"); return errno; } act.sa_handler = sigQuitHandler; if(sigaction(SIGINT, &act, NULL) < 0 || \ sigaction(SIGTERM, &act, NULL) < 0 || \ sigaction(SIGQUIT, &act, NULL) < 0) { logCrit("file: "__FILE__", line: %d, " \ "call sigaction fail, errno: %d, error info: %s", \ __LINE__, errno, STRERROR(errno)); logCrit("exit abnormally!\n"); return errno; } #if defined(DEBUG_FLAG) /* #if defined(OS_LINUX) memset(&act, 0, sizeof(act)); sigemptyset(&act.sa_mask); act.sa_sigaction = sigSegvHandler; act.sa_flags = SA_SIGINFO; if (sigaction(SIGSEGV, &act, NULL) < 0 || \ sigaction(SIGABRT, &act, NULL) < 0) { logCrit("file: "__FILE__", line: %d, " \ "call sigaction fail, errno: %d, error info: %s", \ __LINE__, errno, STRERROR(errno)); logCrit("exit abnormally!\n"); return errno; } #endif */ memset(&act, 0, sizeof(act)); sigemptyset(&act.sa_mask); act.sa_handler = sigDumpHandler; if(sigaction(SIGUSR1, &act, NULL) < 0 || \ sigaction(SIGUSR2, &act, NULL) < 0) { logCrit("file: "__FILE__", line: %d, " \ "call sigaction fail, errno: %d, error info: %s", \ __LINE__, errno, STRERROR(errno)); logCrit("exit abnormally!\n"); return errno; } #endif #ifdef WITH_HTTPD if (!g_http_params.disabled) { if ((result=tracker_httpd_start(bind_addr)) != 0) { logCrit("file: "__FILE__", line: %d, " \ "tracker_httpd_start fail, program exit!", \ __LINE__); return result; } } if ((result=tracker_http_check_start()) != 0) { logCrit("file: "__FILE__", line: %d, " \ "tracker_http_check_start fail, " \ "program exit!", __LINE__); return result; } #endif if ((result=set_run_by(g_run_by_group, g_run_by_user)) != 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } //schedule 调度线程,主要作用待细看 scheduleArray.entries = scheduleEntries; scheduleArray.count = 0; memset(scheduleEntries, 0, sizeof(scheduleEntries)); //日志处理,日志是先存在cache中的,需要定时存储 INIT_SCHEDULE_ENTRY(scheduleEntries[scheduleArray.count], scheduleArray.count + 1, TIME_NONE, TIME_NONE, TIME_NONE, g_sync_log_buff_interval, log_sync_func, &g_log_context); scheduleArray.count++; //用户检测trunk server服务器是否可用(trunk server是选定的一个storage) INIT_SCHEDULE_ENTRY(scheduleEntries[scheduleArray.count], scheduleArray.count + 1, TIME_NONE, TIME_NONE, TIME_NONE, g_check_active_interval, tracker_mem_check_alive, NULL); scheduleArray.count++; //每5分钟刷新一下status INIT_SCHEDULE_ENTRY(scheduleEntries[scheduleArray.count], scheduleArray.count + 1, 0, 0, 0, TRACKER_SYNC_STATUS_FILE_INTERVAL, tracker_write_status_to_file, NULL); scheduleArray.count++; if (g_rotate_error_log) { INIT_SCHEDULE_ENTRY_EX(scheduleEntries[scheduleArray.count], scheduleArray.count + 1, g_error_log_rotate_time, 24 * 3600, log_notify_rotate, &g_log_context); scheduleArray.count++; if (g_log_file_keep_days > 0) { log_set_keep_days(&g_log_context, g_log_file_keep_days); INIT_SCHEDULE_ENTRY(scheduleEntries[scheduleArray.count], scheduleArray.count + 1, 1, 0, 0, 24 * 3600, log_delete_old_files, &g_log_context); scheduleArray.count++; } } if ((result=sched_start(&scheduleArray, &schedule_tid, \ g_thread_stack_size, (bool * volatile)&g_continue_flag)) != 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } //选主机制,tracker默认不会把自己加入队列 if ((result=tracker_relationship_init()) != 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } log_set_cache(true); bTerminateFlag = false; bAcceptEndFlag = false; //accept线程,工作线程和消息接收线程是分开的 tracker_accept_loop(sock); bAcceptEndFlag = true; if (g_schedule_flag) { pthread_kill(schedule_tid, SIGINT); } tracker_terminate_threads(); #ifdef WITH_HTTPD if (g_http_check_flag) { tracker_http_check_stop(); } while (g_http_check_flag) { usleep(50000); } #endif wait_count = 0; //线程数和调度flag还在,则继续运行程序 while ((g_tracker_thread_count != 0) || g_schedule_flag) { /* #if defined(DEBUG_FLAG) && defined(OS_LINUX) if (bSegmentFault) { sleep(5); break; } #endif */ usleep(10000); if (++wait_count > 3000) { logWarning("waiting timeout, exit!"); break; } } tracker_mem_destroy(); tracker_service_destroy(); tracker_relationship_destroy(); logInfo("exit normally.\n"); log_destroy(); delete_pid_file(pidFilename); return 0; }
int main(int argc, char *argv[]) { char *conf_filename; int result; int sock; pthread_t schedule_tid; struct sigaction act; ScheduleEntry scheduleEntries[SCHEDULE_ENTRIES_COUNT]; ScheduleArray scheduleArray; if (argc < 2) { printf("Usage: %s <config_file>\n", argv[0]); return 1; } g_current_time = time(NULL); g_up_time = g_current_time; srand(g_up_time); log_init(); #if defined(DEBUG_FLAG) && defined(OS_LINUX) if (getExeAbsoluteFilename(argv[0], g_exe_name, \ sizeof(g_exe_name)) == NULL) { logCrit("exit abnormally!\n"); log_destroy(); return errno != 0 ? errno : ENOENT; } #endif conf_filename = argv[1]; memset(bind_addr, 0, sizeof(bind_addr)); if ((result=tracker_load_from_conf_file(conf_filename, \ bind_addr, sizeof(bind_addr))) != 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } if ((result=tracker_load_status_from_file(&g_tracker_last_status)) != 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } base64_init_ex(&g_base64_context, 0, '-', '_', '.'); if ((result=set_rand_seed()) != 0) { logCrit("file: "__FILE__", line: %d, " \ "set_rand_seed fail, program exit!", __LINE__); return result; } if ((result=tracker_mem_init()) != 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } sock = socketServer(bind_addr, g_server_port, &result); if (sock < 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } if ((result=tcpsetserveropt(sock, g_fdfs_network_timeout)) != 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } daemon_init(true); umask(0); if (dup2(g_log_context.log_fd, STDOUT_FILENO) < 0 || \ dup2(g_log_context.log_fd, STDERR_FILENO) < 0) { logCrit("file: "__FILE__", line: %d, " \ "call dup2 fail, errno: %d, error info: %s, " \ "program exit!", __LINE__, errno, STRERROR(errno)); g_continue_flag = false; return errno; } if ((result=tracker_service_init()) != 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } memset(&act, 0, sizeof(act)); sigemptyset(&act.sa_mask); act.sa_handler = sigUsrHandler; if(sigaction(SIGUSR1, &act, NULL) < 0 || \ sigaction(SIGUSR2, &act, NULL) < 0) { logCrit("file: "__FILE__", line: %d, " \ "call sigaction fail, errno: %d, error info: %s", \ __LINE__, errno, STRERROR(errno)); logCrit("exit abnormally!\n"); return errno; } act.sa_handler = sigHupHandler; if(sigaction(SIGHUP, &act, NULL) < 0) { logCrit("file: "__FILE__", line: %d, " \ "call sigaction fail, errno: %d, error info: %s", \ __LINE__, errno, STRERROR(errno)); logCrit("exit abnormally!\n"); return errno; } act.sa_handler = SIG_IGN; if(sigaction(SIGPIPE, &act, NULL) < 0) { logCrit("file: "__FILE__", line: %d, " \ "call sigaction fail, errno: %d, error info: %s", \ __LINE__, errno, STRERROR(errno)); logCrit("exit abnormally!\n"); return errno; } act.sa_handler = sigQuitHandler; if(sigaction(SIGINT, &act, NULL) < 0 || \ sigaction(SIGTERM, &act, NULL) < 0 || \ sigaction(SIGQUIT, &act, NULL) < 0) { logCrit("file: "__FILE__", line: %d, " \ "call sigaction fail, errno: %d, error info: %s", \ __LINE__, errno, STRERROR(errno)); logCrit("exit abnormally!\n"); return errno; } #if defined(DEBUG_FLAG) /* #if defined(OS_LINUX) memset(&act, 0, sizeof(act)); sigemptyset(&act.sa_mask); act.sa_sigaction = sigSegvHandler; act.sa_flags = SA_SIGINFO; if (sigaction(SIGSEGV, &act, NULL) < 0 || \ sigaction(SIGABRT, &act, NULL) < 0) { logCrit("file: "__FILE__", line: %d, " \ "call sigaction fail, errno: %d, error info: %s", \ __LINE__, errno, STRERROR(errno)); logCrit("exit abnormally!\n"); return errno; } #endif */ memset(&act, 0, sizeof(act)); sigemptyset(&act.sa_mask); act.sa_handler = sigDumpHandler; if(sigaction(SIGUSR1, &act, NULL) < 0 || \ sigaction(SIGUSR2, &act, NULL) < 0) { logCrit("file: "__FILE__", line: %d, " \ "call sigaction fail, errno: %d, error info: %s", \ __LINE__, errno, STRERROR(errno)); logCrit("exit abnormally!\n"); return errno; } #endif #ifdef WITH_HTTPD if (!g_http_params.disabled) { if ((result=tracker_httpd_start(bind_addr)) != 0) { logCrit("file: "__FILE__", line: %d, " \ "tracker_httpd_start fail, program exit!", \ __LINE__); return result; } } if ((result=tracker_http_check_start()) != 0) { logCrit("file: "__FILE__", line: %d, " \ "tracker_http_check_start fail, " \ "program exit!", __LINE__); return result; } #endif if ((result=set_run_by(g_run_by_group, g_run_by_user)) != 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } scheduleArray.entries = scheduleEntries; memset(scheduleEntries, 0, sizeof(scheduleEntries)); scheduleEntries[0].id = 1; scheduleEntries[0].time_base.hour = TIME_NONE; scheduleEntries[0].time_base.minute = TIME_NONE; scheduleEntries[0].interval = g_sync_log_buff_interval; scheduleEntries[0].task_func = log_sync_func; scheduleEntries[0].func_args = &g_log_context; scheduleEntries[1].id = 2; scheduleEntries[1].time_base.hour = TIME_NONE; scheduleEntries[1].time_base.minute = TIME_NONE; scheduleEntries[1].interval = g_check_active_interval; scheduleEntries[1].task_func = tracker_mem_check_alive; scheduleEntries[1].func_args = NULL; scheduleEntries[2].id = 3; scheduleEntries[2].time_base.hour = 0; scheduleEntries[2].time_base.minute = 0; scheduleEntries[2].interval = TRACKER_SYNC_STATUS_FILE_INTERVAL; scheduleEntries[2].task_func = tracker_write_status_to_file; scheduleEntries[2].func_args = NULL; scheduleArray.count = 3; if (g_rotate_error_log) { scheduleEntries[scheduleArray.count].id = 4; scheduleEntries[scheduleArray.count].time_base = \ g_error_log_rotate_time; scheduleEntries[scheduleArray.count].interval = \ 24 * 3600; scheduleEntries[scheduleArray.count].task_func = \ log_notify_rotate; scheduleEntries[scheduleArray.count].func_args = \ &g_log_context; scheduleArray.count++; } if ((result=sched_start(&scheduleArray, &schedule_tid, \ g_thread_stack_size, (bool * volatile)&g_continue_flag)) != 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } if ((result=tracker_relationship_init()) != 0) { logCrit("exit abnormally!\n"); log_destroy(); return result; } log_set_cache(true); bTerminateFlag = false; bAcceptEndFlag = false; tracker_accept_loop(sock); bAcceptEndFlag = true; if (g_schedule_flag) { pthread_kill(schedule_tid, SIGINT); } tracker_terminate_threads(); #ifdef WITH_HTTPD if (g_http_check_flag) { tracker_http_check_stop(); } while (g_http_check_flag) { usleep(50000); } #endif while ((g_tracker_thread_count != 0) || g_schedule_flag) { /* #if defined(DEBUG_FLAG) && defined(OS_LINUX) if (bSegmentFault) { sleep(5); break; } #endif */ usleep(50000); } tracker_mem_destroy(); tracker_service_destroy(); tracker_relationship_destroy(); logInfo("exit normally.\n"); log_destroy(); return 0; }