Content
0.序
1. ngx_cycle_t结构
2. ngx_init_cycle()分析
3.注意问题
3.1如何调用CORE模块的callback函数?
3.2 open_files链表中的文件名何时初始化?
4.小结
0.序
Nginx的大部分初始化工作主要围绕一个类型为ngx_cycle_t类型的全局变量(cycle)展开。本文重点介绍全局变量ngx_cycle的初始化。
实现文件:./src/core/ngx_cycle.c。.表示nginx-1.0.4代码目录,本文为/usr/src/nginx-1.0.4。
1. ngx_cycle_t结构
该结构在./src/core/ngx_cycle.h文件中定义,如下。
- struct ngx_cycle_s {
- void ****conf_ctx;
- ngx_pool_t *pool;
-
- ngx_log_t *log;
- ngx_log_t new_log;
-
- ngx_connection_t **files;
- ngx_connection_t *free_connections;
- ngx_uint_t free_connection_n;
-
- ngx_queue_t reusable_connections_queue;
-
- ngx_array_t listening;
- ngx_array_t pathes;
- ngx_list_t open_files;
- ngx_list_t shared_memory;
-
- ngx_uint_t connection_n;
- ngx_uint_t files_n;
-
- ngx_connection_t *connections;
- ngx_event_t *read_events;
- ngx_event_t *write_events;
-
- ngx_cycle_t *old_cycle;
-
- ngx_str_t conf_file;
- ngx_str_t conf_param;
- ngx_str_t conf_prefix;
- ngx_str_t prefix;
- ngx_str_t lock_file;
- ngx_str_t hostname;
- };
该结构体的大小是确定的,sizeof(ngx_cycle_t)=224。
其中,
- open_files链表元素结构为ngx_open_file_t;
- shared_memory链表元素结构为ngx_shm_zone_t;
- listening数组元素结构为ngx_listening_t,该数组用来存放监听套接字。
各种数据结构关系图如下。
2. ngx_init_cycle()分析
初始化过程如下。
- 调用ngx_timezone_update()更新时区,调用ngx_time_update()更新时间
- 创建大小为NGX_CYCLE_POOL_SIZE=16384B的内存池,并从中分配ngx_cycle_t结构
- 简单初始化,如记录pool指针、log指针
- 初始化配置前缀、前缀、配置文件、配置参数等字符串
- 初始化pathes数组
- 初始化open_files链表
- 初始化shared_memory链表
- 初始化listening数组
- 初始化resuable_connections_queue队列
- 配置文件解析
- 调用core模块的init_conf()
- 遍历open_files链表中的每一个文件并打开
- 创建共享内存并初始化(新旧shared_memory链表的比较,相同的共享内存保留,旧的不同的共享内存被释放,新的被创建)
- (尝试5遍)遍历listening数组并打开所有侦听sockets(socket()->setsockopt()->bind()->listen())
- 提交新的cycle配置,并调用所有模块的init_module(实际上只有ngx_event_core_module模块定义了该callback,即只有ngx_event_module_init()被调用)
- 关闭或删除残留在old_cycle中的资源
- 释放多余的共享内存
- 关闭多余的侦听sockets
- 关闭多余的打开文件
具体请参考附录代码,不需要细究每一步实现,重要的是要搞清楚其初始化流程。
简要的函数调用图如下。图的自动生成,可参考<用Graphviz可视化函数调用-使用开源软件来简化复杂调用结构>。
初始化过程中全局结构ngx_cycle结构图如下。
main()调用ngx_init_cycle()后,全局变量ngx_cycle的内容如下。可对比上图查看。
- (gdb) p *ngx_cycle
- $3 = {
- conf_ctx = 0x6b1060,
- pool = 0x6b0280,
- log = 0x6b02e8,
- new_log = {
- log_level = 4,
- file = 0x6b0558,
- connection = 0,
- handler = 0,
- data = 0x0,
- action = 0x0
- },
- files = 0x0,
- free_connections = 0x0,
- free_connection_n = 0,
- reusable_connections_queue = {
- prev = 0x6b0330,
- next = 0x6b0330
- },
- listening = {
- elts = 0x6b0930,
- nelts = 1,
- size = 184,
- nalloc = 10,
- pool = 0x6b0280
- },
- pathes = {
- elts = 0x6b04d8,
- nelts = 5,
- size = 8,
- nalloc = 10,
- pool = 0x6b0280
- },
- open_files = {
- last = 0x6b0398,
- part = {
- elts = 0x6b0528,
- nelts = 2,
- next = 0x0
- ---Type <return> to continue, or q <return> to quit---
- },
- size = 48,
- nalloc = 20,
- pool = 0x6b0280
- },
- shared_memory = {
- last = 0x6b03d0,
- part = {
- elts = 0x6b08e8,
- nelts = 0,
- next = 0x0
- },
- size = 72,
- nalloc = 1,
- pool = 0x6b0280
- },
- connection_n = 1024,
- files_n = 0,
- connections = 0x0,
- read_events = 0x0,
- write_events = 0x0,
- old_cycle = 0x0,
- conf_file = {
- len = 32,
- data = 0x6b04b7 "/usr/local/nginx/conf/nginx.conf"
- },
- conf_param = {
- len = 0,
- data = 0x6b04d8 "\240{l"
- },
- conf_prefix = {
- len = 22,
- data = 0x6b0490 "/usr/local/nginx/conf//usr/local/nginx//usr/local/nginx/conf/nginx.conf"
- },
- prefix = {
- len = 17,
- data = 0x6b04a6 "/usr/local/nginx//usr/local/nginx/conf/nginx.conf"
- },
- lock_file = {
- ---Type <return> to continue, or q <return> to quit---
- len = 33,
- data = 0x6ccee0 "/usr/local/nginx/logs/nginx.lock.accept"
- },
- hostname = {
- len = 4,
- data = 0x6b11c0 "yu30"
- }
- }
3.注意问题
3.1如何调用CORE模块的callback函数?
即如可调用core模块的create_conf()和init_conf()?
(1) callback定义
file: ./src/core/ngx_conf_file.h
- typedef struct {
- ngx_str_t name;
- void *(*create_conf)(ngx_cycle_t *cycle);
- char *(*init_conf)(ngx_cycle_t *cycle, void *conf);
- } ngx_core_module_t;
(2) callback初始化
静态初始化ngx_core_module_ctx和ngx_core_module结构。在编译期间就已确定CORE模块的callback了。
file: ./src/core/nginx.c
- static ngx_core_module_t ngx_core_module_ctx = {
- ngx_string("core"),
- ngx_core_module_create_conf,
- ngx_core_module_init_conf
- };
-
-
- ngx_module_t ngx_core_module = {
- NGX_MODULE_V1,
- &ngx_core_module_ctx,
- ngx_core_commands,
- NGX_CORE_MODULE,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NGX_MODULE_V1_PADDING
- };
静态初始化ngx_core_commands结构。
file: ./src/core/nginx.c
- static ngx_command_t ngx_core_commands[] = {
-
- { ngx_string("daemon"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- 0,
- offsetof(ngx_core_conf_t, daemon),
- NULL },
-
- { ngx_string("master_process"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- 0,
- offsetof(ngx_core_conf_t, master),
- NULL },
-
- { ngx_string("timer_resolution"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- 0,
- offsetof(ngx_core_conf_t, timer_resolution),
- NULL },
-
- { ngx_string("pid"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- 0,
- offsetof(ngx_core_conf_t, pid),
- NULL },
-
- { ngx_string("lock_file"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- 0,
- offsetof(ngx_core_conf_t, lock_file),
- NULL },
-
- { ngx_string("worker_processes"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- 0,
- offsetof(ngx_core_conf_t, worker_processes),
- NULL },
-
-
-
- #if (NGX_THREADS)
-
- { ngx_string("worker_threads"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- 0,
- offsetof(ngx_core_conf_t, worker_threads),
- NULL },
-
- { ngx_string("thread_stack_size"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- 0,
- offsetof(ngx_core_conf_t, thread_stack_size),
- NULL },
-
- #endif
-
- ngx_null_command
- };
3.2 open_files链表中的文件名何时初始化?
在初始化open_files链表之后遍历该链表并打开文件之前,并未看到向open_files链表中写入文件名。那么,何时写入open_files链表的?
——在ngx_conf_open_file函数中写入。
具体请参考源代码。打开文件后,open_files链表就保存了ngx_open_file_t结构的数据,具体请参考该结构定义。
4.小结
本文主要分析ngx_cycle的初始化,后文继续分析其中调用的CORE模块的callback和配置文件解析等。
Appendix: ngx_init_cycle()代码
省略,可自行研究。
上文来自:http://blog.csdn.net/livelylittlefish/article/details/7247080