ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Nginx源码分析之--os相关脚本

2019-07-31 13:56:15  阅读:231  来源: 互联网

标签:SRCS os feature Nginx UNIX 源码 DEPS auto NGX


01 选择平台

我将在本文中分析nginx是如何发现当前的宿主操作系统,以及对特定操作系统进行初始化的过程。

os相关脚本

1. 测试宿主操作系统

我们首先看一下nginx是如何通过脚本来确定当前运行的操作系统版本。
这里面有一个参数是很重要的,NGX_PLATFORM,这个参数保存了当前宿主的操作系统,我们看一下它是如何被赋值的。

(1)初始化

首先在auto/options被初始化为空。

1NGX_PLATFORM=
(2)解析配置参数

在执行configure命令的时候,我们可以通过指定crossbuild参数来主动设置当前的操作系统。

1--crossbuild=*)                  NGX_PLATFORM="$value"      ;;
(3)自主决定

如果我们没有在configure参数中指定上述参数(我们大多数情况下也不会指定该选项),那么nginx会自动判断操作系统类型。
configure脚本中,我们看如下内容:

 1if test -z "$NGX_PLATFORM"; then
2    echo "checking for OS"
3
4    NGX_SYSTEM=`uname -s 2>/dev/null`
5    NGX_RELEASE=`uname -r 2>/dev/null`
6    NGX_MACHINE=`uname -m 2>/dev/null`
7
8    echo " + $NGX_SYSTEM $NGX_RELEASE $NGX_MACHINE"
9
10    NGX_PLATFORM="$NGX_SYSTEM:$NGX_RELEASE:$NGX_MACHINE";
11
12    case "$NGX_SYSTEM" in
13        MINGW32_* | MINGW64_* | MSYS_*)
14            NGX_PLATFORM=win32
15        ;;
16    esac
17
18else
19    echo "building for $NGX_PLATFORM"
20    NGX_SYSTEM=$NGX_PLATFORM
21fi

这一部分就是nginx判断操作系统版本的代码。

①. 向终端输出内容,表示开始检查平台类型。

1echo "checking for OS"
复制代码

②. 检测操作系类型,发行版本号,机器体系架构

1NGX_SYSTEM=`uname -s 2>/dev/null`
2NGX_RELEASE=`uname -r 2>/dev/null`
3NGX_MACHINE=`uname -m 2>/dev/null`
4
5echo " + $NGX_SYSTEM $NGX_RELEASE $NGX_MACHINE"
6
7NGX_PLATFORM="$NGX_SYSTEM:$NGX_RELEASE:$NGX_MACHINE";

在我的计算机上面,上面的脚本执行之后内容依次是:

1NGX_SYSTEM=Linux
2NGX_RELEASE=3.10.0-693.2.2.el7.x86_64
3NGX_MACHINE=x86_64
复制代码

说明我的操作系统是3.10版本的Linux,当前计算机是x86_64架构。
so,

1NGX_PLATFORM=Linux:3.10.0-693.2.2.el7.x86_64:x86_64

02 os/conf脚本

我们这个时候分析os/conf脚本的话,就非常简单了。

1. 脚本内容

  1echo "checking for $NGX_SYSTEM specific features"
 2
 3case "$NGX_PLATFORM" in
 4
 5    FreeBSD:*)
 6        . auto/os/freebsd
 7    ;;
 8
 9    Linux:*)
10        . auto/os/linux
11    ;;
12
13    SunOS:*)
14        . auto/os/solaris
15    ;;
16
17    Darwin:*)
18        . auto/os/darwin
19    ;;
20
21    win32)
22        . auto/os/win32
23    ;;
24
25    DragonFly:*)
26        have=NGX_FREEBSD . auto/have_headers
27        CORE_INCS="$UNIX_INCS"
28        CORE_DEPS="$UNIX_DEPS $FREEBSD_DEPS"
29        CORE_SRCS="$UNIX_SRCS $FREEBSD_SRCS"
30
31        echo " + sendfile() found"
32        have=NGX_HAVE_SENDFILE . auto/have
33        CORE_SRCS="$CORE_SRCS $FREEBSD_SENDFILE_SRCS"
34
35        ngx_spacer='
36'
37    ;;
38
39    NetBSD:*)
40        CORE_INCS="$UNIX_INCS"
41        CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
42        CORE_SRCS="$UNIX_SRCS"
43
44        NGX_RPATH=YES
45    ;;
46
47    HP-UX:*)
48        # HP/UX
49        have=NGX_HPUX . auto/have_headers
50        CORE_INCS="$UNIX_INCS"
51        CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
52        CORE_SRCS="$UNIX_SRCS"
53        CC_AUX_FLAGS="$CC_AUX_FLAGS -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1"
54        CC_AUX_FLAGS="$CC_AUX_FLAGS -D_HPUX_ALT_XOPEN_SOCKET_API"
55    ;;
56
57    OSF1:*)
58        # Tru64 UNIX
59        have=NGX_TRU64 . auto/have_headers
60        have=NGX_HAVE_STRERROR_R . auto/nohave
61        CORE_INCS="$UNIX_INCS"
62        CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
63        CORE_SRCS="$UNIX_SRCS"
64    ;;
65
66    GNU:*)
67        # GNU Hurd
68        have=NGX_GNU_HURD . auto/have_headers
69        CORE_INCS="$UNIX_INCS"
70        CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
71        CORE_SRCS="$UNIX_SRCS"
72        CC_AUX_FLAGS="$CC_AUX_FLAGS -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64"
73    ;;
74
75    *)
76        CORE_INCS="$UNIX_INCS"
77        CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
78        CORE_SRCS="$UNIX_SRCS"
79    ;;
80
81esac
82
83
84case "$NGX_MACHINE" in
85
86    i386 | i686 | i86pc)
87        have=NGX_HAVE_NONALIGNED . auto/have
88        NGX_MACH_CACHE_LINE=32
89    ;;
90
91    amd64 | x86_64)
92        have=NGX_HAVE_NONALIGNED . auto/have
93        NGX_MACH_CACHE_LINE=64
94    ;;
95
96    sun4u | sun4v | sparc | sparc64)
97        have=NGX_ALIGNMENT value=16 . auto/define
98        # TODO
99        NGX_MACH_CACHE_LINE=64
100    ;;
101
102    ia64 )
103        have=NGX_ALIGNMENT value=16 . auto/define
104        # TODO
105        NGX_MACH_CACHE_LINE=64
106    ;;
107
108    aarch64 )
109        have=NGX_ALIGNMENT value=16 . auto/define
110        NGX_MACH_CACHE_LINE=64
111    ;;
112
113    *)
114        have=NGX_ALIGNMENT value=16 . auto/define
115        NGX_MACH_CACHE_LINE=32
116    ;;
117
118esac
119
120if test -z "$NGX_CPU_CACHE_LINE"; then
121    NGX_CPU_CACHE_LINE=$NGX_MACH_CACHE_LINE
122fi
123
124have=NGX_CPU_CACHE_LINE value=$NGX_CPU_CACHE_LINE . auto/define

2. 脚本分析

1).向终端输出提示字符

1echo "checking for $NGX_SYSTEM specific features"

2).根据NGX_PLATFORM执行特定脚本
根据上面获取的NGX_PLATFORM判断不同的平台,执行每个平台特定的脚本。我们使用的是linxu系统,所以执行linux平台脚本。

1 Linux:*)
2        . auto/os/linux
3    ;;

这个脚本后面再分析。

3). 根据机器架构设置字节对齐方式以及缓存相关特性
因为我的计算机是x86_64,所以执行如下脚本:

1 amd64 | x86_64)
2        have=NGX_HAVE_NONALIGNED . auto/have
3        NGX_MACH_CACHE_LINE=64
4    ;;

这里就是使用auto/have脚本向NGX_AUTO_CONFIG_H中写入:

1#ifndef NGX_AUTO_CONFIG_H
2#define NGX_AUTO_CONFIG_H 1
3#endif

4). 设置缓存行长度数据

1if test -z "$NGX_CPU_CACHE_LINE"; then
2    NGX_CPU_CACHE_LINE=$NGX_MACH_CACHE_LINE
3fi
4
5have=NGX_CPU_CACHE_LINE value=$NGX_CPU_CACHE_LINE . auto/define

因为我们在auto/cc编译器相关的脚本中也设置了NGX_CPU_CACHE_LINE,所以这里先判断NGX_CPU_CACHE_LINE的值,如果之前没有设置,那么就使用auto/os/conf脚本中的值。
然后将值通过auto/define写入到头文件中。

03 Linux平台特性

在上面提到过,nginx会根据当前的操作系统执行平台特定脚本。对于我的电脑来说,就是执行auto/os/linux脚本。下面我们看一下这个脚本都干了什么。

1. 脚本内容

  1have=NGX_LINUX . auto/have_headers
 2
 3CORE_INCS="$UNIX_INCS"
 4CORE_DEPS="$UNIX_DEPS $LINUX_DEPS"
 5CORE_SRCS="$UNIX_SRCS $LINUX_SRCS"
 6
 7ngx_spacer='
 8'
 9
10cc_aux_flags="$CC_AUX_FLAGS"
11CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64"
12
13
14# Linux kernel version
15
16version=$((`uname -r \
17    | sed -n -e 's/^\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\).*/ \
18                                                 \1*256*256+\2*256+\3/p' \
19             -e 's/^\([0-9][0-9]*\)\.\([0-9][0-9]*\).*/\1*256*256+\2*256/p'`))
20
21version=${version:-0}
22
23
24# posix_fadvise64() had been implemented in 2.5.60
25
26if [ $version -lt 132412 ]; then
27    have=NGX_HAVE_POSIX_FADVISE . auto/nohave
28fi
29
30# epoll, EPOLLET version
31
32ngx_feature="epoll"
33ngx_feature_name="NGX_HAVE_EPOLL"
34ngx_feature_run=yes
35ngx_feature_incs="#include <sys/epoll.h>"
36ngx_feature_path=
37ngx_feature_libs=
38ngx_feature_test="int efd = 0;
39                  struct epoll_event ee;
40                  ee.events = EPOLLIN|EPOLLOUT|EPOLLET;
41                  ee.data.ptr = NULL;
42                  (void) ee;
43                  efd = epoll_create(100);
44                  if (efd == -1) return 1;"
45. auto/feature
46
47if [ $ngx_found = yes ]; then
48    have=NGX_HAVE_CLEAR_EVENT . auto/have
49    CORE_SRCS="$CORE_SRCS $EPOLL_SRCS"
50    EVENT_MODULES="$EVENT_MODULES $EPOLL_MODULE"
51    EVENT_FOUND=YES
52
53
54    # EPOLLRDHUP appeared in Linux 2.6.17, glibc 2.8
55
56    ngx_feature="EPOLLRDHUP"
57    ngx_feature_name="NGX_HAVE_EPOLLRDHUP"
58    ngx_feature_run=no
59    ngx_feature_incs="#include <sys/epoll.h>"
60    ngx_feature_path=
61    ngx_feature_libs=
62    ngx_feature_test="int efd = 0, fd = 0;
63                      struct epoll_event ee;
64                      ee.events = EPOLLIN|EPOLLRDHUP|EPOLLET;
65                      ee.data.ptr = NULL;
66                      epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ee)"
67    . auto/feature
68
69
70    # EPOLLEXCLUSIVE appeared in Linux 4.5, glibc 2.24
71
72    ngx_feature="EPOLLEXCLUSIVE"
73    ngx_feature_name="NGX_HAVE_EPOLLEXCLUSIVE"
74    ngx_feature_run=no
75    ngx_feature_incs="#include <sys/epoll.h>"
76    ngx_feature_path=
77    ngx_feature_libs=
78    ngx_feature_test="int efd = 0, fd = 0;
79                      struct epoll_event ee;
80                      ee.events = EPOLLIN|EPOLLEXCLUSIVE;
81                      ee.data.ptr = NULL;
82                      epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ee)"
83    . auto/feature
84fi
85
86
87# O_PATH and AT_EMPTY_PATH were introduced in 2.6.39, glibc 2.14
88
89ngx_feature="O_PATH"
90ngx_feature_name="NGX_HAVE_O_PATH"
91ngx_feature_run=no
92ngx_feature_incs="#include <sys/types.h>
93                  #include <sys/stat.h>
94                  #include <fcntl.h>"
95ngx_feature_path=
96ngx_feature_libs=
97ngx_feature_test="int fd; struct stat sb;
98                  fd = openat(AT_FDCWD, \".\", O_PATH|O_DIRECTORY|O_NOFOLLOW);
99                  if (fstatat(fd, \"\", &sb, AT_EMPTY_PATH) != 0) return 1"
100. auto/feature
101
102
103# sendfile()
104
105CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURCE"
106ngx_feature="sendfile()"
107ngx_feature_name="NGX_HAVE_SENDFILE"
108ngx_feature_run=yes
109ngx_feature_incs="#include <sys/sendfile.h>
110                  #include <errno.h>"
111ngx_feature_path=
112ngx_feature_libs=
113ngx_feature_test="int s = 0, fd = 1;
114                  ssize_t n; off_t off = 0;
115                  n = sendfile(s, fd, &off, 1);
116                  if (n == -1 && errno == ENOSYS) return 1"
117. auto/feature
118
119if [ $ngx_found = yes ]; then
120    CORE_SRCS="$CORE_SRCS $LINUX_SENDFILE_SRCS"
121fi
122
123
124# sendfile64()
125
126CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64"
127ngx_feature="sendfile64()"
128ngx_feature_name="NGX_HAVE_SENDFILE64"
129ngx_feature_run=yes
130ngx_feature_incs="#include <sys/sendfile.h>
131                  #include <errno.h>"
132ngx_feature_path=
133ngx_feature_libs=
134ngx_feature_test="int s = 0, fd = 1;
135                  ssize_t n; off_t off = 0;
136                  n = sendfile(s, fd, &off, 1);
137                  if (n == -1 && errno == ENOSYS) return 1"
138. auto/feature
139
140
141ngx_include="sys/prctl.h"; . auto/include
142
143# prctl(PR_SET_DUMPABLE)
144
145ngx_feature="prctl(PR_SET_DUMPABLE)"
146ngx_feature_name="NGX_HAVE_PR_SET_DUMPABLE"
147ngx_feature_run=yes
148ngx_feature_incs="#include <sys/prctl.h>"
149ngx_feature_path=
150ngx_feature_libs=
151ngx_feature_test="if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) return 1"
152. auto/feature
153
154
155# prctl(PR_SET_KEEPCAPS)
156
157ngx_feature="prctl(PR_SET_KEEPCAPS)"
158ngx_feature_name="NGX_HAVE_PR_SET_KEEPCAPS"
159ngx_feature_run=yes
160ngx_feature_incs="#include <sys/prctl.h>"
161ngx_feature_path=
162ngx_feature_libs=
163ngx_feature_test="if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1) return 1"
164. auto/feature
165
166
167# capabilities
168
169ngx_feature="capabilities"
170ngx_feature_name="NGX_HAVE_CAPABILITIES"
171ngx_feature_run=no
172ngx_feature_incs="#include <linux/capability.h>
173                  #include <sys/syscall.h>"
174ngx_feature_path=
175ngx_feature_libs=
176ngx_feature_test="struct __user_cap_data_struct    data;
177                  struct __user_cap_header_struct  header;
178
179                  header.version = _LINUX_CAPABILITY_VERSION_1;
180                  data.effective = CAP_TO_MASK(CAP_NET_RAW);
181                  data.permitted = 0;
182
183                  (void) header;
184                  (void) data;
185                  (void) SYS_capset"
186. auto/feature
187
188
189# crypt_r()
190
191ngx_feature="crypt_r()"
192ngx_feature_name="NGX_HAVE_GNU_CRYPT_R"
193ngx_feature_run=no
194ngx_feature_incs="#include <crypt.h>"
195ngx_feature_path=
196ngx_feature_libs=-lcrypt
197ngx_feature_test="struct crypt_data  cd;
198                  crypt_r(\"key\", \"salt\", &cd);"
199. auto/feature
200
201
202ngx_include="sys/vfs.h";     . auto/include
203
204
205CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64"

脚本分析

1). 变量初始化
初始化许多变量,我们看一下脚本就行了,非常简单。

 1have=NGX_LINUX . auto/have_headers
2
3CORE_INCS="$UNIX_INCS"
4CORE_DEPS="$UNIX_DEPS $LINUX_DEPS"
5CORE_SRCS="$UNIX_SRCS $LINUX_SRCS"
6
7ngx_spacer='
8'
9
10cc_aux_flags="$CC_AUX_FLAGS"
11CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64"

2). 计算Linux内核版本数字
通过sed命令计算Linux的内核版本。

1# Linux kernel version
2
3version=$((`uname -r \
4    | sed -n -e 's/^\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\).*/ \
5                                                 \1*256*256+\2*256+\3/p' \
6             -e 's/^\([0-9][0-9]*\)\.\([0-9][0-9]*\).*/\1*256*256+\2*256/p'`))
7
8version=${version:-0}

3).测试Linux的某些特性
剩下的代码都是测试Linux是否支持一些特性,我们可以参考之前的auto/feature文章进行分析。

04 总结

我们在本文中详细的分析了auto/os/目录下的脚本。
这一部分的脚本主要是为了对特定平台进行初始化,由于我个人的计算机是Linux平台,所以我值分析了auto/os/linux脚本,其他的可以自行分析。





标签:SRCS,os,feature,Nginx,UNIX,源码,DEPS,auto,NGX
来源: https://blog.51cto.com/14453419/2425209

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有