nginx 系统配置相关初始化

2014-12-27 20:01:12   最后更新: 2014-12-27 20:01:12   访问数量:692




// 保存调用参数到全局变量,init_cycle 只用于提供 log 参数 if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) { return 1; } // 保存配置文件路径、程序运行路径、调用参数到 init_cycle if (ngx_process_options(&init_cycle) != NGX_OK) { return 1; } // 对齐校验表 if (ngx_crc32_table_init() != NGX_OK) { return 1; }

 

// static ngx_int_t ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv) // 将调用参数保存到全局变量 ngx_os_argv、ngx_argc、ngx_argv、ngx_os_environ 中 {{{ static ngx_int_t ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv) { #if (NGX_FREEBSD) ngx_os_argv = (char **) argv; ngx_argc = argc; ngx_argv = (char **) argv; #else size_t len; ngx_int_t i; ngx_os_argv = (char **) argv; ngx_argc = argc; ngx_argv = ngx_alloc((argc + 1) * sizeof(char *), cycle->log); if (ngx_argv == NULL) { return NGX_ERROR; } for (i = 0; i < argc; i++) { len = ngx_strlen(argv[i]) + 1; ngx_argv[i] = ngx_alloc(len, cycle->log); if (ngx_argv[i] == NULL) { return NGX_ERROR; } (void) ngx_cpystrn((u_char *) ngx_argv[i], (u_char *) argv[i], len); } ngx_argv[i] = NULL; #endif ngx_os_environ = environ; return NGX_OK; } // }}}

 

众所周知,在C语言中,argc 保存了我们调用程序时所使用的参数个数,而 argv 是一个字符数组的数组,有 argc 个字符数组作为元素,每个字符数组都是一个调用参数字符串

在该函数中,将 argc 和 argv 中的调用参数保存到了全局变量 ngx_os_argv、ngx_argc、ngx_argv、ngx_os_environ 中

这里 ngx_argv 的空间是直接 malloc 出来的

ngx_alloc 是对 malloc 函数进行的封装,实现了错误日志的输出

然后,将系统环境变量数组赋值给全局变量 ngx_os_environ,这样以后就可以使用 ngx_os_environ 去定位系统环境变量了

// static ngx_int_t ngx_process_options(ngx_cycle_t *cycle) // 保存配置文件路径、参数、程序运行路径信息到 cycle {{{ static ngx_int_t ngx_process_options(ngx_cycle_t *cycle) { u_char *p; size_t len; if (ngx_prefix) { len = ngx_strlen(ngx_prefix); p = ngx_prefix; if (len && !ngx_path_separator(p[len - 1])) { p = ngx_pnalloc(cycle->pool, len + 1); if (p == NULL) { return NGX_ERROR; } ngx_memcpy(p, ngx_prefix, len); p[len++] = '/'; } // 初始化配置文件路径和程序目录路径 cycle->conf_prefix.len = len; cycle->conf_prefix.data = p; cycle->prefix.len = len; cycle->prefix.data = p; } else { #ifndef NGX_PREFIX p = ngx_pnalloc(cycle->pool, NGX_MAX_PATH); if (p == NULL) { return NGX_ERROR; } // 用当前程序运行目录作为 nginx 默认目录 if (ngx_getcwd(p, NGX_MAX_PATH) == 0) { ngx_log_stderr(ngx_errno, "[emerg]: " ngx_getcwd_n " failed"); return NGX_ERROR; } len = ngx_strlen(p); p[len++] = '/'; // 初始化配置文件路径和程序目录路径 cycle->conf_prefix.len = len; cycle->conf_prefix.data = p; cycle->prefix.len = len; cycle->prefix.data = p; #else #ifdef NGX_CONF_PREFIX ngx_str_set(&cycle->conf_prefix, NGX_CONF_PREFIX); #else ngx_str_set(&cycle->conf_prefix, NGX_PREFIX); #endif ngx_str_set(&cycle->prefix, NGX_PREFIX); #endif } if (ngx_conf_file) { cycle->conf_file.len = ngx_strlen(ngx_conf_file); cycle->conf_file.data = ngx_conf_file; } else { ngx_str_set(&cycle->conf_file, NGX_CONF_PATH); } if (ngx_conf_full_name(cycle, &cycle->conf_file, 0) != NGX_OK) { return NGX_ERROR; } // 获取目录后面跟的参数 for (p = cycle->conf_file.data + cycle->conf_file.len - 1; p > cycle->conf_file.data; p--) { if (ngx_path_separator(*p)) { cycle->conf_prefix.len = p - ngx_cycle->conf_file.data + 1; cycle->conf_prefix.data = ngx_cycle->conf_file.data; break; } } if (ngx_conf_params) { cycle->conf_param.len = ngx_strlen(ngx_conf_params); cycle->conf_param.data = ngx_conf_params; } // 测试时降低默认 log 级别 if (ngx_test_config) { cycle->log->log_level = NGX_LOG_INFO; } return NGX_OK; } // }}}

 

如果已经保存配置文件路径的全局变量 ngx_prefix,那么,这个初始化过程会直接用他去初始化 init_cycle 变量

在第一次调用中,该变量尚未被赋值,因此,直接调用了函数:

ngx_str_set(&cycle->conf_prefix, NGX_CONF_PREFIX);

 

ngx_str_set 是一个红函数,定义如下:

#define ngx_str_set(str, text) \ (str)->len = sizeof(text) - 1; (str)->data = (u_char *) text

 

将 const char * 的字符串直接转化为 nginx_str 结构对象

 

执行后,cycle->conf_prefix 保存了配置文件目录地址

(gdb) p cycle->conf_prefix $8 = { len = 11, data = 0x80ba0f9 "/etc/nginx/" }

 

 

cycle->prefix 保存了 nginx 的运行目录

(gdb) p cycle->prefix $9 = { len = 34, data = 0x80ba8e4 "/home/zeyu/Workspace/nginx-1.7.7//" }

 

 

同样,由于我们第一次调用,没有初始化过全局变量 ngx_conf_file,进而执行了

ngx_str_set(&cycle->conf_file, NGX_CONF_PATH);

 

将配置文件地址写入了 cycle->conf_file

(gdb) p cycle->conf_file $13 = { len = 21, data = 0x80ba105 "/etc/nginx/nginx.conf" }

 

 

之后要进行的,是检测路径是否是绝对路径,如果不是,那么按照相对路径进行处理,补全为绝对路径

网络编程中非常常用的一种校验方式就是 crc32,循环冗余码校验

crc32 的校验依赖于一个校验表,他保存在 ngx_crc32.c 中定义的两个全局变量中,这个函数所做的就是将这两个表中的数据进行16位对齐,以增加CPU的读取速度

// ngx_int_t ngx_crc32_table_init(void) // 循环冗余校验表(CRC32)初始化(对齐) {{{ ngx_int_t ngx_crc32_table_init(void) { void *p; // 已对齐 if (((uintptr_t) ngx_crc32_table_short & ~((uintptr_t) ngx_cacheline_size - 1)) == (uintptr_t) ngx_crc32_table_short) { return NGX_OK; } p = ngx_alloc(16 * sizeof(uint32_t) + ngx_cacheline_size, ngx_cycle->log); if (p == NULL) { return NGX_ERROR; } p = ngx_align_ptr(p, ngx_cacheline_size); ngx_memcpy(p, ngx_crc32_table16, 16 * sizeof(uint32_t)); ngx_crc32_table_short = p; return NGX_OK; } // }}}

 

 






技术帖      linux      unix      network      c语言      龙潭书斋      nginx      源码      opensource     


京ICP备15018585号