我是靠谱客的博主 体贴乌龟,最近开发中收集的这篇文章主要介绍nginx源码分析—core模块callback,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

作者:阿波
链接:http://blog.csdn.net/livelylittlefish/article/details/7262750

Content
0. 序
1. Core模块的配置结构
2. create_conf分析
3. init_conf分析
4. 小结

0. 序

<nginx源码分析—全局变量ngx_cycle的初始化>中,简单介绍了如何调用core模块的callback,并简单列出其定义及其初始化,本文将重点阐述callback做什么。

1. Core模块的配置结构

如前文所述,core模块的callback有两个create_conf()init_conf(),从名字就可以看出,一个创建配置结构,另一个初始化该配置结构。core模块的配置结构如下,存放配置文件中的核心指令,如deamonmaster等。

./src/core/ngx_cycle.h

typedef struct {
ngx_flag_t
daemon;
ngx_flag_t
master;
ngx_msec_t
timer_resolution;
ngx_int_t
worker_processes;
ngx_int_t
debug_points;
ngx_int_t
rlimit_nofile;
ngx_int_t
rlimit_sigpending;
off_t
rlimit_core;
int
priority;
ngx_uint_t
cpu_affinity_n;
u_long
*cpu_affinity;
char
*username;
/* 用户名 */
ngx_uid_t
user;
/* user ID */
ngx_gid_t
group;
/* group ID*/
ngx_str_t
working_directory;
/*
*/
ngx_str_t
lock_file;
/* 用户名 */
ngx_str_t
pid;
ngx_str_t
oldpid;
/* 以'.oldbin'结尾 */
ngx_array_t
env;
char
**environment;
#if (NGX_THREADS)
ngx_int_t
worker_threads;
size_t
thread_stack_size;
#endif
} ngx_core_conf_t;

2. create_conf分析

create_conf只是指针,CORE模块的create_conf指向ngx_core_module_init_conf()函数,该函数创建ngx_core_conf_t配置结构。

static void *
ngx_core_module_create_conf(ngx_cycle_t *cycle)
{
ngx_core_conf_t
*ccf;
ccf = ngx_pcalloc(cycle->pool, sizeof(ngx_core_conf_t));
if (ccf == NULL) {
return NULL;
}
/*
* set by ngx_pcalloc()
*
*
ccf->pid = NULL;
*
ccf->oldpid = NULL;
*
ccf->priority = 0;
*
ccf->cpu_affinity_n = 0;
*
ccf->cpu_affinity = NULL;
*/
ccf->daemon = NGX_CONF_UNSET;
ccf->master = NGX_CONF_UNSET;
ccf->timer_resolution = NGX_CONF_UNSET_MSEC;
ccf->worker_processes = NGX_CONF_UNSET;
ccf->debug_points = NGX_CONF_UNSET;
ccf->rlimit_nofile = NGX_CONF_UNSET;
ccf->rlimit_core = NGX_CONF_UNSET;
ccf->rlimit_sigpending = NGX_CONF_UNSET;
ccf->user = (ngx_uid_t) NGX_CONF_UNSET_UINT;
ccf->group = (ngx_gid_t) NGX_CONF_UNSET_UINT;
#if (NGX_THREADS)
ccf->worker_threads = NGX_CONF_UNSET;
ccf->thread_stack_size = NGX_CONF_UNSET_SIZE;
#endif
if (ngx_array_init(&ccf->env, cycle->pool, 1, sizeof(ngx_str_t))
!= NGX_OK)
{
return NULL;
}
return ccf;
}

该函数很简单,即将配置结构的各个字段初始化为未设置的值。如下。

#define NGX_CONF_UNSET
-1
#define NGX_CONF_UNSET_UINT
(ngx_uint_t) -1
#define NGX_CONF_UNSET_PTR
(void *) -1
#define NGX_CONF_UNSET_SIZE
(size_t) -1
#define NGX_CONF_UNSET_MSEC
(ngx_msec_t) -1

3. init_conf分析

init_conf才是真正的初始化该结构。

(1) 初始化daemon、master等

直接赋值。

(2) 初始化pid、oldpid

调用ngx_conf_full_name()函数初始化pid,实际上就是在pid字符串前加上NGX_PREFIX获取pid全路径,NGX_PREFIX定义如下。

#ifndef NGX_PREFIX
#define NGX_PREFIX
"/usr/local/nginx/"
#endif

例如,ngx_conf_full_name()被调用前ccf->pid的内容如下。

(gdb) p ccf->pid
$2 = {
len = 14,
data = 0x4727ff "logs/nginx.pid"
}

ngx_conf_full_name()被调用后ccf->pid的内容如下。

(gdb) p ccf->pid
$3 = {
len = 31,
data = 0x6cce78 "/usr/local/nginx/logs/nginx.pid"
}

(3)初始化username,user,group

该初始化通过调用系统函数getpwnam()getgrnam()完成。相关数据结构如下。

The getpwnam() function returns a pointer to a structure containing the broken-out fields of the record in the password database (e.g., the local password file /etc/passwd, NIS, and LDAP) that matches the username name.
       The passwd structure is defined in <pwd.h> as follows:
           struct passwd {
               char   *pw_name;       /* username */
               char   *pw_passwd;     /* user password */
               uid_t   pw_uid;        /* user ID */
               gid_t   pw_gid;        /* group ID */
               char   *pw_gecos;      /* user information */
               char   *pw_dir;        /* home directory */
               char   *pw_shell;      /* shell program */
           };

The getgrnam() function returns a pointer to a structure containing the broken-out fields of the record in the group database (e.g., the local group file /etc/group, NIS, and LDAP) that matches the group name name.
      The group structure is defined in <grp.h> as follows:
           struct group {
               char   *gr_name;       /* group name */
               char   *gr_passwd;     /* group password */
               gid_t   gr_gid;        /* group ID */
               char  **gr_mem;        /* group members */
           };

获得的数据如下。

(gdb) p *pwd
$5 = {
pw_name = 0x6b82a0 "nobody",
pw_passwd = 0x6b82a7 "x",
pw_uid = 99,
pw_gid = 99,
pw_gecos = 0x6b82af "Nobody",
pw_dir = 0x6b82b6 "/",
pw_shell = 0x6b82b8 "/sbin/nologin"
}
(gdb) p *grp
$6 = {
gr_name = 0x6c3bf0 "nobody",
gr_passwd = 0x6c3bf7 "x",
gr_gid = 99,
gr_mem = 0x6c3c00
}

(4) 初始化lock_file

同初始化pid,调用ngx_conf_full_name()函数初始化lock_file,即在lock_file字符串前加上NGX_PREFIX获取其全路径,其全路径如下。

(gdb) p ccf->lock_file
$6 = {
len = 32,
data = 0x6ccebf "/usr/local/nginx/logs/nginx.lock"
}

(5) 初始化ngx_cycle->lock_file

ngx_cycle->lock_file的初始化是复制ccf->lock_file的内容并在其后链接".accept"。

(6) ngx_cpymem与ngx_memcpy

ngx_cpymem(dst,src,n):将src内容拷贝n个到dst,且返回地址dst+n

ngx_memcpy(dst,src,n):将src内容拷贝n个到dst

(7) 配置结构初始化后的内容

跟踪调试即可获得ngx_core_module这个CORE模块的配置结构,如下。

(gdb) p *ccf
$12 = {
daemon = 1,
master = 1,
timer_resolution = 0,
worker_processes = 1,
debug_points = 0,
rlimit_nofile = -1,
rlimit_sigpending = -1,
rlimit_core = -1,
priority = 0,
cpu_affinity_n = 0,
cpu_affinity = 0x0,
username = 0x47280e "nobody",
user = 99,
group = 99,
working_directory = {
len = 0,
data = 0x0
},
lock_file = {
len = 32,
data = 0x6ccebf "/usr/local/nginx/logs/nginx.lock"
},
pid = {
len = 31,
data = 0x6cce78 "/usr/local/nginx/logs/nginx.pid"
},
oldpid = {
len = 39,
data = 0x6cce98 "/usr/local/nginx/logs/nginx.pid.oldbin"
},
env = {
elts = 0x6b12a0,
nelts = 0,
size = 16,
nalloc = 1,
pool = 0x6b0280
},
environment = 0x0
}

4. 小结

本文主要分析core模块的callback,后文继续分析配置文件解析等。

阅读、分析优秀的开源代码,一定要亲自操刀运行、调试,才能深刻理解调用路径,数据流向。当然笔者还没有开始分析nginx的核心功能代码,我想那将是非常享受的代码之旅。

 

Reference

# man getpwnam

# man getgrnam

最后

以上就是体贴乌龟为你收集整理的nginx源码分析—core模块callback的全部内容,希望文章能够帮你解决nginx源码分析—core模块callback所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部