您的位置:首页 > 运维架构 > Nginx

nginx源码分析—core模块callback

2012-05-15 15:55 701 查看
作者:阿波

链接:/article/1451044.html

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模块的配置结构如下,存放配置文件中的核心指令,如deamon,master等。

./src/core/ngx_cycle.h

[cpp] view
plaincopy

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配置结构。

[cpp] view
plaincopy

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;

}

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

[cpp] view
plaincopy

#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定义如下。

[cpp] view
plaincopy

#ifndef NGX_PREFIX

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

#endif

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

[plain] view
plaincopy

(gdb) p ccf->pid

$2 = {

len = 14,

data = 0x4727ff "logs/nginx.pid"

}

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

[plain] view
plaincopy

(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 */

};

获得的数据如下。

[plain] view
plaincopy

(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获取其全路径,其全路径如下。

[plain] view
plaincopy

(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模块的配置结构,如下。

[plain] view
plaincopy

(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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: