Chinaunix首页 | 论坛 | 博客
  • 博客访问: 92339
  • 博文数量: 31
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 380
  • 用 户 组: 普通用户
  • 注册时间: 2014-02-24 22:04
文章分类

全部博文(31)

文章存档

2014年(31)

我的朋友

分类: C/C++

2014-07-21 13:20:42


Fdfs_trackerd.c文件中tracker的运行函数架构
main
|-----log_init,getExeAbsoluteFilename
|-----tracker_load_from_conf_file
|-----tracker_load_status_from_file
|-----base64_init_ex
|-----tracker_mem_init
|-----socketServer
|-----tcpsetserveropt
|-----daemon_init
|-----tracker_service_init
|-----sigUsrHandler,sigHupHandler,sigQuitHandler,sigDumpHandler
|-----tracker_httpd_start
|-----tracker_http_check_start
|-----set_run_by
|-----sched_start
|-----tracker_accept_loop
|-----tracker_terminate_threads,tracker_http_check_stop
|-----tracker_mem_destroy,tracker_service_destroy,log_destroy


通过tracker目录下的Fdfs_trackerd.c文件,可以分析出tracker的执行流程

点击(此处)折叠或打开

  1. int main(int argc, char *argv[])
  2. {
  3.     char *conf_filename;   //配置文件名称
  4.     int result;
  5.     int sock;   //sock id
  6.     pthread_t schedule_tid;
  7.     struct sigaction act;  //信号
  8.     ScheduleEntry scheduleEntries[SCHEDULE_ENTRIES_COUNT];
  9.     ScheduleArray scheduleArray;

  10.     if (argc < 2)
  11.     {
  12.         printf("Usage: %s \n", argv[0]);
  13.         return 1;
  14.     }

  15.     g_up_time = time(NULL);
  16.     log_init();

  17. #if defined(DEBUG_FLAG) && defined(OS_LINUX)
  18.     if (getExeAbsoluteFilename(argv[0], g_exe_name, \    //获取配置文件的绝对路径名
  19.         sizeof(g_exe_name)) == NULL)
  20.     {
  21.         log_destroy();
  22.         return errno != 0 ? errno : ENOENT;
  23.     }
  24. #endif

  25.     conf_filename = argv[1];    //tracker的配置文件
  26.     memset(bind_addr, 0, sizeof(bind_addr));
  27.     if ((result=tracker_load_from_conf_file(conf_filename, \   //解析配置文件,初始化全局参数
  28.             bind_addr, sizeof(bind_addr))) != 0)
  29.     {
  30.         log_destroy();
  31.         return result;
  32.     }

  33.     if ((result=tracker_load_status_from_file(&g_tracker_last_status)) != 0)    //从状态文件中读取状态信息
  34.     {
  35.         log_destroy();
  36.         return result;
  37.     }

  38.     base64_init_ex(&g_base64_context, 0, '-', '_', '.');    //
  39.     if ((result=set_rand_seed()) != 0)
  40.     {
  41.         logCrit("file: "__FILE__", line: %d, " \
  42.             "set_rand_seed fail, program exit!", __LINE__);
  43.         return result;
  44.     }

  45.     if ((result=tracker_mem_init()) != 0)    //所有的空间分配操作,数据读取操作,锁的初始化操作
  46.     {
  47.         log_destroy();
  48.         return result;
  49.     }
  50.     
  51.     sock = socketServer(bind_addr, g_server_port, &result);    //创建socket,绑定,监听
  52.     if (sock < 0)
  53.     {
  54.         log_destroy();
  55.         return result;
  56.     }
  57.     
  58.     if ((result=tcpsetserveropt(sock, g_fdfs_network_timeout)) != 0)  //设定socket的选项
  59.     {
  60.         log_destroy();
  61.         return result;
  62.     }

  63.     daemon_init(true);    //使该进程成功一个守护进程
  64.     umask(0);    //重设文件掩码
  65.     
  66.     if (dup2(g_log_context.log_fd, STDOUT_FILENO) < 0 || \
  67.         dup2(g_log_context.log_fd, STDERR_FILENO) < 0)
  68.     {
  69.         logCrit("file: "__FILE__", line: %d, " \
  70.             "call dup2 fail, errno: %d, error info: %s, " \
  71.             "program exit!", __LINE__, errno, STRERROR(errno));
  72.         g_continue_flag = false;
  73.         return errno;
  74.     }

  75.     if ((result=tracker_service_init()) != 0)   //初始化tracker service
  76.     {
  77.         log_destroy();
  78.         return result;
  79.     }
  80.     
  81.     memset(&act, 0, sizeof(act));   //初始化信号内存
  82.     sigemptyset(&act.sa_mask);

  83.     act.sa_handler = sigUsrHandler;   //设信号SIGUSR1与SIGUSR2的处理程序
  84.     if(sigaction(SIGUSR1, &act, NULL) < 0 || \
  85.         sigaction(SIGUSR2, &act, NULL) < 0)
  86.     {
  87.         logCrit("file: "__FILE__", line: %d, " \
  88.             "call sigaction fail, errno: %d, error info: %s", \
  89.             __LINE__, errno, STRERROR(errno));
  90.         return errno;
  91.     }

  92.     act.sa_handler = sigHupHandler;  //设信号SIGHUP的处理程序
  93.     if(sigaction(SIGHUP, &act, NULL) < 0)
  94.     {
  95.         logCrit("file: "__FILE__", line: %d, " \
  96.             "call sigaction fail, errno: %d, error info: %s", \
  97.             __LINE__, errno, STRERROR(errno));
  98.         return errno;
  99.     }
  100.     
  101.     act.sa_handler = SIG_IGN;     //设信号SIGPIPE的处理程序
  102.     if(sigaction(SIGPIPE, &act, NULL) < 0)
  103.     {
  104.         logCrit("file: "__FILE__", line: %d, " \
  105.             "call sigaction fail, errno: %d, error info: %s", \
  106.             __LINE__, errno, STRERROR(errno));
  107.         return errno;
  108.     }

  109.     act.sa_handler = sigQuitHandler;    //设信号SIGINT的处理程序
  110.     if(sigaction(SIGINT, &act, NULL) < 0 || \
  111.         sigaction(SIGTERM, &act, NULL) < 0 || \
  112.         sigaction(SIGQUIT, &act, NULL) < 0)
  113.     {
  114.         logCrit("file: "__FILE__", line: %d, " \
  115.             "call sigaction fail, errno: %d, error info: %s", \
  116.             __LINE__, errno, STRERROR(errno));
  117.         return errno;
  118.     }

  119. #if defined(DEBUG_FLAG)
  120. /*
  121. #if defined(OS_LINUX)
  122.     memset(&act, 0, sizeof(act));
  123.     sigemptyset(&act.sa_mask);
  124.         act.sa_sigaction = sigSegvHandler;
  125.         act.sa_flags = SA_SIGINFO;
  126.         if (sigaction(SIGSEGV, &act, NULL) < 0 || \   //设信号SIGSEGV与SIGABRT的处理程序
  127.             sigaction(SIGABRT, &act, NULL) < 0)
  128.     {
  129.         logCrit("file: "__FILE__", line: %d, " \
  130.             "call sigaction fail, errno: %d, error info: %s", \
  131.             __LINE__, errno, STRERROR(errno));
  132.         return errno;
  133.     }
  134. #endif
  135. */

  136.     memset(&act, 0, sizeof(act));
  137.     sigemptyset(&act.sa_mask);
  138.     act.sa_handler = sigDumpHandler;
  139.     if(sigaction(SIGUSR1, &act, NULL) < 0 || \
  140.         sigaction(SIGUSR2, &act, NULL) < 0)
  141.     {
  142.         logCrit("file: "__FILE__", line: %d, " \
  143.             "call sigaction fail, errno: %d, error info: %s", \
  144.             __LINE__, errno, STRERROR(errno));
  145.         return errno;
  146.     }
  147. #endif

  148. #ifdef WITH_HTTPD   //http设置
  149.     if (!g_http_params.disabled)  
  150.     {
  151.         if ((result=tracker_httpd_start(bind_addr)) != 0)
  152.         {
  153.             logCrit("file: "__FILE__", line: %d, " \
  154.                 "tracker_httpd_start fail, program exit!", \
  155.                 __LINE__);
  156.             return result;
  157.         }

  158.     }

  159.     if ((result=tracker_http_check_start()) != 0)
  160.     {
  161.         logCrit("file: "__FILE__", line: %d, " \
  162.             "tracker_http_check_start fail, " \
  163.             "program exit!", __LINE__);
  164.         return result;
  165.     }
  166. #endif

  167.     if ((result=set_run_by(g_run_by_group, g_run_by_user)) != 0)   //设置用户启动组与启动用户
  168.     {
  169.         log_destroy();
  170.         return result;
  171.     }

  172.     scheduleArray.entries = scheduleEntries;   //初始化调度数组
  173.     scheduleArray.count = SCHEDULE_ENTRIES_COUNT;

  174.     memset(scheduleEntries, 0, sizeof(scheduleEntries));
  175.     scheduleEntries[0].id = 1;
  176.     scheduleEntries[0].time_base.hour = TIME_NONE;
  177.     scheduleEntries[0].time_base.minute = TIME_NONE;
  178.     scheduleEntries[0].interval = g_sync_log_buff_interval;
  179.     scheduleEntries[0].task_func = log_sync_func;  //处理函数
  180.     scheduleEntries[0].func_args = &g_log_context;  //参数

  181.     scheduleEntries[1].id = 2;
  182.     scheduleEntries[1].time_base.hour = TIME_NONE;
  183.     scheduleEntries[1].time_base.minute = TIME_NONE;
  184.     scheduleEntries[1].interval = g_check_active_interval;
  185.     scheduleEntries[1].task_func = tracker_mem_check_alive;
  186.     scheduleEntries[1].func_args = NULL;

  187.     scheduleEntries[2].id = 3;
  188.     scheduleEntries[2].time_base.hour = 0;
  189.     scheduleEntries[2].time_base.minute = 0;
  190.     scheduleEntries[2].interval = TRACKER_SYNC_STATUS_FILE_INTERVAL;
  191.     scheduleEntries[2].task_func = tracker_write_status_to_file;
  192.     scheduleEntries[2].func_args = NULL;
  193.     if ((result=sched_start(&scheduleArray, &schedule_tid, \  //调度开始
  194.         g_thread_stack_size, &g_continue_flag)) != 0) 
  195.     {
  196.         log_destroy();
  197.         return result;
  198.     }

  199.     log_set_cache(true);

  200.     bTerminateFlag = false;
  201.     bAcceptEndFlag = false;

  202.     tracker_accept_loop(sock);   //开始接受连接请求
  203.     bAcceptEndFlag = true;
  204.     if (g_schedule_flag)
  205.     {
  206.         pthread_kill(schedule_tid, SIGINT);//发SIGINT信号
  207.     }
  208.     tracker_terminate_threads();

  209. #ifdef WITH_HTTPD
  210.     if (g_http_check_flag)
  211.     {
  212.         tracker_http_check_stop();
  213.     }

  214.     while (g_http_check_flag)
  215.     {
  216.         usleep(50000);
  217.     }
  218. #endif

  219.     while ((g_tracker_thread_count != 0) || g_schedule_flag)
  220.     {

  221. /*
  222. #if defined(DEBUG_FLAG) && defined(OS_LINUX)
  223.         if (bSegmentFault)
  224.         {
  225.             sleep(5);
  226.             break;
  227.         }
  228. #endif
  229. */

  230.         usleep(50000);
  231.     }
  232.     
  233.     tracker_mem_destroy();  //清理内存
  234.     tracker_service_destroy();    //清理服务
  235.     
  236.     logInfo("exit nomally.\n");
  237.     log_destroy();  //清理日志
  238.     
  239.     return 0;
  240. }


函数执行步骤如下:
(1) 日志系统初始化,调用函数log_init,并获取配置文件的绝对文件名称,调用函数getExeAbsoluteFilename
(2) 从配置文件中读取配置数据,并初始化全局变量,调用函数tracker_load_from_conf_file
(3) 从状态配置文件中读取状态数据,并初始化全局变量,调用函数tracker_load_status_from_file
(4) 调用base64_init_ex函数,初始化g_base64_context变量
(5) 初始化所需要的内存与锁,调用函数tracker_mem_init
(6) 创建socket,调用函数socketServer
(7) 设置socket,调用函数tcpsetserveropt
(8) 使进程变成守护进程,调用函数daemon_init
(9) 初始化tracker service,调用函数tracker_service_init
(10)设定信号处理函数
(11)启动http服务,调用函数tracker_httpd_start
(12)tracker_http_check_start
(13)设置运行用户与用户组,调用函数set_run_by
(14)调度进程启动,调用函数sched_start
(15)主循环启动,调用函数tracker_accept_loop
(16)清理

阅读(1251) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~