├── ReadMe.markdown
├── TFS_RESTful_API.markdown
├── conf
└── example.conf
├── config
└── src
├── ngx_http_connection_pool.c
├── ngx_http_connection_pool.h
├── ngx_http_tfs.c
├── ngx_http_tfs.h
├── ngx_http_tfs_block_cache.c
├── ngx_http_tfs_block_cache.h
├── ngx_http_tfs_data_server_message.c
├── ngx_http_tfs_data_server_message.h
├── ngx_http_tfs_duplicate.c
├── ngx_http_tfs_duplicate.h
├── ngx_http_tfs_errno.h
├── ngx_http_tfs_json.c
├── ngx_http_tfs_json.h
├── ngx_http_tfs_local_block_cache.c
├── ngx_http_tfs_local_block_cache.h
├── ngx_http_tfs_meta_server_message.c
├── ngx_http_tfs_meta_server_message.h
├── ngx_http_tfs_module.c
├── ngx_http_tfs_name_server_message.c
├── ngx_http_tfs_name_server_message.h
├── ngx_http_tfs_peer_connection.c
├── ngx_http_tfs_peer_connection.h
├── ngx_http_tfs_protocol.h
├── ngx_http_tfs_raw_fsname.c
├── ngx_http_tfs_raw_fsname.h
├── ngx_http_tfs_rc_server_info.c
├── ngx_http_tfs_rc_server_info.h
├── ngx_http_tfs_rc_server_message.c
├── ngx_http_tfs_rc_server_message.h
├── ngx_http_tfs_remote_block_cache.c
├── ngx_http_tfs_remote_block_cache.h
├── ngx_http_tfs_restful.c
├── ngx_http_tfs_restful.h
├── ngx_http_tfs_root_server_message.c
├── ngx_http_tfs_root_server_message.h
├── ngx_http_tfs_server_handler.c
├── ngx_http_tfs_server_handler.h
├── ngx_http_tfs_tair_helper.c
├── ngx_http_tfs_tair_helper.h
├── ngx_http_tfs_timers.c
├── ngx_http_tfs_timers.h
├── ngx_tfs_common.c
└── ngx_tfs_common.h
/ReadMe.markdown:
--------------------------------------------------------------------------------
1 | 名称
2 | ====
3 |
4 | * nginx-tfs
5 |
6 | 描述
7 | ====
8 |
9 | * 这个模块实现了TFS的客户端,为TFS提供了RESTful API。TFS的全称是Taobao File System,是淘宝开源的一个分布式文件系统。
10 |
11 | 编译安装
12 | =======
13 |
14 | 1. TFS模块使用了一个开源的JSON库来支持JSON,请先安装[yajl](http://lloyd.github.com/yajl/)-2.0.1。
15 |
16 | 2. 下载[nginx](http://www.nginx.org/)或[tengine](http://tengine.taobao.org/)。
17 |
18 | 3. ./configure --add-module=/path/to/nginx-tfs
19 |
20 | 4. make && make install
21 |
22 | 配置
23 | ====
24 |
25 | http {
26 | tfs_upstream tfs_rc {
27 | server 127.0.0.1:6100;
28 | type rcs;
29 | rcs_zone name=tfs1 size=128M;
30 | rcs_interface eth0;
31 | rcs_heartbeat lock_file=/logs/lk.file interval=10s;
32 | }
33 |
34 | server {
35 | listen 7500;
36 | server_name localhost;
37 |
38 | tfs_keepalive max_cached=100 bucket_count=10;
39 | tfs_log "pipe:/usr/sbin/cronolog -p 30min /path/to/nginx/logs/cronolog/%Y/%m/%Y-%m-%d-%H-%M-tfs_access.log";
40 |
41 | location / {
42 | tfs_pass tfs://tfs_rc;
43 | }
44 | }
45 | }
46 |
47 | 指令
48 | ====
49 |
50 | server
51 | ------------
52 |
53 | **Syntax**: *server address*
54 |
55 | **Default**: *none*
56 |
57 | **Context**: *tfs_upstream*
58 |
59 | 指定后端TFS服务器的地址,当指令type为rcs时为RcServer的地址,如果为为ns时为NameServer的地址。此指令必须配置。例如:
60 |
61 | server 10.0.0.1:8108;
62 |
63 | type
64 | ----------------
65 |
66 | **Syntax**: *type [ns | rcs]*
67 |
68 | **Default**: *ns*
69 |
70 | **Context**: *tfs_upstream*
71 |
72 | 设置server类型,类型只能为ns或者rcs,如果为ns,则指令server指定的地址为NameServer的地址,如果为rcs,则为RcServer的地址。如需使用自定义文件名功能请设置类型为rcs,使用自定义文件名功能需额外配置MetaServer和RootServer。
73 |
74 | rcs\_zone
75 | --------------
76 |
77 | **Syntax**: *rcs_zone name=n size=num*
78 |
79 | **Default**: *none*
80 |
81 | **Context**: *tfs_upstream*
82 |
83 | 配置TFS应用在RcServer的配置信息。若开启RcServer(配置了type rcs),则必须配置此指令。配置此指令会在共享内存中缓存TFS应用在RcServer的配置信息,并可以通过指令rcs_heartbeat来和RcServer进行keepalive以保证应用的配置信息的及时更新。例如:
84 |
85 | rcs_zone name=tfs1 size=128M;
86 |
87 | rcs\_heartbeat
88 | --------------
89 |
90 | **Syntax**: *rcs_heartbeat lock_file=/path/to/file interval=time*
91 |
92 | **Default**: *none*
93 |
94 | **Context**: *tfs_upstream*
95 |
96 | 配置TFS应用和RcServer的keepalive,应用可通过此功能来和RcServer定期交互,以及时更新其配置信息。若开启RcServer功能(配置了type rcs),则必须配置此指令。例如:
97 |
98 | rcs_heartbeat lock_file=/path/to/nginx/logs/lk.file interval=10s;
99 |
100 | rcs\_interface
101 | ----------------
102 |
103 | **Syntax**: *rcs\_interface interface*
104 |
105 | **Default**: *none*
106 |
107 | **Context**: *tfs_upstream*
108 |
109 | 配置TFS模块使用的网卡。若开启RcServer功能(配置了type rcs),则必须配置此指令。例如:
110 |
111 | rcs_interface eth0;
112 |
113 | tfs\_upstream
114 | ----------------
115 |
116 | **Syntax**: *tfs\_upstream name {...}*
117 |
118 | **Default**: *none*
119 |
120 | **Context**: *http*
121 |
122 | 配置TFS模块的server信息,这个块包括上面几个命令。例如:
123 |
124 | tfs_upstream tfs_rc {
125 | server 127.0.0.1:6100;
126 | type rcs;
127 | rcs_zone name=tfs1 size=128M;
128 | rcs_interface eth0;
129 | rcs_heartbeat lock_file=/logs/lk.file interval=10s;
130 | }
131 |
132 |
133 | tfs_pass
134 | --------
135 |
136 | **Syntax**: *tfs_pass name*
137 |
138 | **Default**: *none*
139 |
140 | **Context**: *location*
141 |
142 | 是否打开TFS模块功能,此指令为关键指令,决定请求是否由TFS模块处理,必须配置。需要注意,这里不支持直接写ip地址或者域名,这里只支持指令tfs_upstream name {...} 配置的upstream,并且必须以 tfs:// 开头。例如:
143 |
144 |
145 | tfs_upstream tfs_rc {
146 | };
147 |
148 | location / {
149 | tfs_pass tfs://tfs_rc;
150 | }
151 |
152 | tfs_keepalive
153 | -------------
154 |
155 | **Syntax**: *tfs_keepalive max_cached=num bucket_count=num*
156 |
157 | **Default**: *none*
158 |
159 | **Context**: *http, server*
160 |
161 | 配置TFS模块使用的连接池的大小,TFS模块的连接池会缓存TFS模块和后端TFS服务器的连接。可以把这个连接池看作由多个hash桶构成的hash表,其中bucket\_count是桶的个数,max\_cached是桶的容量。此指令必须配置。注意,应该根据机器的内存情况来合理配置连接池的大小。例如:
162 |
163 | tfs_keepalive max_cached=100 bucket_count=15;
164 |
165 | tfs\_block\_cache\_zone
166 | -----------------------
167 |
168 | **Syntax**: *tfs_block_cache_zone size=num*
169 |
170 | **Default**: *none*
171 |
172 | **Context**: *http*
173 |
174 | 配置TFS模块的本地BlockCache。配置此指令会在共享内存中缓存TFS中的Block和DataServer的映射关系。注意,应根据机器的内存情况来合理配置BlockCache大小。例如:
175 |
176 | tfs_block_cache_zone size=256M;
177 |
178 | tfs\_log
179 | ----------------
180 |
181 | **Syntax**: *tfs_log path*
182 |
183 | **Default**: *none*
184 |
185 | **Context**: *http, server*
186 |
187 | 是否进行TFS访问记录。配置此指令会以固定格式将访问TFS的请求记录到指定log中,以便进行分析。具体格式参见代码。例如:
188 |
189 | tfs_log "pipe:/usr/sbin/cronolog -p 30min /path/to/nginx/logs/cronolog/%Y/%m/%Y-%m-%d-%H-%M-tfs_access.log";
190 |
191 | 注:cronolog支持依赖于tengine提供的扩展的日志模块。
192 |
193 | tfs\_body\_buffer\_size
194 | -----------------------
195 |
196 | **Syntax**: *tfs_body_buffer_size size*
197 |
198 | **Default**: *8k|16k*
199 |
200 | **Context**: *http, server, location*
201 |
202 | 配置用于和后端TFS服务器交互时使用的的body_buffer的大小。默认为页大小的2倍。建议设为2m。例如:
203 |
204 | tfs_body_buffer_size 2m;
205 |
206 | tfs\_connect\_timeout
207 | ---------------------
208 |
209 | **Syntax**: *tfs_connect_timeout time*
210 |
211 | **Default**: *3s*
212 |
213 | **Context**: *http, server, location*
214 |
215 | 配置连接后端TFS服务器的超时时间。
216 |
217 | tfs\_send\_timeout
218 | ------------------
219 |
220 | **Syntax**: *tfs_send_timeout time*
221 |
222 | **Default**: *3s*
223 |
224 | **Context**: *http, server, location*
225 |
226 | 配置向后端TFS服务器发送数据的超时时间。
227 |
228 | tfs\_read\_timeout
229 | ------------------
230 |
231 | **Syntax**: *tfs_read_timeout time*
232 |
233 | **Default**: *3s*
234 |
235 | **Context**: *http, server, location*
236 |
237 | 配置从后端TFS服务器接收数据的超时时间。
238 |
239 | 其他
240 | ----
241 | 能支持上传文件大小决定于client_max_body_size指令配置的大小。
242 |
243 |
244 |
245 |
--------------------------------------------------------------------------------
/conf/example.conf:
--------------------------------------------------------------------------------
1 |
2 | #user nobody;
3 | worker_processes 8;
4 |
5 | error_log logs/error.log warn;
6 | #error_log "pipe:/usr/sbin/cronolog /path/to/nginx/logs/cronolog/%Y/%m/%Y-%m-%d-error.log" warn;
7 |
8 | #pid logs/nginx.pid;
9 |
10 | #daemon off;
11 |
12 | events {
13 | worker_connections 10240;
14 | }
15 |
16 |
17 | http {
18 | include mime.types;
19 | default_type application/octet-stream;
20 |
21 | #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
22 | # '$status $body_bytes_sent "$http_referer" '
23 | # '"$http_user_agent" "$http_x_forwarded_for"';
24 |
25 | #access_log logs/access.log main;
26 |
27 | sendfile on;
28 | #tcp_nopush on;
29 |
30 | #keepalive_timeout 0;
31 | keepalive_timeout 65;
32 |
33 | gzip off;
34 |
35 | tfs_upstream tfs_ups {
36 | # ns_addr
37 | server 10.0.0.1:8108;
38 | # rcs_addr
39 | #server 10.0.0.1:7200;
40 | type ns;
41 | #rcs_interface eth0;
42 | #rcs_zone name=tfs1 size=128M;
43 | #rcs_heartbeat lock_file=/logs/lk.file interval=10s;
44 | }
45 |
46 | tfs_block_cache_zone size=256M;
47 |
48 | tfs_send_timeout 3s;
49 | tfs_connect_timeout 3s;
50 | tfs_read_timeout 3s;
51 |
52 | tfs_body_buffer_size 2m;
53 |
54 | server {
55 | listen 7500;
56 | server_name localhost;
57 | client_max_body_size 40960m;
58 |
59 | #charset koi8-r;
60 |
61 | #access_log "pipe:/usr/sbin/cronolog /path/to/nginx/logs/cronolog/%Y/%m/%Y-%m-%d-access.log";
62 |
63 | tfs_keepalive max_cached=100 bucket_count=10;
64 | #tfs_log "pipe:/usr/sbin/cronolog -p 30min /path/to/nginx/logs/cronolog/%Y/%m/%Y-%m-%d-%H-%M-tfs_access.log";
65 |
66 | location / {
67 | tfs_pass tfs://tfs_ups;
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/config:
--------------------------------------------------------------------------------
1 |
2 | # Copyright (C) 2010-2013 Alibaba Group Holding Limited
3 |
4 | ngx_feature_name=
5 | ngx_feature_run=no
6 | ngx_feature_incs="#include \
7 | #include "
8 | ngx_feature_test="yajl_version();"
9 |
10 | if [ -n "$LIBYAJL_INC" -o -n "$LIBYAJL_LIB" ]; then
11 | # explicit set libdyajl lib path
12 | ngx_feature="libdyajl library in directories specified by LIBYAJL_INC ($LIBYAJL_INC) and LIBYAJL_LIB ($LIBYAJL_LIB)"
13 | ngx_feature_path="$LIBYAJL_INC"
14 | if [ $NGX_RPATH = YES ]; then
15 | ngx_feature_libs="-R$LIBYAJL_LIB -L$LIBYAJL_LIB -lyajl"
16 | else
17 | ngx_feature_libs="-L$LIBYAJL_LIB -lyajl"
18 | fi
19 | . auto/feature
20 | else
21 | # auto-discovery
22 | ngx_feature="libyajl library"
23 | ngx_feature_path=
24 | ngx_feature_libs="-lyajl"
25 | . auto/feature
26 |
27 | if [ $ngx_found = no ]; then
28 | # FreeBSD, OpenBSD, linux
29 | ngx_feature="libyajl library in /usr/local/"
30 | ngx_feature_path="/usr/local/include/yajl /usr/local/include"
31 | if [ $NGX_RPATH = YES ]; then
32 | ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lyajl"
33 | else
34 | ngx_feature_libs="-L/usr/local/lib -lyajl"
35 | fi
36 | . auto/feature
37 | fi
38 |
39 | if [ $ngx_found = no ]; then
40 | # NetBSD
41 | ngx_feature="libyajl library in /usr/pkg/"
42 | ngx_feature_path="/usr/pkg/include/yajl /usr/pkg/include"
43 | if [ $NGX_RPATH = YES ]; then
44 | ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lyajl"
45 | else
46 | ngx_feature_libs="-L/usr/pkg/lib -lyajl"
47 | fi
48 | . auto/feature
49 | fi
50 |
51 | if [ $ngx_found = no ]; then
52 | # MacPorts
53 | ngx_feature="libyajl library in /opt/local/"
54 | ngx_feature_path="/opt/local/include/yajl /opt/local/include"
55 | if [ $NGX_RPATH = YES ]; then
56 | ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lyajl"
57 | else
58 | ngx_feature_libs="-L/opt/local/lib -lyajl"
59 | fi
60 | . auto/feature
61 | fi
62 | fi
63 |
64 | if [ $ngx_found = yes ]; then
65 | CORE_INCS="$CORE_INCS $ngx_feature_path"
66 | CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
67 | else
68 | cat << END
69 | $0: error: the ngx_tfs addon requires the libyajl library.
70 | END
71 | exit 1
72 | fi
73 |
74 |
75 | ngx_addon_name=ngx_http_tfs_module
76 | HTTP_MODULES="$HTTP_MODULES ngx_http_tfs_module"
77 |
78 |
79 | NGX_ADDON_DEPS="$NGX_ADDON_DEPS \
80 | $ngx_addon_dir/src/ngx_http_tfs.h \
81 | $ngx_addon_dir/src/ngx_http_tfs_errno.h \
82 | $ngx_addon_dir/src/ngx_tfs_common.h \
83 | $ngx_addon_dir/src/ngx_http_tfs_restful.h \
84 | $ngx_addon_dir/src/ngx_http_tfs_restful.h \
85 | $ngx_addon_dir/src/ngx_http_tfs_protocol.h \
86 | $ngx_addon_dir/src/ngx_http_connection_pool.h \
87 | $ngx_addon_dir/src/ngx_http_tfs_json.h \
88 | $ngx_addon_dir/src/ngx_http_tfs_rc_server_info.h \
89 | $ngx_addon_dir/src/ngx_http_tfs_raw_fsname.h \
90 | $ngx_addon_dir/src/ngx_http_tfs_tair_helper.h \
91 | $ngx_addon_dir/src/ngx_http_tfs_duplicate.h \
92 | $ngx_addon_dir/src/ngx_http_tfs_block_cache.h \
93 | $ngx_addon_dir/src/ngx_http_tfs_local_block_cache.h \
94 | $ngx_addon_dir/src/ngx_http_tfs_remote_block_cache.h \
95 | $ngx_addon_dir/src/ngx_http_tfs_timers.h \
96 | $ngx_addon_dir/src/ngx_http_tfs_rc_server_message.h \
97 | $ngx_addon_dir/src/ngx_http_tfs_name_server_message.h \
98 | $ngx_addon_dir/src/ngx_http_tfs_data_server_message.h \
99 | $ngx_addon_dir/src/ngx_http_tfs_root_server_message.h \
100 | $ngx_addon_dir/src/ngx_http_tfs_meta_server_message.h \
101 | $ngx_addon_dir/src/ngx_http_tfs_peer_connection.h \
102 | $ngx_addon_dir/src/ngx_http_tfs_server_handler.h "
103 |
104 |
105 | NGX_ADDON_SRCS="$NGX_ADDON_SRCS \
106 | $ngx_addon_dir/src/ngx_tfs_common.c \
107 | $ngx_addon_dir/src/ngx_http_tfs.c \
108 | $ngx_addon_dir/src/ngx_http_tfs_module.c \
109 | $ngx_addon_dir/src/ngx_http_tfs_restful.c \
110 | $ngx_addon_dir/src/ngx_http_connection_pool.c \
111 | $ngx_addon_dir/src/ngx_http_tfs_json.c \
112 | $ngx_addon_dir/src/ngx_http_tfs_rc_server_info.c \
113 | $ngx_addon_dir/src/ngx_http_tfs_raw_fsname.c \
114 | $ngx_addon_dir/src/ngx_http_tfs_tair_helper.c \
115 | $ngx_addon_dir/src/ngx_http_tfs_duplicate.c \
116 | $ngx_addon_dir/src/ngx_http_tfs_block_cache.c \
117 | $ngx_addon_dir/src/ngx_http_tfs_local_block_cache.c \
118 | $ngx_addon_dir/src/ngx_http_tfs_remote_block_cache.c \
119 | $ngx_addon_dir/src/ngx_http_tfs_timers.c \
120 | $ngx_addon_dir/src/ngx_http_tfs_rc_server_message.c \
121 | $ngx_addon_dir/src/ngx_http_tfs_name_server_message.c \
122 | $ngx_addon_dir/src/ngx_http_tfs_data_server_message.c \
123 | $ngx_addon_dir/src/ngx_http_tfs_root_server_message.c \
124 | $ngx_addon_dir/src/ngx_http_tfs_meta_server_message.c \
125 | $ngx_addon_dir/src/ngx_http_tfs_peer_connection.c \
126 | $ngx_addon_dir/src/ngx_http_tfs_server_handler.c "
127 |
128 |
129 | CORE_LIBS="$CORE_LIBS"
130 | CORE_INCS="$CORE_INCS $ngx_addon_dir/src"
131 |
--------------------------------------------------------------------------------
/src/ngx_http_connection_pool.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #include
8 |
9 |
10 | static void ngx_http_connection_pool_close(ngx_connection_t *c);
11 | static void ngx_http_connection_pool_close_handler(ngx_event_t *ev);
12 | static void ngx_http_connection_pool_dummy_handler(ngx_event_t *ev);
13 |
14 | static ngx_int_t ngx_http_connection_pool_get(ngx_peer_connection_t *pc,
15 | void *data);
16 | static void ngx_http_connection_pool_free(ngx_peer_connection_t *pc,
17 | void *data, ngx_uint_t state);
18 |
19 |
20 | ngx_http_connection_pool_t *
21 | ngx_http_connection_pool_init(ngx_pool_t *pool, ngx_uint_t max_cached,
22 | ngx_uint_t bucket_count)
23 | {
24 | ngx_uint_t j, k;
25 | ngx_http_connection_pool_t *conn_pool;
26 | ngx_http_connection_pool_elt_t *cached;
27 |
28 | conn_pool = ngx_pcalloc(pool, sizeof(ngx_http_connection_pool_t));
29 | if (conn_pool == NULL) {
30 | return NULL;
31 | }
32 |
33 | conn_pool->bucket_count = bucket_count;
34 | conn_pool->max_cached = max_cached;
35 |
36 | conn_pool->cache = ngx_pcalloc(pool, sizeof(ngx_queue_t) * bucket_count);
37 | if (conn_pool->cache == NULL) {
38 | return NULL;
39 | }
40 |
41 | conn_pool->free = ngx_pcalloc(pool, sizeof(ngx_queue_t) * bucket_count);
42 | if (conn_pool->free == NULL) {
43 | return NULL;
44 | }
45 |
46 | for (j = 0; j < bucket_count; j++) {
47 | ngx_queue_init(&conn_pool->cache[j]);
48 | ngx_queue_init(&conn_pool->free[j]);
49 | cached = ngx_pcalloc(pool,
50 | sizeof(ngx_http_connection_pool_elt_t) * max_cached);
51 | if (cached == NULL) {
52 | return NULL;
53 | }
54 |
55 | for (k = 0; k < max_cached; k++) {
56 | ngx_queue_insert_head(&conn_pool->free[j], &cached[k].queue);
57 | }
58 | }
59 |
60 | conn_pool->get_peer = ngx_http_connection_pool_get;
61 | conn_pool->free_peer = ngx_http_connection_pool_free;
62 | return conn_pool;
63 | }
64 |
65 |
66 | ngx_int_t
67 | ngx_http_connection_pool_get(ngx_peer_connection_t *pc, void *data)
68 | {
69 | u_char pc_addr[32] = {'\0'};
70 | ngx_uint_t bucket_id, hash;
71 | ngx_queue_t *q, *cache, *free;
72 | ngx_connection_t *c;
73 | ngx_http_connection_pool_t *p;
74 | ngx_http_connection_pool_elt_t *item;
75 |
76 | p = data;
77 |
78 | #if (NGX_DEBUG)
79 | p->count--;
80 | #endif
81 |
82 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
83 | "get keepalive peer");
84 |
85 | p->failed = 0;
86 |
87 | hash = ngx_murmur_hash2((u_char *) pc->sockaddr, pc->socklen);
88 | bucket_id = hash % p->bucket_count;
89 |
90 | cache = &p->cache[bucket_id];
91 | free = &p->free[bucket_id];
92 |
93 | ngx_sprintf(pc_addr, "%s:%d",
94 | inet_ntoa(((struct sockaddr_in*)(pc->sockaddr))->sin_addr),
95 | ntohs(((struct sockaddr_in*)(pc->sockaddr))->sin_port));
96 |
97 | for (q = ngx_queue_head(cache);
98 | q != ngx_queue_sentinel(cache);
99 | q = ngx_queue_next(q))
100 | {
101 | item = ngx_queue_data(q, ngx_http_connection_pool_elt_t, queue);
102 | c = item->connection;
103 |
104 | if (ngx_memn2cmp((u_char *) &item->sockaddr, (u_char *) pc->sockaddr,
105 | item->socklen, pc->socklen)
106 | == 0)
107 | {
108 | ngx_queue_remove(q);
109 | ngx_queue_insert_head(free, q);
110 |
111 | ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
112 | "get keepalive peer: using connection %p", c);
113 |
114 | c->idle = 0;
115 | c->log = pc->log;
116 | c->read->log = pc->log;
117 | c->write->log = pc->log;
118 | c->pool->log = pc->log;
119 |
120 | pc->connection = c;
121 | pc->cached = 1;
122 |
123 | item->free = free;
124 | return NGX_DONE;
125 | }
126 | }
127 |
128 | return NGX_OK;
129 | }
130 |
131 |
132 | void
133 | ngx_http_connection_pool_free(ngx_peer_connection_t *pc,
134 | void *data, ngx_uint_t state)
135 | {
136 | ngx_http_connection_pool_t *p = data;
137 | ngx_http_connection_pool_elt_t *item;
138 |
139 | ngx_uint_t hash, bucket_id;
140 | ngx_queue_t *q, *cache, *free;
141 | ngx_connection_t *c;
142 |
143 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
144 | "free keepalive peer");
145 |
146 | /* remember failed state - peer.free() may be called more than once */
147 |
148 | if (state & NGX_PEER_FAILED) {
149 | p->failed = 1;
150 | }
151 |
152 | /* cache valid connections */
153 |
154 | c = pc->connection;
155 |
156 | if (p->failed
157 | || c == NULL
158 | || c->read->eof
159 | || c->read->error
160 | || c->read->timedout
161 | || c->write->error
162 | || c->write->timedout)
163 | {
164 | return;
165 | }
166 |
167 | if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
168 | return;
169 | }
170 |
171 | #if (NGX_DEBUG)
172 | p->count++;
173 | #endif
174 | ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
175 | "free keepalive peer: saving connection %p", c);
176 |
177 | hash = ngx_murmur_hash2((u_char *) pc->sockaddr, pc->socklen);
178 | bucket_id = hash % p->bucket_count;
179 |
180 | cache = &p->cache[bucket_id];
181 | free = &p->free[bucket_id];
182 |
183 | if (ngx_queue_empty(free)) {
184 | q = ngx_queue_last(cache);
185 | ngx_queue_remove(q);
186 |
187 | item = ngx_queue_data(q, ngx_http_connection_pool_elt_t, queue);
188 |
189 | ngx_http_connection_pool_close(item->connection);
190 |
191 | } else {
192 | q = ngx_queue_head(free);
193 | ngx_queue_remove(q);
194 |
195 | item = ngx_queue_data(q, ngx_http_connection_pool_elt_t, queue);
196 | }
197 |
198 | item->connection = c;
199 | item->free = free;
200 | ngx_queue_insert_head(cache, q);
201 |
202 | pc->connection = NULL;
203 |
204 | if (c->read->timer_set) {
205 | ngx_del_timer(c->read);
206 | }
207 |
208 | if (c->write->timer_set) {
209 | ngx_del_timer(c->write);
210 | }
211 |
212 | c->write->handler = ngx_http_connection_pool_dummy_handler;
213 | c->read->handler = ngx_http_connection_pool_close_handler;
214 |
215 | c->data = item;
216 | c->idle = 1;
217 | c->log = ngx_cycle->log;
218 | c->read->log = ngx_cycle->log;
219 | c->write->log = ngx_cycle->log;
220 | c->pool->log = ngx_cycle->log;
221 |
222 | item->socklen = pc->socklen;
223 | ngx_memcpy(&item->sockaddr, pc->sockaddr, pc->socklen);
224 |
225 | if (c->read->ready) {
226 | ngx_http_connection_pool_close_handler(c->read);
227 | }
228 | }
229 |
230 |
231 | static void
232 | ngx_http_connection_pool_close_handler(ngx_event_t *ev)
233 | {
234 | ngx_http_connection_pool_elt_t *item;
235 |
236 | int n;
237 | char buf[1];
238 | ngx_connection_t *c;
239 |
240 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0,
241 | "keepalive close handler");
242 |
243 | c = ev->data;
244 |
245 | if (c->close) {
246 | goto close;
247 | }
248 |
249 | n = recv(c->fd, buf, 1, MSG_PEEK);
250 |
251 | if (n == -1 && ngx_socket_errno == NGX_EAGAIN) {
252 | /* stale event */
253 |
254 | if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
255 | goto close;
256 | }
257 |
258 | return;
259 | }
260 |
261 | close:
262 |
263 | item = c->data;
264 |
265 |
266 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0,
267 | "connection pool close connection");
268 |
269 | ngx_http_connection_pool_close(c);
270 |
271 | ngx_queue_remove(&item->queue);
272 | ngx_queue_insert_head(item->free, &item->queue);
273 | }
274 |
275 |
276 | static void
277 | ngx_http_connection_pool_close(ngx_connection_t *c)
278 | {
279 |
280 | #if (NGX_HTTP_SSL)
281 |
282 | if (c->ssl) {
283 | c->ssl->no_wait_shutdown = 1;
284 | c->ssl->no_send_shutdown = 1;
285 |
286 | if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
287 | c->ssl->handler = ngx_http_connection_pool_close;
288 | return;
289 | }
290 | }
291 |
292 | #endif
293 |
294 | ngx_destroy_pool(c->pool);
295 | ngx_close_connection(c);
296 | }
297 |
298 |
299 | static void
300 | ngx_http_connection_pool_dummy_handler(ngx_event_t *ev)
301 | {
302 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0,
303 | "keepalive dummy handler");
304 | }
305 |
306 | #if (NGX_DEBUG)
307 | void
308 | ngx_http_connection_pool_check(ngx_http_connection_pool_t *conn_pool,
309 | ngx_log_t *log)
310 | {
311 | if (conn_pool->count != 0) {
312 | ngx_log_error(NGX_LOG_ERR, log, 0,
313 | "<== conn pool check ==> "
314 | "some keepalive peer do not free!, conn_pool count: %i",
315 | conn_pool->count);
316 |
317 | } else {
318 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0,
319 | "<== conn pool check ==> all keepalive peers are free");
320 | }
321 | }
322 | #endif
323 |
--------------------------------------------------------------------------------
/src/ngx_http_connection_pool.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #ifndef _NGX_HTTP_CONNECTION_POOL_H_INCLUDED_
8 | #define _NGX_HTTP_CONNECTION_POOL_H_INCLUDED_
9 |
10 |
11 | #include
12 | #include
13 | #include
14 |
15 |
16 | typedef struct ngx_http_connection_pool_s ngx_http_connection_pool_t;
17 |
18 |
19 | typedef struct {
20 | ngx_queue_t queue;
21 | ngx_connection_t *connection;
22 | socklen_t socklen;
23 | u_char sockaddr[NGX_SOCKADDRLEN];
24 | ngx_queue_t *free;
25 | } ngx_http_connection_pool_elt_t;
26 |
27 |
28 | struct ngx_http_connection_pool_s {
29 | ngx_queue_t *cache;
30 | ngx_queue_t *free;
31 | ngx_uint_t max_cached;
32 | ngx_uint_t bucket_count;
33 |
34 | ngx_uint_t failed; /* unsigned:1 */
35 | ngx_pool_t *pool;
36 | #if (NGX_DEBUG)
37 | ngx_int_t count; /* check get&free op pairs */
38 | #endif
39 |
40 | ngx_event_get_peer_pt get_peer;
41 | ngx_event_free_peer_pt free_peer;
42 | };
43 |
44 |
45 | ngx_http_connection_pool_t *ngx_http_connection_pool_init(ngx_pool_t *pool,
46 | ngx_uint_t max_count, ngx_uint_t bucket_count);
47 |
48 | #if (NGX_DEBUG)
49 | void ngx_http_connection_pool_check(ngx_http_connection_pool_t *coon_pool,
50 | ngx_log_t *log);
51 | #endif
52 |
53 | #endif /* _NGX_HTTP_CONNECTION_POOL_H_INCLUDED_ */
54 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #ifndef _NGX_HTTP_TFS_H_INCLUDED_
8 | #define _NGX_HTTP_TFS_H_INCLUDED_
9 |
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 |
27 | typedef ngx_table_elt_t *(*ngx_http_tfs_create_header_pt)(ngx_http_request_t *r);
28 |
29 |
30 | typedef struct {
31 | ngx_str_t state_msg;
32 | ngx_int_t state;
33 | } ngx_http_tfs_state_t;
34 |
35 |
36 | typedef struct {
37 | uint32_t ds_count;
38 | ngx_http_tfs_inet_t *ds_addrs;
39 | int32_t version;
40 | int32_t lease_id;
41 | } ngx_http_tfs_block_info_t;
42 |
43 |
44 | typedef enum {
45 | NGX_HTTP_TFS_FROM_NONE = 0,
46 | NGX_HTTP_TFS_FROM_CACHE,
47 | NGX_HTTP_TFS_FROM_NS,
48 | } ngx_http_tfs_block_info_src_e;
49 |
50 |
51 | typedef struct {
52 | uint32_t block_id;
53 | uint64_t file_id;
54 | int64_t offset; /* offset in the file */
55 | uint32_t size;
56 | uint32_t crc;
57 | } NGX_PACKED ngx_http_tfs_segment_info_t;
58 |
59 |
60 | typedef struct {
61 | u_char file_name[NGX_HTTP_TFS_FILE_NAME_LEN];
62 | int64_t offset;
63 | uint32_t size;
64 | uint32_t crc;
65 | } NGX_PACKED ngx_http_tfs_tmp_segment_info_t;
66 |
67 |
68 | struct ngx_http_tfs_segment_data_s {
69 | uint8_t cache_hit;
70 | ngx_http_tfs_block_info_src_e block_info_src;
71 | ngx_http_tfs_segment_info_t segment_info;
72 | /* read/write offset inside this segment */
73 | uint32_t oper_offset;
74 | /* read/write size inside this segment */
75 | uint32_t oper_size;
76 | union {
77 | uint64_t write_file_number;
78 | };
79 | ngx_http_tfs_block_info_t block_info;
80 | ngx_uint_t ds_retry;
81 | ngx_uint_t ds_index;
82 | ngx_chain_t *data;
83 | } NGX_PACKED;
84 |
85 |
86 | typedef struct {
87 |
88 | uint8_t still_have; /* for custom file */
89 | uint32_t cluster_id;
90 | uint32_t open_mode;
91 | /* not for large_file's data */
92 | int64_t file_offset;
93 | uint64_t left_length;
94 | uint64_t file_hole_size;
95 | uint32_t last_write_segment_index;
96 | uint32_t segment_index;
97 | uint32_t segment_count;
98 | ngx_http_tfs_segment_data_t *segment_data;
99 | } NGX_PACKED ngx_http_tfs_file_t;
100 |
101 |
102 | struct ngx_http_tfs_upstream_s {
103 | ngx_str_t lock_file;
104 | ngx_msec_t rcs_interval;
105 |
106 | ngx_str_t rcs_zone_name;
107 | ngx_shm_zone_t *rcs_shm_zone;
108 | ngx_http_tfs_rc_ctx_t *rc_ctx;
109 |
110 | /* upstream name and port */
111 | in_port_t port;
112 | ngx_str_t host;
113 | ngx_addr_t *ups_addr;
114 |
115 | struct sockaddr_in local_addr;
116 | u_char local_addr_text[NGX_INET_ADDRSTRLEN];
117 |
118 | ngx_flag_t enable_rcs;
119 |
120 | ngx_http_tfs_timers_data_t *timer_data;
121 |
122 | unsigned used:1;
123 | };
124 |
125 |
126 | struct ngx_http_tfs_loc_conf_s {
127 | ngx_msec_t timeout;
128 |
129 | size_t max_temp_file_size;
130 | size_t temp_file_write_size;
131 |
132 | size_t busy_buffers_size_conf;
133 |
134 | uint64_t meta_root_server;
135 | ngx_http_tfs_meta_table_t meta_server_table;
136 |
137 | ngx_http_tfs_upstream_t *upstream;
138 | };
139 |
140 |
141 | typedef struct {
142 |
143 | ngx_log_t *log;
144 | } ngx_http_tfs_srv_conf_t;
145 |
146 |
147 | struct ngx_http_tfs_main_conf_s {
148 | ngx_msec_t tfs_connect_timeout;
149 | ngx_msec_t tfs_send_timeout;
150 | ngx_msec_t tfs_read_timeout;
151 |
152 | ngx_msec_t tair_timeout;
153 | ngx_http_tfs_tair_instance_t dup_instances[NGX_HTTP_TFS_MAX_CLUSTER_COUNT];
154 |
155 | size_t send_lowat;
156 | size_t buffer_size;
157 | size_t body_buffer_size;
158 | size_t busy_buffers_size;
159 |
160 | ngx_shm_zone_t *block_cache_shm_zone;
161 |
162 | ngx_flag_t enable_remote_block_cache;
163 | ngx_http_tfs_tair_instance_t remote_block_cache_instance;
164 | ngx_http_tfs_local_block_cache_ctx_t *local_block_cache_ctx;
165 |
166 | ngx_http_connection_pool_t *conn_pool;
167 |
168 | uint32_t cluster_id;
169 |
170 | ngx_array_t upstreams;
171 | };
172 |
173 |
174 | typedef ngx_int_t (*tfs_peer_handler_pt)(ngx_http_tfs_t *t);
175 | typedef void (*ngx_http_tfs_handler_pt)(ngx_http_request_t *r,
176 | ngx_http_tfs_t *t);
177 | typedef ngx_int_t (*ngx_http_tfs_sub_process_pt)(ngx_http_tfs_t *t);
178 |
179 |
180 | typedef struct {
181 | ngx_list_t headers;
182 |
183 | ngx_uint_t status_n;
184 | ngx_str_t status_line;
185 |
186 | ngx_table_elt_t *status;
187 | ngx_table_elt_t *date;
188 | ngx_table_elt_t *server;
189 | ngx_table_elt_t *connection;
190 |
191 | ngx_table_elt_t *expires;
192 | ngx_table_elt_t *etag;
193 | ngx_table_elt_t *x_accel_expires;
194 | ngx_table_elt_t *x_accel_redirect;
195 | ngx_table_elt_t *x_accel_limit_rate;
196 |
197 | ngx_table_elt_t *content_type;
198 | ngx_table_elt_t *content_length;
199 |
200 | ngx_table_elt_t *last_modified;
201 | ngx_table_elt_t *location;
202 | ngx_table_elt_t *accept_ranges;
203 | ngx_table_elt_t *www_authenticate;
204 |
205 | #if (NGX_HTTP_GZIP)
206 | ngx_table_elt_t *content_encoding;
207 | #endif
208 |
209 | off_t content_length_n;
210 |
211 | ngx_array_t cache_control;
212 | } ngx_http_tfs_headers_in_t;
213 |
214 |
215 | struct ngx_http_tfs_s {
216 | ngx_http_tfs_handler_pt read_event_handler;
217 | ngx_http_tfs_handler_pt write_event_handler;
218 |
219 | ngx_http_tfs_peer_connection_t *tfs_peer;
220 | ngx_http_tfs_peer_connection_t *tfs_peer_servers;
221 | uint8_t tfs_peer_count;
222 |
223 | ngx_http_tfs_loc_conf_t *loc_conf;
224 | ngx_http_tfs_srv_conf_t *srv_conf;
225 | ngx_http_tfs_main_conf_t *main_conf;
226 |
227 | ngx_http_tfs_restful_ctx_t r_ctx;
228 |
229 | ngx_output_chain_ctx_t output;
230 | ngx_chain_writer_ctx_t writer;
231 |
232 | ngx_chain_t *request_bufs;
233 | ngx_chain_t *send_body;
234 | ngx_pool_t *pool;
235 |
236 | ngx_buf_t header_buffer;
237 |
238 | ngx_chain_t *recv_chain;
239 |
240 | ngx_chain_t *out_bufs;
241 | ngx_chain_t *busy_bufs;
242 | ngx_chain_t *free_bufs;
243 |
244 | ngx_http_tfs_rcs_info_t *rc_info_node;
245 | ngx_rbtree_node_t *node;
246 |
247 | ngx_uint_t logical_cluster_index;
248 | ngx_uint_t rw_cluster_index;
249 |
250 | /* keep alive */
251 | ngx_queue_t *curr_ka_queue;
252 |
253 | /* header pointer */
254 | void *header;
255 | ngx_int_t header_size;
256 |
257 | tfs_peer_handler_pt create_request;
258 | tfs_peer_handler_pt input_filter;
259 | tfs_peer_handler_pt retry_handler;
260 | tfs_peer_handler_pt process_request_body;
261 | tfs_peer_handler_pt finalize_request;
262 |
263 | void *finalize_data;
264 | void *data;
265 |
266 | ngx_int_t request_sent;
267 | ngx_uint_t sent_size;
268 | off_t length;
269 |
270 | ngx_log_t *log;
271 |
272 | ngx_int_t parse_state;
273 |
274 | /* final file name */
275 | ngx_str_t file_name;
276 |
277 | ngx_int_t state;
278 |
279 | /* custom file */
280 | ngx_http_tfs_custom_meta_info_t meta_info;
281 | ngx_str_t last_file_path;
282 | int64_t last_file_pid;
283 | uint8_t last_file_type;
284 | ngx_int_t *dir_lens;
285 | ngx_int_t last_dir_level;
286 | uint16_t orig_action;
287 | ngx_array_t file_holes;
288 |
289 | ngx_http_tfs_headers_in_t headers_in;
290 |
291 | /* delete */
292 | ngx_int_t group_count;
293 | ngx_int_t group_seq;
294 |
295 | /* name ip */
296 | ngx_http_tfs_inet_t name_server_addr;
297 | ngx_str_t name_server_addr_text;
298 |
299 | ngx_http_tfs_json_gen_t *json_output;
300 |
301 | ngx_uint_t status;
302 | ngx_str_t status_line;
303 | ngx_int_t tfs_status;
304 |
305 | uint64_t output_size;
306 |
307 | /* de-duplicate info */
308 | ngx_http_tfs_dedup_ctx_t dedup_ctx;
309 |
310 | /* stat info */
311 | ngx_http_tfs_stat_info_t stat_info;
312 |
313 | /* file info */
314 | ngx_chain_t *meta_segment_data;
315 | ngx_http_tfs_file_t file;
316 | ngx_http_tfs_segment_head_t *seg_head;
317 | ngx_http_tfs_raw_file_info_t file_info;
318 | ngx_buf_t *readv2_rsp_tail_buf;
319 | uint8_t read_ver;
320 |
321 | /* block cache */
322 | ngx_http_tfs_block_cache_ctx_t block_cache_ctx;
323 |
324 | /* for parallel write segments */
325 | ngx_http_tfs_t *parent;
326 | ngx_http_tfs_t *next;
327 | ngx_http_tfs_t *free_sts;
328 | ngx_http_tfs_sub_process_pt sp_callback;
329 | uint32_t sp_count;
330 | uint32_t sp_done_count;
331 | uint32_t sp_fail_count;
332 | uint32_t sp_succ_count;
333 | uint32_t sp_curr;
334 | unsigned sp_ready:1;
335 |
336 | unsigned header_only:1;
337 | unsigned header_sent:1;
338 | unsigned has_split_frag:1;
339 | /* for custrom file read */
340 | unsigned is_first_segment:1;
341 |
342 | unsigned use_dedup:1;
343 | unsigned is_stat_dup_file:1;
344 | unsigned is_large_file:1;
345 | unsigned is_process_meta_seg:1;
346 | unsigned retry_curr_ns:1;
347 | };
348 |
349 |
350 | ngx_int_t ngx_http_tfs_init(ngx_http_tfs_t *t);
351 | void ngx_http_tfs_finalize_request(ngx_http_request_t *r,
352 | ngx_http_tfs_t *t, ngx_int_t rc);
353 | void ngx_http_tfs_finalize_state(ngx_http_tfs_t *t, ngx_int_t rc);
354 | ngx_int_t ngx_http_tfs_reinit(ngx_http_request_t *r, ngx_http_tfs_t *t);
355 | ngx_int_t ngx_http_tfs_connect(ngx_http_tfs_t *t);
356 | ngx_int_t ngx_http_tfs_lookup_block_cache(ngx_http_tfs_t *t,
357 | ngx_http_tfs_segment_data_t *segment_data);
358 | ngx_int_t ngx_http_tfs_batch_lookup_block_cache(ngx_http_tfs_t *t);
359 | void ngx_http_tfs_remove_block_cache(ngx_http_tfs_t *t,
360 | ngx_http_tfs_segment_data_t *segment_data);
361 | ngx_int_t ngx_http_tfs_set_output_appid(ngx_http_tfs_t *t, uint64_t app_id);
362 | void ngx_http_tfs_set_custom_initial_parameters(ngx_http_tfs_t *t);
363 | ngx_int_t ngx_http_tfs_misc_ctx_init(ngx_http_tfs_t *t,
364 | ngx_http_tfs_rcs_info_t *rc_node);
365 | ngx_int_t ngx_http_tfs_batch_process_start(ngx_http_tfs_t *t);
366 | ngx_int_t ngx_http_tfs_batch_process_end(ngx_http_tfs_t *t);
367 | ngx_int_t ngx_http_tfs_batch_process_next(ngx_http_tfs_t *t);
368 |
369 |
370 | #endif /* _NGX_TFS_H_INCLUDED_ */
371 |
372 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_block_cache.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 |
13 | ngx_int_t
14 | ngx_http_tfs_block_cache_lookup(ngx_http_tfs_block_cache_ctx_t *ctx,
15 | ngx_pool_t *pool, ngx_log_t *log, ngx_http_tfs_block_cache_key_t *key,
16 | ngx_http_tfs_block_cache_value_t *value)
17 | {
18 | ngx_int_t rc = NGX_DECLINED;
19 |
20 | if (ctx->curr_lookup_cache == NGX_HTTP_TFS_LOCAL_BLOCK_CACHE) {
21 |
22 | ctx->curr_lookup_cache = NGX_HTTP_TFS_REMOTE_BLOCK_CACHE;
23 |
24 | if (ctx->use_cache & NGX_HTTP_TFS_LOCAL_BLOCK_CACHE) {
25 | rc = ngx_http_tfs_local_block_cache_lookup(ctx->local_ctx,
26 | pool, log, key, value);
27 |
28 | if (rc == NGX_OK) {
29 | return rc;
30 | }
31 | }
32 | }
33 |
34 | if (ctx->curr_lookup_cache == NGX_HTTP_TFS_REMOTE_BLOCK_CACHE) {
35 |
36 | ctx->curr_lookup_cache = NGX_HTTP_TFS_NO_BLOCK_CACHE;
37 |
38 | if (ctx->use_cache & NGX_HTTP_TFS_REMOTE_BLOCK_CACHE) {
39 | rc = ngx_http_tfs_remote_block_cache_lookup(&ctx->remote_ctx,
40 | pool, log, key);
41 | }
42 | }
43 |
44 | return rc;
45 | }
46 |
47 |
48 | void
49 | ngx_http_tfs_block_cache_insert(ngx_http_tfs_block_cache_ctx_t *ctx,
50 | ngx_pool_t *pool, ngx_log_t *log, ngx_http_tfs_block_cache_key_t *key,
51 | ngx_http_tfs_block_cache_value_t *value)
52 | {
53 | if (ctx->use_cache & NGX_HTTP_TFS_REMOTE_BLOCK_CACHE) {
54 | ngx_http_tfs_remote_block_cache_insert(&ctx->remote_ctx,
55 | pool, log, key, value);
56 | }
57 |
58 | if (ctx->use_cache & NGX_HTTP_TFS_LOCAL_BLOCK_CACHE) {
59 | ngx_http_tfs_local_block_cache_insert(ctx->local_ctx, log, key, value);
60 | }
61 | }
62 |
63 |
64 | void
65 | ngx_http_tfs_block_cache_remove(ngx_http_tfs_block_cache_ctx_t *ctx,
66 | ngx_pool_t *pool, ngx_log_t *log, ngx_http_tfs_block_cache_key_t* key,
67 | uint8_t hit_status)
68 | {
69 | if (hit_status != NGX_HTTP_TFS_NO_BLOCK_CACHE
70 | && (ctx->use_cache & NGX_HTTP_TFS_LOCAL_BLOCK_CACHE))
71 | {
72 | ngx_http_tfs_local_block_cache_remove(ctx->local_ctx, log, key);
73 | }
74 |
75 | if (hit_status == NGX_HTTP_TFS_REMOTE_BLOCK_CACHE) {
76 | ngx_http_tfs_remote_block_cache_remove(&ctx->remote_ctx,
77 | pool, log, key);
78 | }
79 | }
80 |
81 |
82 | ngx_int_t
83 | ngx_http_tfs_block_cache_batch_lookup(ngx_http_tfs_block_cache_ctx_t *ctx,
84 | ngx_pool_t *pool, ngx_log_t *log, ngx_array_t *keys,
85 | ngx_array_t *kvs)
86 | {
87 | uint32_t i;
88 | ngx_int_t rc;
89 | ngx_uint_t local_miss_count;
90 | ngx_array_t local_miss_keys;
91 | ngx_http_tfs_t *t;
92 | ngx_http_tfs_segment_data_t *segment_data;
93 | ngx_http_tfs_block_cache_key_t *key;
94 |
95 | rc = NGX_DECLINED;
96 |
97 | if (ctx->curr_lookup_cache == NGX_HTTP_TFS_LOCAL_BLOCK_CACHE) {
98 |
99 | ctx->curr_lookup_cache = NGX_HTTP_TFS_REMOTE_BLOCK_CACHE;
100 |
101 | if (ctx->use_cache & NGX_HTTP_TFS_LOCAL_BLOCK_CACHE) {
102 | rc = ngx_http_tfs_local_block_cache_batch_lookup(ctx->local_ctx,
103 | pool, log, keys,
104 | kvs);
105 |
106 | if (rc == NGX_OK || rc == NGX_ERROR) {
107 | return rc;
108 | }
109 | }
110 | }
111 |
112 | /* rc == NGX_DECLIEND */
113 | if (ctx->curr_lookup_cache == NGX_HTTP_TFS_REMOTE_BLOCK_CACHE) {
114 |
115 | ctx->curr_lookup_cache = NGX_HTTP_TFS_NO_BLOCK_CACHE;
116 |
117 | if (ctx->use_cache & NGX_HTTP_TFS_REMOTE_BLOCK_CACHE) {
118 | t = ctx->remote_ctx.data;
119 | local_miss_count = keys->nelts - kvs->nelts;
120 |
121 | rc = ngx_array_init(&local_miss_keys, t->pool, local_miss_count,
122 | sizeof(ngx_http_tfs_block_cache_key_t));
123 | if (rc == NGX_ERROR) {
124 | return rc;
125 | }
126 |
127 | segment_data = &t->file.segment_data[t->file.segment_index];
128 | for (i = 0; i < keys->nelts; i++, segment_data++) {
129 | if (segment_data->cache_hit == NGX_HTTP_TFS_NO_BLOCK_CACHE) {
130 | key = (ngx_http_tfs_block_cache_key_t *)
131 | ngx_array_push(&local_miss_keys);
132 | key->ns_addr = *((uint64_t*)(&t->name_server_addr));
133 | key->block_id = segment_data->segment_info.block_id;
134 | }
135 | }
136 |
137 | rc = ngx_http_tfs_remote_block_cache_batch_lookup(&ctx->remote_ctx,
138 | pool, log,
139 | &local_miss_keys);
140 | }
141 | }
142 | return rc;
143 | }
144 |
145 |
146 | ngx_int_t
147 | ngx_http_tfs_block_cache_cmp(ngx_http_tfs_block_cache_key_t *left,
148 | ngx_http_tfs_block_cache_key_t *right)
149 | {
150 | if (left->ns_addr == right->ns_addr) {
151 | if (left->block_id == right->block_id) {
152 | return 0;
153 | }
154 | if (left->block_id < right->block_id) {
155 | return -1;
156 | }
157 | return 1;
158 | }
159 | if (left->ns_addr < right->ns_addr) {
160 | return -1;
161 | }
162 | return 1;
163 | }
164 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_block_cache.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #ifndef _NGX_HTTP_TFS_BLOCK_CACHE_H_INCLUDED_
8 | #define _NGX_HTTP_TFS_BLOCK_CACHE_H_INCLUDED_
9 |
10 |
11 | #include
12 | #include
13 |
14 |
15 | #define NGX_HTTP_TFS_BLOCK_CACHE_KEY_SIZE \
16 | sizeof(ngx_http_tfs_block_cache_key_t)
17 |
18 | #define NGX_HTTP_TFS_REMOTE_BLOCK_CACHE_VALUE_BASE_SIZE sizeof(uint32_t)
19 |
20 | #define NGX_HTTP_TFS_BLOCK_CACHE_DISCARD_ITEM_COUNT 10000
21 |
22 | #define NGX_HTTP_TFS_BLOCK_CACHE_STAT_COUNT (3000 * 60 * 60)
23 |
24 | #define NGX_HTTP_TFS_NO_BLOCK_CACHE 0x0
25 | #define NGX_HTTP_TFS_LOCAL_BLOCK_CACHE 0x1
26 | #define NGX_HTTP_TFS_REMOTE_BLOCK_CACHE 0x2
27 |
28 |
29 | typedef struct {
30 | uint64_t ns_addr;
31 | uint32_t block_id;
32 | } __attribute__ ((__packed__)) ngx_http_tfs_block_cache_key_t;
33 |
34 |
35 | typedef struct {
36 | uint32_t ds_count;
37 | uint64_t *ds_addrs;
38 | } ngx_http_tfs_block_cache_value_t;
39 |
40 |
41 | typedef struct {
42 | ngx_http_tfs_block_cache_key_t *key;
43 | ngx_http_tfs_block_cache_value_t *value;
44 | } ngx_http_tfs_block_cache_kv_t;
45 |
46 |
47 | typedef struct {
48 | ngx_rbtree_t rbtree;
49 | ngx_rbtree_node_t sentinel;
50 | ngx_queue_t queue;
51 | uint64_t discard_item_count;
52 | uint64_t hit_count;
53 | uint64_t miss_count;
54 | } ngx_http_tfs_block_cache_shctx_t;
55 |
56 |
57 | typedef struct {
58 | ngx_http_tfs_block_cache_shctx_t *sh;
59 | ngx_slab_pool_t *shpool;
60 | } ngx_http_tfs_local_block_cache_ctx_t;
61 |
62 |
63 | typedef struct {
64 | void *data;
65 | ngx_http_tfs_tair_instance_t *tair_instance;
66 | } ngx_http_tfs_remote_block_cache_ctx_t;
67 |
68 |
69 | typedef struct {
70 | ngx_http_tfs_local_block_cache_ctx_t *local_ctx;
71 | ngx_http_tfs_remote_block_cache_ctx_t remote_ctx;
72 | uint8_t use_cache;
73 | uint8_t curr_lookup_cache;
74 | } ngx_http_tfs_block_cache_ctx_t;
75 |
76 |
77 | ngx_int_t ngx_http_tfs_block_cache_lookup(ngx_http_tfs_block_cache_ctx_t *ctx,
78 | ngx_pool_t *pool, ngx_log_t *log, ngx_http_tfs_block_cache_key_t* key,
79 | ngx_http_tfs_block_cache_value_t *value);
80 | void ngx_http_tfs_block_cache_insert(ngx_http_tfs_block_cache_ctx_t *ctx,
81 | ngx_pool_t *pool, ngx_log_t *log, ngx_http_tfs_block_cache_key_t *key,
82 | ngx_http_tfs_block_cache_value_t *value);
83 | void ngx_http_tfs_block_cache_remove(ngx_http_tfs_block_cache_ctx_t *ctx,
84 | ngx_pool_t *pool, ngx_log_t *log, ngx_http_tfs_block_cache_key_t *key,
85 | uint8_t hit_status);
86 | ngx_int_t ngx_http_tfs_block_cache_batch_lookup(
87 | ngx_http_tfs_block_cache_ctx_t *ctx,
88 | ngx_pool_t *pool, ngx_log_t *log, ngx_array_t* keys, ngx_array_t *kvs);
89 | void ngx_http_tfs_block_cache_batch_insert(ngx_http_tfs_block_cache_ctx_t *ctx,
90 | ngx_pool_t *pool, ngx_log_t *log, ngx_array_t* kvs);
91 | ngx_int_t ngx_http_tfs_block_cache_cmp(ngx_http_tfs_block_cache_key_t *left,
92 | ngx_http_tfs_block_cache_key_t *right);
93 |
94 |
95 | #endif /* _NGX_HTTP_TFS_BLOCK_CACHE_H_INCLUDED_ */
96 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_data_server_message.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #ifndef _NGX_HTTP_TFS_DATA_SERVER_MESSAGE_H_INCLUDED_
8 | #define _NGX_HTTP_TFS_DATA_SERVER_MESSAGE_H_INCLUDED_
9 |
10 |
11 | #include
12 |
13 |
14 | ngx_chain_t *ngx_http_tfs_data_server_create_message(ngx_http_tfs_t *t);
15 | ngx_int_t ngx_http_tfs_data_server_parse_message(ngx_http_tfs_t *t);
16 | ngx_http_tfs_inet_t *ngx_http_tfs_select_data_server(ngx_http_tfs_t *t,
17 | ngx_http_tfs_segment_data_t *segment_data);
18 |
19 | ngx_int_t ngx_http_tfs_get_meta_segment(ngx_http_tfs_t *t);
20 | ngx_int_t ngx_http_tfs_set_meta_segment_data(ngx_http_tfs_t *t);
21 | ngx_int_t ngx_http_tfs_parse_meta_segment(ngx_http_tfs_t *t, ngx_chain_t *data);
22 | ngx_int_t ngx_http_tfs_get_segment_for_write(ngx_http_tfs_t *t);
23 |
24 | ngx_int_t ngx_http_tfs_get_segment_for_read(ngx_http_tfs_t *t);
25 | ngx_int_t ngx_http_tfs_get_segment_for_delete(ngx_http_tfs_t *t);
26 |
27 | ngx_int_t ngx_http_tfs_fill_file_hole(ngx_http_tfs_t *t, size_t file_hole_size);
28 |
29 |
30 | #endif /* _NGX_HTTP_TFS_DATA_SERVER_MESSAGE_H_INCLUDED_ */
31 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_duplicate.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | static void ngx_http_tfs_duplicate_get_handler(ngx_http_tair_key_value_t *kv,
13 | ngx_int_t rc, void *data);
14 | static void ngx_http_tfs_duplicate_put_handler(ngx_int_t rc, void *data);
15 | static void ngx_http_tfs_duplicate_delete_handler(ngx_int_t rc, void *data);
16 | static void ngx_http_tfs_duplicate_callback(ngx_http_tfs_dedup_ctx_t *ctx,
17 | ngx_int_t rc);
18 |
19 | ngx_int_t ngx_http_tfs_duplicate_check_suffix(ngx_str_t *tfs_name,
20 | ngx_str_t *suffix);
21 | ngx_int_t ngx_http_tfs_duplicate_check_filename(ngx_str_t *dup_name,
22 | ngx_http_tfs_raw_fsname_t* fsname);
23 |
24 |
25 | ngx_int_t
26 | ngx_http_tfs_get_duplicate_info(ngx_http_tfs_dedup_ctx_t *ctx,
27 | ngx_pool_t *pool, ngx_log_t * log, ngx_chain_t *data)
28 | {
29 | u_char *p;
30 | ssize_t data_len;
31 | ngx_int_t rc;
32 | ngx_http_tair_data_t tair_key;
33 |
34 | data_len = 0;
35 |
36 | rc = ngx_http_tfs_sum_md5(data, ctx->tair_key, &data_len, log);
37 | if (rc == NGX_ERROR) {
38 | return NGX_ERROR;
39 | }
40 |
41 | p = ctx->tair_key;
42 | p += NGX_HTTP_TFS_MD5_RESULT_LEN;
43 |
44 | *(uint32_t *) p = htonl(data_len);
45 |
46 | tair_key.type = NGX_HTTP_TAIR_BYTEARRAY;
47 | tair_key.data = ctx->tair_key;
48 | tair_key.len = NGX_HTTP_TFS_DUPLICATE_KEY_SIZE;
49 |
50 | ctx->md5_sumed = 1;
51 |
52 | rc = ngx_http_tfs_tair_get_helper(ctx->tair_instance, pool, log,
53 | &tair_key,
54 | ngx_http_tfs_duplicate_get_handler,
55 | ctx);
56 |
57 | return rc;
58 | }
59 |
60 |
61 | static void
62 | ngx_http_tfs_duplicate_get_handler(ngx_http_tair_key_value_t *kv, ngx_int_t rc,
63 | void *data)
64 | {
65 | u_char *p;
66 | ngx_http_tfs_t *t;
67 | ngx_http_tfs_dedup_ctx_t *ctx;
68 |
69 | ctx = data;
70 | t = ctx->data;
71 |
72 | if (rc == NGX_HTTP_ETAIR_SUCCESS) {
73 | p = kv->value->data;
74 | if (p != NULL
75 | && (kv->value->len > NGX_HTTP_TFS_DUPLICATE_VALUE_BASE_SIZE))
76 | {
77 | ctx->file_ref_count = *(int32_t *)p;
78 | p += sizeof(int32_t);
79 | ctx->dup_file_name.len = kv->value->len - sizeof(int32_t);
80 | ctx->dup_file_name.data = ngx_pcalloc(t->pool,
81 | ctx->dup_file_name.len);
82 | if (ctx->dup_file_name.data == NULL) {
83 | rc = NGX_ERROR;
84 |
85 | } else {
86 | ngx_memcpy(ctx->dup_file_name.data, p, ctx->dup_file_name.len);
87 | rc = NGX_OK;
88 | }
89 | ctx->dup_version = kv->version;
90 |
91 | } else {
92 | rc = NGX_ERROR;
93 | }
94 | ngx_log_debug3(NGX_LOG_DEBUG_HTTP, t->log, 0,
95 | "get duplicate info: "
96 | "file name: %V, file ref count: %d, dup_version: %d",
97 | &ctx->dup_file_name,
98 | ctx->file_ref_count,
99 | ctx->dup_version);
100 |
101 | } else {
102 | rc = NGX_ERROR;
103 | ctx->dup_version = NGX_HTTP_TFS_DUPLICATE_INITIAL_MAGIC_VERSION;
104 | }
105 | ngx_http_tfs_duplicate_callback(ctx, rc);
106 | }
107 |
108 |
109 | ngx_int_t
110 | ngx_http_tfs_set_duplicate_info(ngx_http_tfs_dedup_ctx_t *ctx,
111 | ngx_pool_t *pool, ngx_log_t * log, ngx_chain_t *data)
112 | {
113 | u_char *p;
114 | ssize_t data_len;
115 | ngx_int_t rc;
116 | ngx_http_tair_data_t tair_key;
117 | ngx_http_tair_data_t tair_value;
118 |
119 | data_len = 0;
120 |
121 | if (!ctx->md5_sumed) {
122 | rc = ngx_http_tfs_sum_md5(data, ctx->tair_key, &data_len, log);
123 | if (rc == NGX_ERROR) {
124 | return NGX_ERROR;
125 | }
126 |
127 | p = ctx->tair_key;
128 | p += NGX_HTTP_TFS_MD5_RESULT_LEN;
129 |
130 | *(uint32_t *) p = htonl(data_len);
131 | ctx->md5_sumed = 1;
132 | }
133 |
134 | tair_key.len = NGX_HTTP_TFS_DUPLICATE_KEY_SIZE;
135 | tair_key.data = ctx->tair_key;
136 | tair_key.type = NGX_HTTP_TAIR_BYTEARRAY;
137 |
138 | tair_value.len =
139 | NGX_HTTP_TFS_DUPLICATE_VALUE_BASE_SIZE + ctx->dup_file_name.len;
140 | tair_value.data = ngx_pcalloc(pool, tair_value.len);
141 | if (tair_value.data == NULL) {
142 | return NGX_ERROR;
143 | }
144 | ngx_memcpy(tair_value.data, &ctx->file_ref_count,
145 | NGX_HTTP_TFS_DUPLICATE_VALUE_BASE_SIZE);
146 | ngx_memcpy(tair_value.data + NGX_HTTP_TFS_DUPLICATE_VALUE_BASE_SIZE,
147 | ctx->dup_file_name.data, ctx->dup_file_name.len);
148 | tair_value.type = NGX_HTTP_TAIR_BYTEARRAY;
149 | ngx_log_debug3(NGX_LOG_DEBUG_HTTP, log, 0,
150 | "set duplicate info: "
151 | "file name: %V, file ref count: %d, dup_version: %d",
152 | &ctx->dup_file_name,
153 | ctx->file_ref_count,
154 | ctx->dup_version);
155 |
156 | rc = ngx_http_tfs_tair_put_helper(ctx->tair_instance, pool, log,
157 | &tair_key, &tair_value, 0/*expire*/,
158 | ctx->dup_version,
159 | ngx_http_tfs_duplicate_put_handler, ctx);
160 |
161 | return rc;
162 | }
163 |
164 |
165 | static void
166 | ngx_http_tfs_duplicate_put_handler(ngx_int_t rc, void *data)
167 | {
168 | ngx_http_tfs_dedup_ctx_t *ctx;
169 |
170 | ctx = data;
171 |
172 | if (rc == NGX_HTTP_ETAIR_SUCCESS) {
173 | rc = NGX_OK;
174 |
175 | } else {
176 | rc = NGX_ERROR;
177 | }
178 | ngx_http_tfs_duplicate_callback(ctx, rc);
179 | }
180 |
181 |
182 | ngx_int_t
183 | ngx_http_tfs_delete_duplicate_info(ngx_http_tfs_dedup_ctx_t *ctx,
184 | ngx_pool_t *pool, ngx_log_t * log, ngx_chain_t *data)
185 | {
186 | u_char *p;
187 | ssize_t data_len;
188 | ngx_int_t rc;
189 | ngx_array_t tair_keys;
190 | ngx_http_tair_data_t *tair_key;
191 |
192 | data_len = 0;
193 |
194 | if (!ctx->md5_sumed) {
195 | rc = ngx_http_tfs_sum_md5(data, ctx->tair_key, &data_len, log);
196 | if (rc == NGX_ERROR) {
197 | return NGX_ERROR;
198 | }
199 |
200 | p = ctx->tair_key;
201 | p += NGX_HTTP_TFS_MD5_RESULT_LEN;
202 |
203 | *(uint32_t *) p = htonl(data_len);
204 | ctx->md5_sumed = 1;
205 | }
206 |
207 | rc = ngx_array_init(&tair_keys, pool, 1, sizeof(ngx_http_tair_data_t));
208 | if (rc == NGX_ERROR) {
209 | return rc;
210 | }
211 | tair_key = (ngx_http_tair_data_t*) ngx_array_push(&tair_keys);
212 |
213 | tair_key->type = NGX_HTTP_TAIR_BYTEARRAY;
214 | tair_key->data = ctx->tair_key;
215 | tair_key->len = NGX_HTTP_TFS_DUPLICATE_KEY_SIZE;
216 |
217 | rc = ngx_http_tfs_tair_delete_helper(ctx->tair_instance, pool, log,
218 | &tair_keys,
219 | ngx_http_tfs_duplicate_delete_handler,
220 | ctx);
221 |
222 | return rc;
223 | }
224 |
225 |
226 | static void
227 | ngx_http_tfs_duplicate_delete_handler(ngx_int_t rc, void *data)
228 | {
229 | ngx_http_tfs_dedup_ctx_t *ctx;
230 |
231 | ctx = data;
232 |
233 | if (rc == NGX_HTTP_ETAIR_SUCCESS) {
234 | rc = NGX_OK;
235 |
236 | } else {
237 | rc = NGX_ERROR;
238 | }
239 | ngx_http_tfs_duplicate_callback(ctx, rc);
240 | }
241 |
242 |
243 | ngx_int_t
244 | ngx_http_tfs_duplicate_check_suffix(ngx_str_t *tfs_name, ngx_str_t *suffix)
245 | {
246 | ngx_int_t rc;
247 |
248 | rc = NGX_ERROR;
249 | if ((tfs_name->len == NGX_HTTP_TFS_FILE_NAME_LEN && suffix->len == 0)
250 | || (tfs_name->len > NGX_HTTP_TFS_FILE_NAME_LEN && suffix->len > 0
251 | && ((tfs_name->len - NGX_HTTP_TFS_FILE_NAME_LEN) == suffix->len)
252 | && (ngx_strncmp(suffix->data,
253 | tfs_name->data + NGX_HTTP_TFS_FILE_NAME_LEN,
254 | suffix->len) == 0)))
255 | {
256 | rc = NGX_OK;
257 | }
258 |
259 | return rc;
260 | }
261 |
262 |
263 | ngx_int_t
264 | ngx_http_tfs_duplicate_check_filename(ngx_str_t *dup_file_name,
265 | ngx_http_tfs_raw_fsname_t* fsname)
266 | {
267 | ngx_int_t rc;
268 | ngx_str_t dup_file_suffix = ngx_null_string;
269 | ngx_http_tfs_raw_fsname_t dup_fsname;
270 |
271 | rc = ngx_http_tfs_raw_fsname_parse(dup_file_name, &dup_file_suffix,
272 | &dup_fsname);
273 | if (rc == NGX_OK) {
274 | if (fsname->cluster_id == dup_fsname.cluster_id
275 | && fsname->file.block_id == dup_fsname.file.block_id
276 | && fsname->file.seq_id == dup_fsname.file.seq_id
277 | && fsname->file.suffix == dup_fsname.file.suffix)
278 | {
279 | return NGX_OK;
280 | }
281 | }
282 |
283 | return NGX_ERROR;
284 | }
285 |
286 |
287 | static void
288 | ngx_http_tfs_duplicate_callback(ngx_http_tfs_dedup_ctx_t *ctx, ngx_int_t rc)
289 | {
290 | ngx_http_tfs_t *t;
291 | ngx_http_tfs_rcs_info_t *rc_info;
292 |
293 | t = ctx->data;
294 | rc_info = t->rc_info_node;
295 |
296 | switch (t->r_ctx.action.code) {
297 | case NGX_HTTP_TFS_ACTION_REMOVE_FILE:
298 | switch(t->state) {
299 | case NGX_HTTP_TFS_STATE_REMOVE_READ_META_SEGMENT:
300 | /* exist in tair */
301 | if (rc == NGX_OK) {
302 | /* check file name */
303 | rc = ngx_http_tfs_duplicate_check_filename(&ctx->dup_file_name,
304 | &t->r_ctx.fsname);
305 | if (rc == NGX_OK) {
306 | /* file name match, modify ref count and save tair */
307 | if (t->r_ctx.unlink_type == NGX_HTTP_TFS_UNLINK_DELETE) {
308 | if (--ctx->file_ref_count <= 0) {
309 | /* if ref count is 0,
310 | * remove key from tair then unlink file */
311 | t->state = NGX_HTTP_TFS_STATE_REMOVE_GET_BLK_INFO;
312 | t->is_stat_dup_file = NGX_HTTP_TFS_NO;
313 | t->tfs_peer->body_buffer = ctx->save_body_buffer;
314 | rc = ngx_http_tfs_delete_duplicate_info(ctx,
315 | t->pool,
316 | t->log,
317 | t->meta_segment_data);
318 | /* do not care delete tair fail,
319 | * go on unlinking file */
320 | if (rc == NGX_ERROR) {
321 | ngx_http_tfs_finalize_state(t, NGX_OK);
322 | }
323 |
324 | return;
325 | }
326 |
327 | /* file_ref_count > 0, just save tair */
328 | t->state = NGX_HTTP_TFS_STATE_REMOVE_DONE;
329 | rc = ngx_http_tfs_set_duplicate_info(ctx, t->pool,
330 | t->log,
331 | t->meta_segment_data);
332 | /* do not care save tair fail, return success */
333 | if (rc == NGX_ERROR) {
334 | ngx_http_tfs_finalize_state(t, NGX_DONE);
335 | }
336 |
337 | return;
338 | }
339 | }
340 |
341 | /* file name not match, unlink file */
342 | t->tfs_peer->body_buffer = ctx->save_body_buffer;
343 | t->state = NGX_HTTP_TFS_STATE_REMOVE_GET_BLK_INFO;
344 | t->is_stat_dup_file = NGX_HTTP_TFS_NO;
345 | ngx_http_tfs_finalize_state(t, NGX_OK);
346 |
347 | return;
348 | }
349 |
350 | /* not exist in tair, unlink file */
351 | t->tfs_peer->body_buffer = ctx->save_body_buffer;
352 | t->state = NGX_HTTP_TFS_STATE_REMOVE_GET_BLK_INFO;
353 | t->is_stat_dup_file = NGX_HTTP_TFS_NO;
354 | ngx_http_tfs_finalize_state(t, NGX_OK);
355 | return;
356 | case NGX_HTTP_TFS_STATE_REMOVE_GET_BLK_INFO:
357 | case NGX_HTTP_TFS_STATE_REMOVE_DELETE_DATA:
358 | ngx_http_tfs_finalize_state(t, NGX_OK);
359 | return;
360 | case NGX_HTTP_TFS_STATE_REMOVE_DONE:
361 | ngx_http_tfs_finalize_state(t, NGX_DONE);
362 | return;
363 | }
364 | break;
365 | case NGX_HTTP_TFS_ACTION_WRITE_FILE:
366 | switch(t->state) {
367 | case NGX_HTTP_TFS_STATE_WRITE_CLUSTER_ID_NS:
368 | case NGX_HTTP_TFS_STATE_WRITE_GET_BLK_INFO:
369 | /* exist in tair */
370 | if (rc == NGX_OK) {
371 | /* check suffix */
372 | rc = ngx_http_tfs_duplicate_check_suffix(&ctx->dup_file_name,
373 | &t->r_ctx.file_suffix);
374 | if (rc == NGX_OK) {
375 | /* suffix match, need to stat file */
376 | rc = ngx_http_tfs_raw_fsname_parse(&ctx->dup_file_name,
377 | &ctx->dup_file_suffix,
378 | &t->r_ctx.fsname);
379 | if (rc == NGX_OK) {
380 | t->file.cluster_id = t->r_ctx.fsname.cluster_id;
381 | t->is_stat_dup_file = NGX_HTTP_TFS_YES;
382 | t->state = NGX_HTTP_TFS_STATE_WRITE_GET_BLK_INFO;
383 | }
384 |
385 | } else {
386 | /* suffix not match, need save new tfs file,
387 | * do not save tair */
388 | t->use_dedup = NGX_HTTP_TFS_NO;
389 | }
390 | } /* not exist in tair need save new tfs file and tair */
391 |
392 | /* need reset meta segment */
393 | rc = ngx_http_tfs_get_meta_segment(t);
394 | if (rc != NGX_OK) {
395 | ngx_log_error(NGX_LOG_ERR, t->log, 0,
396 | "tfs get meta segment failed");
397 | ngx_http_tfs_finalize_request(t->data, t,
398 | NGX_HTTP_INTERNAL_SERVER_ERROR);
399 | return;
400 | }
401 |
402 | /* lookup block cache */
403 | if (t->is_stat_dup_file) {
404 | /* dedup write may need to stat file */
405 | if (rc_info->use_remote_block_cache) {
406 | rc = ngx_http_tfs_get_remote_block_cache_instance(
407 | &t->block_cache_ctx.remote_ctx,
408 | &rc_info->remote_block_cache_info);
409 | if (rc == NGX_ERROR) {
410 | ngx_log_error(NGX_LOG_ERR, t->log, 0,
411 | "get remote block cache instance failed.");
412 |
413 | } else {
414 | t->block_cache_ctx.use_cache |=
415 | NGX_HTTP_TFS_REMOTE_BLOCK_CACHE;
416 | }
417 | }
418 |
419 | rc = ngx_http_tfs_lookup_block_cache(t,
420 | &t->file.segment_data[t->file.segment_index]);
421 | if (rc == NGX_ERROR) {
422 | ngx_log_error(NGX_LOG_ERR, t->log, 0,
423 | "lookup block cache failed");
424 | }
425 |
426 | if (rc == NGX_DECLINED
427 | && (t->block_cache_ctx.use_cache
428 | & NGX_HTTP_TFS_REMOTE_BLOCK_CACHE))
429 | {
430 | return;
431 | }
432 | }
433 |
434 | ngx_http_tfs_finalize_state(t, NGX_OK);
435 | break;
436 | case NGX_HTTP_TFS_STATE_WRITE_STAT_DUP_FILE:
437 | if (rc == NGX_OK) {
438 | t->state = NGX_HTTP_TFS_STATE_WRITE_DONE;
439 | ngx_http_tfs_finalize_state(t, NGX_DONE);
440 |
441 | } else {
442 | /* save tair(add ref count) failed,
443 | * need save new tfs file, do not save tair */
444 | t->state = NGX_HTTP_TFS_STATE_WRITE_CLUSTER_ID_NS;
445 | t->is_stat_dup_file = NGX_HTTP_TFS_NO;
446 | t->use_dedup = NGX_HTTP_TFS_NO;
447 | /* need reset output buf */
448 | t->out_bufs = NULL;
449 | /* need reset block id and file id */
450 | t->file.segment_data[0].segment_info.block_id = 0;
451 | t->file.segment_data[0].segment_info.file_id = 0;
452 | ngx_http_tfs_finalize_state(t, NGX_OK);
453 | }
454 | break;
455 | case NGX_HTTP_TFS_STATE_WRITE_DONE:
456 | ngx_http_tfs_finalize_state(t, NGX_DONE);
457 | break;
458 | }
459 | }
460 | return;
461 | }
462 |
463 |
464 | #ifdef NGX_HTTP_TFS_USE_TAIR
465 |
466 | ngx_int_t
467 | ngx_http_tfs_get_dedup_instance(ngx_http_tfs_dedup_ctx_t *ctx,
468 | ngx_http_tfs_tair_server_addr_info_t *server_addr_info,
469 | uint32_t server_addr_hash)
470 | {
471 | ngx_str_t *st;
472 | ngx_int_t rc, i;
473 | ngx_array_t config_server;
474 | ngx_http_tfs_t *t;
475 | ngx_http_etair_server_conf_t *server;
476 | ngx_http_tfs_tair_instance_t *instance;
477 |
478 | t = ctx->data;
479 |
480 | for (i = 0; i < NGX_HTTP_TFS_MAX_CLUSTER_COUNT; i++) {
481 | instance = &t->main_conf->dup_instances[i];
482 |
483 | if (instance->server == NULL) {
484 | break;
485 | }
486 |
487 | if (instance->server_addr_hash == server_addr_hash) {
488 | ctx->tair_instance = instance;
489 | return NGX_OK;
490 | }
491 | }
492 |
493 | /* not found && full, clear */
494 | if (i > NGX_HTTP_TFS_MAX_CLUSTER_COUNT) {
495 | for (i = 0; i < NGX_HTTP_TFS_MAX_CLUSTER_COUNT; i++) {
496 | instance = &t->main_conf->dup_instances[i];
497 | if (instance->server != NULL) {
498 | ngx_http_etair_destory_server(instance->server,
499 | (ngx_cycle_t *) ngx_cycle);
500 | instance->server = NULL;
501 | }
502 | }
503 | instance = &t->main_conf->dup_instances[0];
504 | }
505 |
506 | rc = ngx_array_init(&config_server, t->pool,
507 | NGX_HTTP_TFS_TAIR_CONFIG_SERVER_COUNT,
508 | sizeof(ngx_str_t));
509 | if (rc == NGX_ERROR) {
510 | return NGX_ERROR;
511 | }
512 |
513 | for (i = 0; i < NGX_HTTP_TFS_TAIR_CONFIG_SERVER_COUNT; i++) {
514 | if (server_addr_info->server[i].len > 0 ) {
515 | st = (ngx_str_t *) ngx_array_push(&config_server);
516 | *st = server_addr_info->server[i];
517 | }
518 | }
519 |
520 | server = &server_addr_info->server[NGX_HTTP_TFS_TAIR_CONFIG_SERVER_COUNT];
521 | server = ngx_http_etair_create_server(server,
522 | &config_server,
523 | t->main_conf->tair_timeout,
524 | (ngx_cycle_t *) ngx_cycle);
525 | if (server == NULL) {
526 | return NGX_ERROR;
527 | }
528 | instance->server = server;
529 | instance->server_addr_hash = server_addr_hash;
530 | instance->area = server_addr_info->area;
531 | ctx->tair_instance = instance;
532 |
533 | return NGX_OK;
534 | }
535 |
536 | #else
537 |
538 | ngx_int_t
539 | ngx_http_tfs_get_dedup_instance(ngx_http_tfs_dedup_ctx_t *ctx,
540 | ngx_http_tfs_tair_server_addr_info_t *server_addr_info,
541 | uint32_t server_addr_hash)
542 | {
543 | return NGX_ERROR;
544 | }
545 |
546 | #endif
547 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_duplicate.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #ifndef _NGX_HTTP_TFS_DUPLICATE_H_INCLUDED_
8 | #define _NGX_HTTP_TFS_DUPLICATE_H_INCLUDED_
9 |
10 |
11 | #include
12 | #include
13 |
14 |
15 | typedef struct {
16 | u_char tair_key[NGX_HTTP_TFS_DUPLICATE_KEY_SIZE];
17 | int32_t dup_version;
18 | int32_t file_ref_count;
19 | ngx_str_t dup_file_name;
20 | ngx_str_t dup_file_suffix;
21 | ngx_buf_t save_body_buffer;
22 | ngx_http_tfs_t *data;
23 | ngx_http_tfs_tair_instance_t *tair_instance;
24 | unsigned md5_sumed:1;
25 | } ngx_http_tfs_dedup_ctx_t;
26 |
27 |
28 | ngx_int_t ngx_http_tfs_get_duplicate_info(ngx_http_tfs_dedup_ctx_t *ctx,
29 | ngx_pool_t *pool, ngx_log_t *log, ngx_chain_t *data);
30 | ngx_int_t ngx_http_tfs_set_duplicate_info(ngx_http_tfs_dedup_ctx_t *ctx,
31 | ngx_pool_t *pool, ngx_log_t *log, ngx_chain_t *data);
32 | ngx_int_t ngx_http_tfs_delete_duplicate_info(ngx_http_tfs_dedup_ctx_t *ctx,
33 | ngx_pool_t *pool, ngx_log_t *log, ngx_chain_t *data);
34 |
35 | ngx_int_t ngx_http_tfs_get_dedup_instance(ngx_http_tfs_dedup_ctx_t *ctx,
36 | ngx_http_tfs_tair_server_addr_info_t *server_addr_info,
37 | uint32_t server_addr_hash);
38 |
39 |
40 | #endif /* _NGX_HTTP_TFS_DUPLICATE_H_INCLUDED_ */
41 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_errno.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #ifndef _NGX_HTTP_TFS_ERRNO_H_INCLUDED_
8 | #define _NGX_HTTP_TFS_ERRNO_H_INCLUDED_
9 |
10 |
11 | #include
12 |
13 |
14 | #define NGX_HTTP_TFS_EXIT_GENERAL_ERROR -1000
15 | #define NGX_HTTP_TFS_EXIT_CONFIG_ERROR -1001
16 | #define NGX_HTTP_TFS_EXIT_UNKNOWN_MSGTYPE -1002
17 | #define NGX_HTTP_TFS_EXIT_INVALID_ARGU -1003
18 | #define NGX_HTTP_TFS_EXIT_ALL_SEGMENT_ -1004
19 | #define NGX_HTTP_TFS_EXIT_INVALIDFD_ERROR -1005
20 | #define NGX_HTTP_TFS_EXIT_NOT_INIT_ERROR -1006
21 | #define NGX_HTTP_TFS_EXIT_INVALID_ARGU_ERROR -1007
22 | #define NGX_HTTP_TFS_EXIT_NOT_PERM_OPER -1008
23 | #define NGX_HTTP_TFS_EXIT_NOT_OPEN_ERROR -1009
24 | #define NGX_HTTP_TFS_EXIT_CHECK_CRC_ERROR -1010
25 | #define NGX_HTTP_TFS_EXIT_SERIALIZE_ERROR -1011
26 | #define NGX_HTTP_TFS_EXIT_DESERIALIZE_ERROR -1012
27 | /* access permission error */
28 | #define NGX_HTTP_TFS_EXIT_ACCESS_PERMISSION_ERROR -1013
29 | /* system parameter error */
30 | #define NGX_HTTP_TFS_EXIT_SYSTEM_PARAMETER_ERROR -1014
31 | #define NGX_HTTP_TFS_EXIT_UNIQUE_META_NOT_EXIST -1015
32 | /* fuction parameter error */
33 | #define NGX_HTTP_TFS_EXIT_PARAMETER_ERROR -1016
34 | /* mmap file failed */
35 | #define NGX_HTTP_TFS_EXIT_MMAP_FILE_ERROR -1017
36 | /* lru value not found by key */
37 | #define NGX_HTTP_TFS_EXIT_LRU_VALUE_NOT_EXIST -1018
38 | /* lru value existed */
39 | #define NGX_HTTP_TFS_EXIT_LRU_VALUE_EXIST -1019
40 | /* channel id invalid */
41 | #define NGX_HTTP_TFS_EXIT_CHANNEL_ID_INVALID -1020
42 | /* data packet timeout */
43 | #define NGX_HTTP_TFS_EXIT_DATA_PACKET_TIMEOUT -1021
44 |
45 | #define NGX_HTTP_TFS_EXIT_FILE_OP_ERROR -2000
46 | #define NGX_HTTP_TFS_EXIT_OPEN_FILE_ERROR -2001
47 | #define NGX_HTTP_TFS_EXIT_INVALID_FD -2002
48 | #define NGX_HTTP_TFS_EXIT_RECORD_SIZE_ERROR -2003
49 | #define NGX_HTTP_TFS_EXIT_READ_FILE_ERROR -2004
50 | #define NGX_HTTP_TFS_EXIT_WRITE_FILE_ERROR -2005
51 | #define NGX_HTTP_TFS_EXIT_FILESYSTEM_ERROR -2006
52 | #define NGX_HTTP_TFS_EXIT_FILE_FORMAT_ERROR -2007
53 | #define NGX_HTTP_TFS_EXIT_SLOTS_OFFSET_SIZE_ERROR -2008
54 | #define NGX_HTTP_TFS_EXIT_FILE_BUSY_ERROR -2009
55 |
56 | #define NGX_HTTP_TFS_EXIT_NETWORK_ERROR -3000
57 | #define NGX_HTTP_TFS_EXIT_IOCTL_ERROR -3001
58 | #define NGX_HTTP_TFS_EXIT_CONNECT_ERROR -3002
59 | #define NGX_HTTP_TFS_EXIT_SENDMSG_ERROR -3003
60 | #define NGX_HTTP_TFS_EXIT_RECVMSG_ERROR -3004
61 | #define NGX_HTTP_TFS_EXIT_TIMEOUT_ERROR -3005
62 | /* waitid exist error */
63 | #define NGX_HTTP_TFS_EXIT_WAITID_EXIST_ERROR -3006
64 | /* waitid not found in waitid set */
65 | #define NGX_HTTP_TFS_EXIT_WAITID_NOT_FOUND_ERROR -3007
66 | /* socket nof found in socket map */
67 | #define NGX_HTTP_TFS_EXIT_SOCKET_NOT_FOUND_ERROR -3008
68 |
69 | #define NGX_HTTP_TFS_EXIT_TFS_ERROR -5000
70 | #define NGX_HTTP_TFS_EXIT_NO_BLOCK -5001
71 | #define NGX_HTTP_TFS_EXIT_NO_DATASERVER -5002
72 | #define NGX_HTTP_TFS_EXIT_BLOCK_NOT_FOUND -5003
73 | #define NGX_HTTP_TFS_EXIT_DATASERVER_NOT_FOUND -5004
74 | /* lease not found */
75 | #define NGX_HTTP_TFS_EXIT_CANNOT_GET_LEASE -5005
76 | #define NGX_HTTP_TFS_EXIT_COMMIT_ERROR -5006
77 | #define NGX_HTTP_TFS_EXIT_LEASE_EXPIRED -5007
78 | #define NGX_HTTP_TFS_EXIT_BINLOG_ERROR -5008
79 | #define NGX_HTTP_TFS_EXIT_NO_REPLICATE -5009
80 | #define NGX_HTTP_TFS_EXIT_BLOCK_BUSY -5010
81 | /* update block information version error */
82 | #define NGX_HTTP_TFS_EXIT_UPDATE_BLOCK_INFO_VERSION_ERROR -5011
83 | /* access mode error */
84 | #define NGX_HTTP_TFS_EXIT_ACCESS_MODE_ERROR -5012
85 | /* play log error */
86 | #define NGX_HTTP_TFS_EXIT_PLAY_LOG_ERROR -5013
87 | /* current nameserver only read */
88 | #define NGX_HTTP_TFS_EXIT_NAMESERVER_ONLY_READ -5014
89 | /* current block already exist */
90 | #define NGX_HTTP_TFS_EXIT_BLOCK_ALREADY_EXIST -5015
91 | /* create block by block id failed */
92 | #define NGX_HTTP_TFS_EXIT_CREATE_BLOCK_BY_ID_ERROR -5016
93 | /* server object not found in XXX */
94 | #define NGX_HTTP_TFS_EIXT_SERVER_OBJECT_NOT_FOUND -5017
95 | /* update relation error */
96 | #define NGX_HTTP_TFS_EXIT_UPDATE_RELATION_ERROR -5018
97 | /* nameserver in safe_mode_time, discard newblk packet */
98 | #define NGX_HTTP_TFS_EXIT_DISCARD_NEWBLK_ERROR -5019
99 |
100 | /* write offset error */
101 | #define NGX_HTTP_TFS_EXIT_WRITE_OFFSET_ERROR -8001
102 | /* read offset error */
103 | #define NGX_HTTP_TFS_EXIT_READ_OFFSET_ERROR -8002
104 | /* block id is zero, fatal error */
105 | #define NGX_HTTP_TFS_EXIT_BLOCKID_ZERO_ERROR -8003
106 | /* block is used up, fatal error */
107 | #define NGX_HTTP_TFS_EXIT_BLOCK_EXHAUST_ERROR -8004
108 | /* need extend too much physcial block when extend block */
109 | #define NGX_HTTP_TFS_EXIT_PHYSICALBLOCK_NUM_ERROR -8005
110 | /* can't find logic block */
111 | #define NGX_HTTP_TFS_EXIT_NO_LOGICBLOCK_ERROR -8006
112 | /* input point is null */
113 | #define NGX_HTTP_TFS_EXIT_POINTER_NULL -8007
114 | /* cat find unused fileid in limited times */
115 | #define NGX_HTTP_TFS_EXIT_CREATE_FILEID_ERROR -8008
116 | /* block id conflict */
117 | #define NGX_HTTP_TFS_EXIT_BLOCKID_CONFLICT_ERROR -8009
118 | /* LogicBlock already Exists */
119 | #define NGX_HTTP_TFS_EXIT_BLOCK_EXIST_ERROR -8010
120 | /* compact block error */
121 | #define NGX_HTTP_TFS_EXIT_COMPACT_BLOCK_ERROR -8011
122 | /* read or write length is less than required */
123 | #define NGX_HTTP_TFS_EXIT_DISK_OPER_INCOMPLETE -8012
124 | /* datafile is NULL / crc / getdata error */
125 | #define NGX_HTTP_TFS_EXIT_DATA_FILE_ERROR -8013
126 | /* too much data file */
127 | #define NGX_HTTP_TFS_EXIT_DATAFILE_OVERLOAD -8014
128 | /* data file is expired */
129 | #define NGX_HTTP_TFS_EXIT_DATAFILE_EXPIRE_ERROR -8015
130 | /* file flag or id error when read file */
131 | #define NGX_HTTP_TFS_EXIT_FILE_INFO_ERROR -8016
132 | /* fileid is same in rename file */
133 | #define NGX_HTTP_TFS_EXIT_RENAME_FILEID_SAME_ERROR -8017
134 | /* file status error(in unlinkfile) */
135 | #define NGX_HTTP_TFS_EXIT_FILE_STATUS_ERROR -8018
136 | /* action is not defined(in unlinkfile) */
137 | #define NGX_HTTP_TFS_EXIT_FILE_ACTION_ERROR -8019
138 | /* file system is not inited */
139 | #define NGX_HTTP_TFS_EXIT_FS_NOTINIT_ERROR -8020
140 | /* file system's bit map conflict */
141 | #define NGX_HTTP_TFS_EXIT_BITMAP_CONFLICT_ERROR -8021
142 | /* physical block is already exist in file system */
143 | #define NGX_HTTP_TFS_EXIT_PHYSIC_UNEXPECT_FOUND_ERROR -8022
144 | #define NGX_HTTP_TFS_EXIT_BLOCK_SETED_ERROR -8023
145 | /* index is loaded when create or load */
146 | #define NGX_HTTP_TFS_EXIT_INDEX_ALREADY_LOADED_ERROR -8024
147 | /* meta not found in index */
148 | #define NGX_HTTP_TFS_EXIT_META_NOT_FOUND_ERROR -8025
149 | /* meta found in index when insert */
150 | #define NGX_HTTP_TFS_EXIT_META_UNEXPECT_FOUND_ERROR -8026
151 | /* require offset is out of index size */
152 | #define NGX_HTTP_TFS_EXIT_META_OFFSET_ERROR -8027
153 | /* bucket size is conflict with before */
154 | #define NGX_HTTP_TFS_EXIT_BUCKET_CONFIGURE_ERROR -8028
155 | /* index already exist when create index */
156 | #define NGX_HTTP_TFS_EXIT_INDEX_UNEXPECT_EXIST_ERROR -8029
157 | /* index is corrupted, and index is created */
158 | #define NGX_HTTP_TFS_EXIT_INDEX_CORRUPT_ERROR -8030
159 | /* ds version error */
160 | #define NGX_HTTP_TFS_EXIT_BLOCK_DS_VERSION_ERROR -8031
161 | /* ns version error */
162 | #define NGX_HTTP_TFS_EXIT_BLOCK_NS_VERSION_ERROR -8332
163 | /* offset is out of physical block size */
164 | #define NGX_HTTP_TFS_EXIT_PHYSIC_BLOCK_OFFSET_ERROR -8033
165 | /* file size is little than fileinfo */
166 | #define NGX_HTTP_TFS_EXIT_READ_FILE_SIZE_ERROR -8034
167 | /* connect to ds fail */
168 | #define NGX_HTTP_TFS_EXIT_DS_CONNECT_ERROR -8035
169 | /* too much block checker */
170 | #define NGX_HTTP_TFS_EXIT_BLOCK_CHECKER_OVERLOAD -8036
171 | /* fallocate is not implement */
172 | #define NGX_HTTP_TFS_EXIT_FALLOCATE_NOT_IMPLEMENT -8037
173 | /* sync file failed */
174 | #define NGX_HTTP_TFS_EXIT_SYNC_FILE_ERROR -8038
175 |
176 | #define NGX_HTTP_TFS_EXIT_SESSION_EXIST_ERROR -9001
177 | #define NGX_HTTP_TFS_EXIT_SESSIONID_INVALID_ERROR -9002
178 | #define NGX_HTTP_TFS_EXIT_APP_NOTEXIST_ERROR -9010
179 | #define NGX_HTTP_TFS_EXIT_APPID_PERMISSION_DENY -9011
180 |
181 | #define NGX_HTTP_TFS_EXIT_SYSTEM_ERROR -10000
182 | #define NGX_HTTP_TFS_EXIT_REGISTER_OPLOG_SYNC_ERROR -12000
183 | #define NGX_HTTP_TFS_EXIT_MAKEDIR_ERROR -13000
184 |
185 | #define NGX_HTTP_TFS_EXIT_UNKNOWN_SQL_ERROR -14000
186 | #define NGX_HTTP_TFS_EXIT_TARGET_EXIST_ERROR -14001
187 | #define NGX_HTTP_TFS_EXIT_PARENT_EXIST_ERROR -14002
188 | #define NGX_HTTP_TFS_EXIT_DELETE_DIR_WITH_FILE_ERROR -14003
189 | #define NGX_HTTP_TFS_EXIT_VERSION_CONFLICT_ERROR -14004
190 | #define NGX_HTTP_TFS_EXIT_NOT_CREATE_ERROR -14005
191 | #define NGX_HTTP_TFS_EXIT_CLUSTER_ID_ERROR -14006
192 | #define NGX_HTTP_TFS_EXIT_FRAG_META_OVERFLOW_ERROR -14007
193 | #define NGX_HTTP_TFS_EXIT_UPDATE_FRAG_INFO_ERROR -14008
194 | #define NGX_HTTP_TFS_EXIT_WRITE_EXIST_POS_ERROR -14009
195 | #define NGX_HTTP_TFS_EXIT_INVALID_FILE_NAME -14010
196 | #define NGX_HTTP_TFS_EXIT_MOVE_TO_SUB_DIR_ERROR -14011
197 | #define NGX_HTTP_TFS_EXIT_OVER_MAX_SUB_DIRS_COUNT -14012
198 | #define NGX_HTTP_TFS_EXIT_OVER_MAX_SUB_DIRS_DEEP -14013
199 | #define NGX_HTTP_TFS_EXIT_OVER_MAX_SUB_FILES_COUNT -14014
200 |
201 | /* server register fail */
202 | #define NGX_HTTP_TFS_EXIT_REGISTER_ERROR -15000
203 | /* server register fail, server is existed */
204 | #define NGX_HTTP_TFS_EXIT_REGISTER_EXIST_ERROR -15001
205 | /* renew lease fail, server is not existed */
206 | #define NGX_HTTP_TFS_EXIT_REGISTER_NOT_EXIST_ERROR -15002
207 | /* table version error */
208 | #define NGX_HTTP_TFS_EXIT_TABLE_VERSION_ERROR -15003
209 | /* bucket id invalid */
210 | #define NGX_HTTP_TFS_EXIT_BUCKET_ID_INVLAID -15004
211 | /* bucket not exist */
212 | #define NGX_HTTP_TFS_EXIT_BUCKET_NOT_EXIST -15005
213 | /* new table not exist */
214 | #define NGX_HTTP_TFS_EXIT_NEW_TABLE_NOT_EXIST -15005
215 | /* new table invalid */
216 | #define NGX_HTTP_TFS_EXIT_NEW_TABLE_INVALID -15005
217 |
218 |
219 | #endif /* _NGX_HTTP_TFS_ERRNO_H_INCLUDED_ */
220 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_json.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #include
8 | #include
9 |
10 |
11 | ngx_http_tfs_json_gen_t *
12 | ngx_http_tfs_json_init(ngx_log_t *log, ngx_pool_t *pool)
13 | {
14 | yajl_gen g;
15 | ngx_http_tfs_json_gen_t *tj_gen;
16 |
17 | g = yajl_gen_alloc(NULL);
18 | if (g == NULL) {
19 | ngx_log_error(NGX_LOG_ERR, log, errno, "alloc yajl_gen failed");
20 | return NULL;
21 | }
22 |
23 | tj_gen = ngx_pcalloc(pool, sizeof(ngx_http_tfs_json_gen_t));
24 | if (tj_gen == NULL) {
25 | return NULL;
26 | }
27 |
28 | yajl_gen_config(g, yajl_gen_beautify, 1);
29 |
30 | tj_gen->gen = g;
31 | tj_gen->pool = pool;
32 | tj_gen->log = log;
33 |
34 | return tj_gen;
35 | }
36 |
37 |
38 | void
39 | ngx_http_tfs_json_destroy(ngx_http_tfs_json_gen_t *tj_gen)
40 | {
41 | if (tj_gen != NULL) {
42 | yajl_gen_free(tj_gen->gen);
43 | }
44 | }
45 |
46 |
47 | ngx_chain_t *
48 | ngx_http_tfs_json_custom_file_info(ngx_http_tfs_json_gen_t *tj_gen,
49 | ngx_http_tfs_custom_meta_info_t *meta_info, uint8_t file_type)
50 | {
51 | size_t size;
52 | u_char time_buf[NGX_HTTP_TFS_GMT_TIME_SIZE];
53 | yajl_gen g;
54 | uint32_t count;
55 | ngx_buf_t *b;
56 | ngx_int_t is_file;
57 | ngx_uint_t i;
58 | ngx_chain_t *cl;
59 | ngx_http_tfs_custom_file_t *file;
60 |
61 | g = tj_gen->gen;
62 | size = 0;
63 |
64 | if (file_type == NGX_HTTP_TFS_CUSTOM_FT_DIR) {
65 | yajl_gen_array_open(g);
66 | }
67 |
68 | for(; meta_info; meta_info = meta_info->next) {
69 | count = meta_info->file_count;
70 | file = meta_info->files;
71 |
72 | for (i = 0; i < count; i++) {
73 | yajl_gen_map_open(g);
74 |
75 | yajl_gen_string(g, (const unsigned char *) "NAME", 4);
76 | yajl_gen_string(g, (const unsigned char *) file[i].file_name.data,
77 | file[i].file_name.len);
78 |
79 | yajl_gen_string(g, (const unsigned char *) "PID", 3);
80 | yajl_gen_integer(g, file[i].file_info.pid);
81 |
82 | yajl_gen_string(g, (const unsigned char *) "ID", 2);
83 | yajl_gen_integer(g, file[i].file_info.id);
84 |
85 | yajl_gen_string(g, (const unsigned char *) "SIZE", 4);
86 | yajl_gen_integer(g, file[i].file_info.size);
87 |
88 | yajl_gen_string(g, (const unsigned char *) "IS_FILE", 7);
89 | if (file_type == NGX_HTTP_TFS_CUSTOM_FT_DIR) {
90 | is_file = (file[i].file_info.pid >> 63) & 0x01;
91 | } else {
92 | is_file = 1;
93 | }
94 | yajl_gen_bool(g, is_file);
95 |
96 | ngx_http_tfs_time(time_buf, file[i].file_info.create_time);
97 | yajl_gen_string(g, (const unsigned char *) "CREATE_TIME", 11);
98 | yajl_gen_string(g, time_buf, NGX_HTTP_TFS_GMT_TIME_SIZE);
99 |
100 | ngx_http_tfs_time(time_buf, file[i].file_info.modify_time);
101 | yajl_gen_string(g, (const unsigned char *) "MODIFY_TIME", 11);
102 | yajl_gen_string(g, time_buf, NGX_HTTP_TFS_GMT_TIME_SIZE);
103 |
104 | yajl_gen_string(g, (const unsigned char *) "VER_NO", 6);
105 | yajl_gen_integer(g, file[i].file_info.ver_no);
106 |
107 | yajl_gen_map_close(g);
108 | }
109 | }
110 |
111 | if (file_type == NGX_HTTP_TFS_CUSTOM_FT_DIR) {
112 | yajl_gen_array_close(g);
113 | }
114 |
115 | cl = ngx_alloc_chain_link(tj_gen->pool);
116 | if (cl == NULL) {
117 | return NULL;
118 | }
119 | cl->next = NULL;
120 |
121 | b = ngx_calloc_buf(tj_gen->pool);
122 | if (b == NULL) {
123 | return NULL;
124 | }
125 |
126 | yajl_gen_get_buf(g, (const unsigned char **) &b->pos, &size);
127 | b->last = b->pos + size;
128 | b->end = b->last;
129 | b->temporary = 1;
130 | b->flush = 1;
131 | /* b->last_buf = 1; */
132 | cl->buf = b;
133 |
134 | return cl;
135 | }
136 |
137 |
138 | ngx_chain_t *
139 | ngx_http_tfs_json_file_name(ngx_http_tfs_json_gen_t *tj_gen,
140 | ngx_str_t *file_name)
141 | {
142 | size_t size;
143 | yajl_gen g;
144 | ngx_buf_t *b;
145 | ngx_chain_t *cl;
146 |
147 | g = tj_gen->gen;
148 | size = 0;
149 |
150 | yajl_gen_map_open(g);
151 | yajl_gen_string(g, (const unsigned char *) "TFS_FILE_NAME", 13);
152 | yajl_gen_string(g, (const unsigned char *) file_name->data, file_name->len);
153 | yajl_gen_map_close(g);
154 |
155 | cl = ngx_alloc_chain_link(tj_gen->pool);
156 | if (cl == NULL) {
157 | return NULL;
158 | }
159 | cl->next = NULL;
160 |
161 | b = ngx_calloc_buf(tj_gen->pool);
162 | if (b == NULL) {
163 | return NULL;
164 | }
165 | yajl_gen_get_buf(g, (const unsigned char **) &b->pos, &size);
166 | b->last = b->pos + size;
167 | b->end = b->last;
168 | b->temporary = 1;
169 | b->flush = 1;
170 | /* b->last_buf = 1; */
171 | cl->buf = b;
172 | return cl;
173 | }
174 |
175 |
176 | ngx_chain_t *
177 | ngx_http_tfs_json_raw_file_info(ngx_http_tfs_json_gen_t *tj_gen,
178 | u_char* file_name, uint32_t block_id,
179 | ngx_http_tfs_raw_file_info_t *file_info)
180 | {
181 | size_t size;
182 | u_char time_buf[NGX_HTTP_TFS_GMT_TIME_SIZE];
183 | yajl_gen g;
184 | ngx_buf_t *b;
185 | ngx_chain_t *cl;
186 |
187 | g = tj_gen->gen;
188 | size = 0;
189 |
190 | yajl_gen_map_open(g);
191 |
192 | yajl_gen_string(g, (const unsigned char *) "FILE_NAME", 9);
193 | yajl_gen_string(g, (const unsigned char *) file_name, 18);
194 |
195 | yajl_gen_string(g, (const unsigned char *) "BLOCK_ID", 8);
196 | yajl_gen_integer(g, block_id);
197 |
198 | yajl_gen_string(g, (const unsigned char *) "FILE_ID", 7);
199 | yajl_gen_integer(g, file_info->id);
200 |
201 | yajl_gen_string(g, (const unsigned char *) "OFFSET", 6);
202 | yajl_gen_integer(g, file_info->offset);
203 |
204 | yajl_gen_string(g, (const unsigned char *) "SIZE", 4);
205 | yajl_gen_integer(g, file_info->size);
206 |
207 | yajl_gen_string(g, (const unsigned char *) "OCCUPY_SIZE", 11);
208 | yajl_gen_integer(g, file_info->u_size);
209 |
210 | ngx_http_tfs_time(time_buf, file_info->modify_time);
211 | yajl_gen_string(g, (const unsigned char *) "MODIFY_TIME", 11);
212 | yajl_gen_string(g, time_buf, NGX_HTTP_TFS_GMT_TIME_SIZE);
213 |
214 | ngx_http_tfs_time(time_buf, file_info->create_time);
215 | yajl_gen_string(g, (const unsigned char *) "CREATE_TIME", 11);
216 | yajl_gen_string(g, time_buf, NGX_HTTP_TFS_GMT_TIME_SIZE);
217 |
218 | yajl_gen_string(g, (const unsigned char *) "STATUS", 6);
219 | yajl_gen_integer(g, file_info->flag);
220 |
221 | yajl_gen_string(g, (const unsigned char *) "CRC", 3);
222 | yajl_gen_integer(g, file_info->crc);
223 |
224 | yajl_gen_map_close(g);
225 |
226 | cl = ngx_alloc_chain_link(tj_gen->pool);
227 | if (cl == NULL) {
228 | return NULL;
229 | }
230 | cl->next = NULL;
231 |
232 | b = ngx_calloc_buf(tj_gen->pool);
233 | if (b == NULL) {
234 | return NULL;
235 | }
236 |
237 | yajl_gen_get_buf(g, (const unsigned char **) &b->pos, &size);
238 |
239 | b->last = b->pos + size;
240 | b->end = b->last;
241 | b->temporary = 1;
242 | b->flush = 1;
243 |
244 | /* b->last_buf = 1; */
245 |
246 | cl->buf = b;
247 |
248 | return cl;
249 | }
250 |
251 |
252 | ngx_chain_t *
253 | ngx_http_tfs_json_appid(ngx_http_tfs_json_gen_t *tj_gen,
254 | uint64_t app_id)
255 | {
256 | size_t size;
257 | yajl_gen g;
258 | ngx_buf_t *b;
259 | ngx_chain_t *cl;
260 |
261 | g = tj_gen->gen;
262 | size = 0;
263 |
264 | u_char str_appid[NGX_INT64_LEN] = {'\0'};
265 | ngx_sprintf(str_appid, "%uL", app_id);
266 |
267 | yajl_gen_map_open(g);
268 | yajl_gen_string(g, (const unsigned char *) "APP_ID", 6);
269 | yajl_gen_string(g, (const unsigned char *) str_appid,
270 | ngx_strlen(str_appid));
271 | yajl_gen_map_close(g);
272 |
273 | cl = ngx_alloc_chain_link(tj_gen->pool);
274 | if (cl == NULL) {
275 | return NULL;
276 | }
277 | cl->next = NULL;
278 |
279 | b = ngx_calloc_buf(tj_gen->pool);
280 | if (b == NULL) {
281 | return NULL;
282 | }
283 |
284 | yajl_gen_get_buf(g, (const unsigned char **) &b->pos, &size);
285 | b->last = b->pos + size;
286 | b->end = b->last;
287 | b->temporary = 1;
288 | b->flush = 1;
289 | /* b->last_buf = 1; */
290 | cl->buf = b;
291 | return cl;
292 | }
293 |
294 |
295 | ngx_chain_t *
296 | ngx_http_tfs_json_file_hole_info(ngx_http_tfs_json_gen_t *tj_gen,
297 | ngx_array_t *file_holes)
298 | {
299 | size_t size;
300 | yajl_gen g;
301 | ngx_buf_t *b;
302 | ngx_uint_t i;
303 | ngx_chain_t *cl;
304 | ngx_http_tfs_file_hole_info_t *file_hole_info;
305 |
306 | g = tj_gen->gen;
307 | size = 0;
308 |
309 | yajl_gen_array_open(g);
310 |
311 | file_hole_info = (ngx_http_tfs_file_hole_info_t *) file_holes->elts;
312 | for(i = 0; i < file_holes->nelts; i++, file_hole_info++) {
313 | yajl_gen_map_open(g);
314 |
315 | yajl_gen_string(g, (const unsigned char *) "OFFSET", 6);
316 | yajl_gen_integer(g, file_hole_info->offset);
317 |
318 | yajl_gen_string(g, (const unsigned char *) "LENGTH", 6);
319 | yajl_gen_integer(g, file_hole_info->length);
320 |
321 | yajl_gen_map_close(g);
322 | }
323 |
324 | yajl_gen_array_close(g);
325 |
326 | cl = ngx_alloc_chain_link(tj_gen->pool);
327 | if (cl == NULL) {
328 | return NULL;
329 | }
330 | cl->next = NULL;
331 |
332 | b = ngx_calloc_buf(tj_gen->pool);
333 | if (b == NULL) {
334 | return NULL;
335 | }
336 |
337 | yajl_gen_get_buf(g, (const unsigned char **) &b->pos, &size);
338 | b->last = b->pos + size;
339 | b->end = b->last;
340 | b->temporary = 1;
341 | b->flush = 1;
342 | /* b->last_buf = 1; */
343 | cl->buf = b;
344 | return cl;
345 | }
346 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_json.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #ifndef _NGX_HTTP_TFS_JSON_H_INCLUDED_
8 | #define _NGX_HTTP_TFS_JSON_H_INCLUDED_
9 |
10 |
11 | #include
12 | #include
13 | #include
14 |
15 |
16 | typedef struct {
17 | yajl_gen gen;
18 | ngx_log_t *log;
19 | ngx_pool_t *pool;
20 | } ngx_http_tfs_json_gen_t;
21 |
22 |
23 | ngx_http_tfs_json_gen_t *ngx_http_tfs_json_init(ngx_log_t *log,
24 | ngx_pool_t *pool);
25 |
26 | void ngx_http_tfs_json_destroy(ngx_http_tfs_json_gen_t *tj_gen);
27 |
28 | ngx_chain_t *ngx_http_tfs_json_custom_file_info(ngx_http_tfs_json_gen_t *tj_gen,
29 | ngx_http_tfs_custom_meta_info_t *info, uint8_t file_type);
30 |
31 | ngx_chain_t *ngx_http_tfs_json_file_name(ngx_http_tfs_json_gen_t *tj_gen,
32 | ngx_str_t *file_name);
33 |
34 | ngx_chain_t *ngx_http_tfs_json_raw_file_info(ngx_http_tfs_json_gen_t *tj_gen,
35 | u_char *file_name, uint32_t block_id,
36 | ngx_http_tfs_raw_file_info_t *file_info);
37 |
38 | ngx_chain_t * ngx_http_tfs_json_appid(ngx_http_tfs_json_gen_t *tj_gen,
39 | uint64_t app_id);
40 | ngx_chain_t * ngx_http_tfs_json_file_hole_info(ngx_http_tfs_json_gen_t *tj_gen,
41 | ngx_array_t *file_holes);
42 |
43 |
44 | #endif /* _NGX_HTTP_TFS_JSON_H_INCLUDED_ */
45 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_local_block_cache.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #include
8 |
9 |
10 | static void ngx_http_tfs_local_block_cache_rbtree_insert_value(
11 | ngx_rbtree_node_t *temp,
12 | ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
13 |
14 | ngx_int_t
15 | ngx_http_tfs_local_block_cache_init_zone(ngx_shm_zone_t *shm_zone, void *data)
16 | {
17 | size_t len;
18 | ngx_http_tfs_local_block_cache_ctx_t *ctx;
19 | ngx_http_tfs_local_block_cache_ctx_t *octx = data;
20 |
21 | ctx = shm_zone->data;
22 |
23 | if (octx) {
24 | ctx->sh = octx->sh;
25 | ctx->shpool = octx->shpool;
26 |
27 | return NGX_OK;
28 | }
29 |
30 | ctx->shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
31 |
32 | if (shm_zone->shm.exists) {
33 | ctx->sh = ctx->shpool->data;
34 |
35 | return NGX_OK;
36 | }
37 |
38 | ctx->sh = ngx_slab_alloc(ctx->shpool,
39 | sizeof(ngx_http_tfs_block_cache_shctx_t));
40 | if (ctx->sh == NULL) {
41 | return NGX_ERROR;
42 | }
43 |
44 | ctx->sh->discard_item_count = NGX_HTTP_TFS_BLOCK_CACHE_DISCARD_ITEM_COUNT;
45 | ctx->sh->hit_count = 0;
46 | ctx->sh->miss_count = 0;
47 |
48 | ctx->shpool->data = ctx->sh;
49 |
50 | ngx_rbtree_init(&ctx->sh->rbtree, &ctx->sh->sentinel,
51 | ngx_http_tfs_local_block_cache_rbtree_insert_value);
52 |
53 | ngx_queue_init(&ctx->sh->queue);
54 |
55 | len = sizeof(" in tfs block cache zone \"\"") + shm_zone->shm.name.len;
56 |
57 | ctx->shpool->log_ctx = ngx_slab_alloc(ctx->shpool, len);
58 | if (ctx->shpool->log_ctx == NULL) {
59 | return NGX_ERROR;
60 | }
61 |
62 | ngx_sprintf(ctx->shpool->log_ctx, " in tfs block cache zone \"%V\"%Z",
63 | &shm_zone->shm.name);
64 |
65 | return NGX_OK;
66 | }
67 |
68 |
69 | void
70 | ngx_http_tfs_local_block_cache_rbtree_insert_value(ngx_rbtree_node_t *temp,
71 | ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
72 | {
73 | ngx_rbtree_node_t **p;
74 | ngx_http_tfs_block_cache_node_t *tbn, *tbnt;
75 |
76 | for ( ;; ) {
77 |
78 | if (node->key < temp->key) {
79 | p = &temp->left;
80 |
81 | } else if (node->key > temp->key) {
82 | p = &temp->right;
83 |
84 | } else { /* node->key == temp->key */
85 | tbn = (ngx_http_tfs_block_cache_node_t *) &node->color;
86 | tbnt = (ngx_http_tfs_block_cache_node_t *) &temp->color;
87 |
88 | p = (ngx_http_tfs_block_cache_cmp(&tbn->key, &tbnt->key) < 0)
89 | ? &temp->left : &temp->right;
90 | }
91 |
92 | if (*p == sentinel) {
93 | break;
94 | }
95 |
96 | temp = *p;
97 | }
98 |
99 | *p = node;
100 | node->parent = temp;
101 | node->left = sentinel;
102 | node->right = sentinel;
103 | ngx_rbt_red(node);
104 | }
105 |
106 |
107 | ngx_int_t
108 | ngx_http_tfs_local_block_cache_lookup(ngx_http_tfs_local_block_cache_ctx_t *ctx,
109 | ngx_pool_t *pool, ngx_log_t *log,
110 | ngx_http_tfs_block_cache_key_t* key,
111 | ngx_http_tfs_block_cache_value_t *value)
112 | {
113 | double hit_ratio;
114 | ngx_int_t rc;
115 | ngx_uint_t hash;
116 | ngx_slab_pool_t *shpool;
117 | ngx_rbtree_node_t *node, *sentinel;
118 | ngx_http_tfs_block_cache_node_t *bcn;
119 |
120 | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, log, 0,
121 | "lookup local block cache, ns addr: %uL, block id: %uD",
122 | key->ns_addr, key->block_id);
123 |
124 | shpool = ctx->shpool;
125 | ngx_shmtx_lock(&shpool->mutex);
126 |
127 | node = ctx->sh->rbtree.root;
128 | sentinel = ctx->sh->rbtree.sentinel;
129 |
130 | hash = ngx_murmur_hash2((u_char*)key, NGX_HTTP_TFS_BLOCK_CACHE_KEY_SIZE);
131 |
132 | while (node != sentinel) {
133 |
134 | if (hash < node->key) {
135 | node = node->left;
136 | continue;
137 | }
138 |
139 | if (hash > node->key) {
140 | node = node->right;
141 | continue;
142 | }
143 |
144 | /* hash == node->key */
145 | bcn = (ngx_http_tfs_block_cache_node_t *) &node->color;
146 | rc = ngx_http_tfs_block_cache_cmp(key, &bcn->key);
147 | if (rc == 0) {
148 | value->ds_count = bcn->count;
149 | value->ds_addrs = ngx_pcalloc(pool,
150 | value->ds_count * sizeof(uint64_t));
151 | if (value->ds_addrs == NULL) {
152 | ngx_shmtx_unlock(&shpool->mutex);
153 | return NGX_ERROR;
154 | }
155 | ngx_memcpy(value->ds_addrs, bcn->data,
156 | value->ds_count * sizeof(uint64_t));
157 | ngx_queue_remove(&bcn->queue);
158 | ngx_queue_insert_head(&ctx->sh->queue, &bcn->queue);
159 | ctx->sh->hit_count++;
160 | if (ctx->sh->hit_count >= NGX_HTTP_TFS_BLOCK_CACHE_STAT_COUNT) {
161 | hit_ratio = 100 * (double)((double)ctx->sh->hit_count
162 | / (double)(ctx->sh->hit_count
163 | + ctx->sh->miss_count));
164 | ngx_log_error(NGX_LOG_INFO, log, 0,
165 | "local block cache hit_ratio: %.2f%%",
166 | hit_ratio);
167 | ctx->sh->hit_count = 0;
168 | ctx->sh->miss_count = 0;
169 | }
170 | ngx_shmtx_unlock(&shpool->mutex);
171 | return NGX_OK;
172 | }
173 | node = (rc < 0) ? node->left : node->right;
174 | }
175 | ctx->sh->miss_count++;
176 | ngx_shmtx_unlock(&shpool->mutex);
177 |
178 | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, log, 0,
179 | "lookup local block cache, "
180 | "ns addr: %uL, block id: %uD not found",
181 | key->ns_addr, key->block_id);
182 |
183 | return NGX_DECLINED;
184 | }
185 |
186 |
187 | ngx_int_t
188 | ngx_http_tfs_local_block_cache_insert(ngx_http_tfs_local_block_cache_ctx_t *ctx,
189 | ngx_log_t *log,
190 | ngx_http_tfs_block_cache_key_t *key,
191 | ngx_http_tfs_block_cache_value_t *value)
192 | {
193 | size_t n;
194 | ngx_slab_pool_t *shpool;
195 | ngx_rbtree_node_t *node;
196 | ngx_http_tfs_block_cache_node_t *bcn;
197 |
198 | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, log, 0,
199 | "insert local block cache, ns addr: %uL, block id: %uD",
200 | key->ns_addr, key->block_id);
201 |
202 | shpool = ctx->shpool;
203 |
204 | ngx_shmtx_lock(&shpool->mutex);
205 |
206 | n = offsetof(ngx_rbtree_node_t, color)
207 | + offsetof(ngx_http_tfs_block_cache_node_t, data)
208 | + value->ds_count * sizeof(uint64_t);
209 |
210 | node = ngx_slab_alloc_locked(shpool, n);
211 | if (node == NULL) { // full, discard
212 | ngx_http_tfs_local_block_cache_discard(ctx);
213 | node = ngx_slab_alloc_locked(shpool, n);
214 | if (node == NULL) {
215 | ngx_shmtx_unlock(&shpool->mutex);
216 | return NGX_ERROR;
217 | }
218 | }
219 |
220 | bcn = (ngx_http_tfs_block_cache_node_t *) &node->color;
221 |
222 | node->key = ngx_murmur_hash2((u_char*)key,
223 | NGX_HTTP_TFS_BLOCK_CACHE_KEY_SIZE);
224 | ngx_memcpy(&bcn->key, key, NGX_HTTP_TFS_BLOCK_CACHE_KEY_SIZE);
225 | bcn->len = (u_char) value->ds_count * sizeof(uint64_t);
226 | bcn->count = value->ds_count;
227 | ngx_memcpy(bcn->data, value->ds_addrs, bcn->len);
228 |
229 | ngx_rbtree_insert(&(ctx->sh->rbtree), node);
230 | ngx_queue_insert_head(&ctx->sh->queue, &bcn->queue);
231 |
232 | ngx_shmtx_unlock(&shpool->mutex);
233 |
234 | return NGX_OK;
235 | }
236 |
237 |
238 | void
239 | ngx_http_tfs_local_block_cache_remove(ngx_http_tfs_local_block_cache_ctx_t *ctx,
240 | ngx_log_t *log, ngx_http_tfs_block_cache_key_t* key)
241 | {
242 | ngx_int_t rc;
243 | ngx_uint_t hash;
244 | ngx_slab_pool_t *shpool;
245 | ngx_rbtree_node_t *node, *sentinel;
246 | ngx_http_tfs_block_cache_node_t *bcn;
247 |
248 | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, log, 0,
249 | "remove local block cache, ns addr: %uL, block id: %uD",
250 | key->ns_addr, key->block_id);
251 |
252 | shpool = ctx->shpool;
253 | ngx_shmtx_lock(&shpool->mutex);
254 |
255 | node = ctx->sh->rbtree.root;
256 | sentinel = ctx->sh->rbtree.sentinel;
257 |
258 | hash = ngx_murmur_hash2((u_char*)key, NGX_HTTP_TFS_BLOCK_CACHE_KEY_SIZE);
259 |
260 | while (node != sentinel) {
261 |
262 | if (hash < node->key) {
263 | node = node->left;
264 | continue;
265 | }
266 |
267 | if (hash > node->key) {
268 | node = node->right;
269 | continue;
270 | }
271 |
272 | /* hash == node->key */
273 | do {
274 | bcn = (ngx_http_tfs_block_cache_node_t *) &node->color;
275 | rc = ngx_http_tfs_block_cache_cmp(key, &bcn->key);
276 | if (rc == 0) {
277 | ngx_rbtree_delete(&ctx->sh->rbtree, node);
278 | ngx_slab_free_locked(ctx->shpool, node);
279 | ngx_queue_remove(&bcn->queue);
280 | ngx_shmtx_unlock(&shpool->mutex);
281 | return;
282 | }
283 | node = (rc < 0) ? node->left : node->right;
284 | } while (node != sentinel && hash == node->key);
285 | break;
286 | }
287 | ngx_shmtx_unlock(&shpool->mutex);
288 |
289 | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, log, 0,
290 | "remove local block cache, "
291 | "ns addr: %uL, block id: %uD not found",
292 | key->ns_addr, key->block_id);
293 |
294 | }
295 |
296 |
297 | void
298 | ngx_http_tfs_local_block_cache_discard(
299 | ngx_http_tfs_local_block_cache_ctx_t *ctx)
300 | {
301 | ngx_uint_t i;
302 | ngx_queue_t *q, *h, *p;
303 | ngx_rbtree_node_t *node;
304 | ngx_http_tfs_block_cache_node_t *bcn;
305 |
306 | h = &ctx->sh->queue;
307 | if (ngx_queue_empty(h)) {
308 | return;
309 | }
310 | q = ngx_queue_last(h);
311 |
312 | for (i = 0; i < ctx->sh->discard_item_count; i++) {
313 | if (q == ngx_queue_sentinel(h)) {
314 | ngx_queue_init(h);
315 | return;
316 | }
317 |
318 | p = ngx_queue_prev(q);
319 |
320 | bcn = ngx_queue_data(q, ngx_http_tfs_block_cache_node_t, queue);
321 |
322 | node = (ngx_rbtree_node_t *)
323 | ((u_char *) bcn - offsetof(ngx_rbtree_node_t, color));
324 |
325 | ngx_rbtree_delete(&ctx->sh->rbtree, node);
326 |
327 | ngx_slab_free_locked(ctx->shpool, node);
328 |
329 | q = p;
330 | }
331 |
332 | q->next = h;
333 | h->prev = q;
334 | }
335 |
336 |
337 | ngx_int_t
338 | ngx_http_tfs_local_block_cache_batch_lookup(
339 | ngx_http_tfs_local_block_cache_ctx_t *ctx,
340 | ngx_pool_t *pool, ngx_log_t *log, ngx_array_t *keys, ngx_array_t *kvs)
341 | {
342 | double hit_ratio;
343 | ngx_int_t rc;
344 | ngx_uint_t i, hash, hit_count;
345 | ngx_slab_pool_t *shpool;
346 | ngx_rbtree_node_t *node, *sentinel;
347 | ngx_http_tfs_block_cache_kv_t *kv;
348 | ngx_http_tfs_block_cache_key_t *key;
349 | ngx_http_tfs_block_cache_node_t *bcn;
350 | ngx_http_tfs_block_cache_value_t *value;
351 |
352 | ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
353 | "batch lookup local block cache, block count: %ui",
354 | keys->nelts);
355 |
356 | key = keys->elts;
357 | shpool = ctx->shpool;
358 | rc = NGX_ERROR;
359 | ngx_shmtx_lock(&shpool->mutex);
360 |
361 | sentinel = ctx->sh->rbtree.sentinel;
362 | hit_count = 0;
363 |
364 | for (i = 0; i < keys->nelts; i++, key++) {
365 | node = ctx->sh->rbtree.root;
366 | hash = ngx_murmur_hash2((u_char*)key,
367 | NGX_HTTP_TFS_BLOCK_CACHE_KEY_SIZE);
368 |
369 | while (node != sentinel) {
370 |
371 | if (hash < node->key) {
372 | node = node->left;
373 | continue;
374 | }
375 |
376 | if (hash > node->key) {
377 | node = node->right;
378 | continue;
379 | }
380 |
381 | /* hash == node->key */
382 | bcn = (ngx_http_tfs_block_cache_node_t *) &node->color;
383 | rc = ngx_http_tfs_block_cache_cmp(key, &bcn->key);
384 | if (rc == 0) {
385 | value = ngx_pcalloc(pool,
386 | sizeof(ngx_http_tfs_block_cache_value_t));
387 | if (value == NULL) {
388 | ngx_shmtx_unlock(&shpool->mutex);
389 | return NGX_ERROR;
390 | }
391 |
392 | value->ds_count = bcn->count;
393 | value->ds_addrs = ngx_pcalloc(pool,
394 | value->ds_count * sizeof(uint64_t));
395 | if (value->ds_addrs == NULL) {
396 | ngx_shmtx_unlock(&shpool->mutex);
397 | return NGX_ERROR;
398 | }
399 | ngx_memcpy(value->ds_addrs, bcn->data,
400 | value->ds_count * sizeof(uint64_t));
401 |
402 | kv = (ngx_http_tfs_block_cache_kv_t *)ngx_array_push(kvs);
403 | kv->key = key;
404 | kv->value = value;
405 |
406 | ngx_queue_remove(&bcn->queue);
407 | ngx_queue_insert_head(&ctx->sh->queue, &bcn->queue);
408 | hit_count++;
409 | break;
410 | }
411 | node = (rc < 0) ? node->left : node->right;
412 | }
413 |
414 | if (node == sentinel) {
415 | ctx->sh->miss_count++;
416 | }
417 | }
418 |
419 | ctx->sh->hit_count += hit_count;
420 | if (ctx->sh->hit_count >= NGX_HTTP_TFS_BLOCK_CACHE_STAT_COUNT) {
421 | hit_ratio = 100 * (double)((double)ctx->sh->hit_count
422 | / (double)(ctx->sh->hit_count
423 | + ctx->sh->miss_count));
424 | ngx_log_error(NGX_LOG_INFO, log, 0,
425 | "local block cache hit_ratio: %.2f%%",
426 | hit_ratio);
427 | ctx->sh->hit_count = 0;
428 | ctx->sh->miss_count = 0;
429 | }
430 |
431 | ngx_shmtx_unlock(&shpool->mutex);
432 |
433 | ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
434 | "batch lookup local block cache, hit_count: %ui",
435 | kvs->nelts);
436 |
437 | /* not all hit */
438 | if (hit_count < keys->nelts) {
439 | rc = NGX_DECLINED;
440 | }
441 |
442 | return rc;
443 | }
444 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_local_block_cache.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #ifndef _NGX_HTTP_TFS_LOCAL_BLOCK_CACHE_H_INCLUDED_
8 | #define _NGX_HTTP_TFS_LOCAL_BLOCK_CACHE_H_INCLUDED_
9 |
10 | #include
11 |
12 |
13 | typedef struct {
14 | u_char color;
15 | u_char dummy;
16 | ngx_queue_t queue;
17 |
18 | ngx_http_tfs_block_cache_key_t key;
19 |
20 | u_char len;
21 | u_short count;
22 | u_char data[1];
23 | } ngx_http_tfs_block_cache_node_t;
24 |
25 |
26 | ngx_int_t ngx_http_tfs_local_block_cache_init_zone(ngx_shm_zone_t *shm_zone,
27 | void *data);
28 |
29 | ngx_int_t ngx_http_tfs_local_block_cache_lookup(
30 | ngx_http_tfs_local_block_cache_ctx_t *ctx,
31 | ngx_pool_t *pool, ngx_log_t *log,
32 | ngx_http_tfs_block_cache_key_t *key,
33 | ngx_http_tfs_block_cache_value_t *value);
34 |
35 | ngx_int_t ngx_http_tfs_local_block_cache_insert(
36 | ngx_http_tfs_local_block_cache_ctx_t *ctx,
37 | ngx_log_t *log, ngx_http_tfs_block_cache_key_t *key,
38 | ngx_http_tfs_block_cache_value_t *value);
39 |
40 | void ngx_http_tfs_local_block_cache_remove(
41 | ngx_http_tfs_local_block_cache_ctx_t *ctx,
42 | ngx_log_t *log, ngx_http_tfs_block_cache_key_t *key);
43 |
44 | void ngx_http_tfs_local_block_cache_discard(
45 | ngx_http_tfs_local_block_cache_ctx_t *ctx);
46 |
47 | ngx_int_t ngx_http_tfs_local_block_cache_batch_lookup(
48 | ngx_http_tfs_local_block_cache_ctx_t *ctx,
49 | ngx_pool_t *pool, ngx_log_t *log, ngx_array_t *keys, ngx_array_t *kvs);
50 |
51 |
52 |
53 | #endif /* _NGX_HTTP_TFS_LOCAL_BLOCK_CACHE_H_INCLUDED_ */
54 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_meta_server_message.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #ifndef _NGX_HTTP_TFS_META_SERVER_MESSAGE_H_INCLUDED_
8 | #define _NGX_HTTP_TFS_META_SERVER_MESSAGE_H_INCLUDED_
9 |
10 |
11 | #include
12 |
13 |
14 | ngx_chain_t *ngx_http_tfs_meta_server_create_message(ngx_http_tfs_t *t);
15 | ngx_int_t ngx_http_tfs_meta_server_parse_message(ngx_http_tfs_t *t);
16 | ngx_http_tfs_inet_t *ngx_http_tfs_select_meta_server(ngx_http_tfs_t *t);
17 |
18 |
19 | #endif /* _NGX_HTTP_TFS_META_SERVER_MESSAGE_H_INCLUDED_ */
20 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_name_server_message.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #ifndef _NGX_HTTP_TFS_NAME_SERVER_MESSAGE_H_INCLUDED_
8 | #define _NGX_HTTP_TFS_NAME_SERVER_MESSAGE_H_INCLUDED_
9 |
10 |
11 | #include
12 |
13 |
14 | ngx_chain_t *ngx_http_tfs_name_server_create_message(ngx_http_tfs_t *t);
15 | ngx_int_t ngx_http_tfs_name_server_parse_message(ngx_http_tfs_t *t);
16 | ngx_int_t ngx_http_tfs_select_name_server(ngx_http_tfs_t *t,
17 | ngx_http_tfs_rcs_info_t *rc_info, ngx_http_tfs_inet_t *addr,
18 | ngx_str_t *addr_text);
19 |
20 |
21 | #endif /* _NGX_HTTP_TFS_NAME_SERVER_MESSAGE_H_INCLUDED_ */
22 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_peer_connection.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #include
8 | #include
9 | #include
10 |
11 |
12 | static ngx_str_t rcs_name = ngx_string("rc server");
13 | static ngx_str_t ns_name = ngx_string("name server");
14 | static ngx_str_t ds_name = ngx_string("data server");
15 | static ngx_str_t rs_name = ngx_string("root server");
16 | static ngx_str_t ms_name = ngx_string("meta server");
17 |
18 |
19 | ngx_int_t
20 | ngx_http_tfs_peer_init(ngx_http_tfs_t *t)
21 | {
22 | char *addr;
23 | uint16_t port;
24 | ngx_http_connection_pool_t *conn_pool;
25 | ngx_http_tfs_peer_connection_t *rc_server, *name_server, *root_server,
26 | *meta_server, *data_server;
27 |
28 | conn_pool = t->main_conf->conn_pool;
29 |
30 | t->tfs_peer_servers = ngx_pcalloc(t->pool,
31 | sizeof(ngx_http_tfs_peer_connection_t) * NGX_HTTP_TFS_SERVER_COUNT);
32 | if (t->tfs_peer_servers == NULL) {
33 | return NGX_ERROR;
34 | }
35 |
36 | name_server = &t->tfs_peer_servers[NGX_HTTP_TFS_NAME_SERVER];
37 | data_server = &t->tfs_peer_servers[NGX_HTTP_TFS_DATA_SERVER];
38 | root_server = &t->tfs_peer_servers[NGX_HTTP_TFS_ROOT_SERVER];
39 | meta_server = &t->tfs_peer_servers[NGX_HTTP_TFS_META_SERVER];
40 |
41 | /* rc server */
42 | if (t->loc_conf->upstream->enable_rcs) {
43 | rc_server = &t->tfs_peer_servers[NGX_HTTP_TFS_RC_SERVER];
44 | rc_server->peer.sockaddr = t->loc_conf->upstream->ups_addr->sockaddr;
45 | rc_server->peer.socklen = t->loc_conf->upstream->ups_addr->socklen;
46 | rc_server->peer.log = t->log;
47 | rc_server->peer.name = &rcs_name;
48 | rc_server->peer.data = conn_pool;
49 | rc_server->peer.get = conn_pool->get_peer;
50 | rc_server->peer.free = conn_pool->free_peer;
51 | rc_server->peer.log_error = NGX_ERROR_ERR;
52 | addr = inet_ntoa(((struct sockaddr_in*)
53 | (rc_server->peer.sockaddr))->sin_addr);
54 | port = ntohs(((struct sockaddr_in*)
55 | (rc_server->peer.sockaddr))->sin_port);
56 | ngx_sprintf(rc_server->peer_addr_text, "%s:%d", addr, port);
57 |
58 | } else {
59 | name_server->peer.sockaddr = t->loc_conf->upstream->ups_addr->sockaddr;
60 | name_server->peer.socklen = t->loc_conf->upstream->ups_addr->socklen;
61 | addr = inet_ntoa(((struct sockaddr_in*)
62 | (name_server->peer.sockaddr))->sin_addr);
63 | port = ntohs(((struct sockaddr_in*)
64 | (name_server->peer.sockaddr))->sin_port);
65 | ngx_sprintf(name_server->peer_addr_text, "%s:%d", addr, port);
66 | }
67 |
68 | /* name server */
69 | name_server->peer.log = t->log;
70 | name_server->peer.name = &ns_name;
71 | name_server->peer.data = conn_pool;
72 | name_server->peer.get = conn_pool->get_peer;
73 | name_server->peer.free = conn_pool->free_peer;
74 | name_server->peer.log_error = NGX_ERROR_ERR;
75 |
76 | /* data server */
77 | data_server->peer.log = t->log;
78 | data_server->peer.name = &ds_name;
79 | data_server->peer.data = conn_pool;
80 | data_server->peer.get = conn_pool->get_peer;
81 | data_server->peer.free = conn_pool->free_peer;
82 | data_server->peer.log_error = NGX_ERROR_ERR;
83 |
84 | if (t->r_ctx.version == 1) {
85 | t->tfs_peer_count = 3;
86 |
87 | } else {
88 | /* root server */
89 | root_server->peer.log = t->log;
90 | root_server->peer.name = &rs_name;
91 | root_server->peer.data = conn_pool;
92 | root_server->peer.get = conn_pool->get_peer;
93 | root_server->peer.free = conn_pool->free_peer;
94 | root_server->peer.log_error = NGX_ERROR_ERR;
95 |
96 | /* meta server */
97 | meta_server->peer.log = t->log;
98 | meta_server->peer.name = &ms_name;
99 | meta_server->peer.data = conn_pool;
100 | meta_server->peer.get = conn_pool->get_peer;
101 | meta_server->peer.free = conn_pool->free_peer;
102 | meta_server->peer.log_error = NGX_ERROR_ERR;
103 |
104 | t->tfs_peer_count = 5;
105 | }
106 |
107 | return NGX_OK;
108 | }
109 |
110 |
111 | static ngx_http_tfs_peer_connection_t *
112 | ngx_http_tfs_select_peer_v1(ngx_http_tfs_t *t)
113 | {
114 | switch (t->r_ctx.action.code) {
115 | case NGX_HTTP_TFS_ACTION_REMOVE_FILE:
116 | switch (t->state) {
117 | case NGX_HTTP_TFS_STATE_REMOVE_START:
118 | t->create_request = ngx_http_tfs_create_rcs_request;
119 | t->process_request_body = ngx_http_tfs_process_rcs;
120 | t->input_filter = NULL;
121 | return &t->tfs_peer_servers[NGX_HTTP_TFS_RC_SERVER];
122 |
123 | case NGX_HTTP_TFS_STATE_REMOVE_GET_GROUP_COUNT:
124 | case NGX_HTTP_TFS_STATE_REMOVE_GET_GROUP_SEQ:
125 | case NGX_HTTP_TFS_STATE_REMOVE_GET_BLK_INFO:
126 | t->create_request = ngx_http_tfs_create_ns_request;
127 | t->process_request_body = ngx_http_tfs_process_ns;
128 | t->input_filter = NULL;
129 | t->retry_handler = NULL;
130 | return &t->tfs_peer_servers[NGX_HTTP_TFS_NAME_SERVER];
131 |
132 | case NGX_HTTP_TFS_STATE_REMOVE_STAT_FILE:
133 | t->create_request = ngx_http_tfs_create_ds_request;
134 | t->process_request_body = ngx_http_tfs_process_ds;
135 | t->input_filter = NULL;
136 | t->retry_handler = ngx_http_tfs_retry_ds;
137 | return &t->tfs_peer_servers[NGX_HTTP_TFS_DATA_SERVER];
138 |
139 | case NGX_HTTP_TFS_STATE_REMOVE_READ_META_SEGMENT:
140 | t->create_request = ngx_http_tfs_create_ds_request;
141 | t->process_request_body = ngx_http_tfs_process_ds_read;
142 | t->input_filter = ngx_http_tfs_process_ds_input_filter;
143 | t->retry_handler = ngx_http_tfs_retry_ds;
144 | return &t->tfs_peer_servers[NGX_HTTP_TFS_DATA_SERVER];
145 |
146 | case NGX_HTTP_TFS_STATE_REMOVE_DELETE_DATA:
147 | t->create_request = ngx_http_tfs_create_ds_request;
148 | t->process_request_body = ngx_http_tfs_process_ds;
149 | t->input_filter = NULL;
150 | t->retry_handler = NULL;
151 | return &t->tfs_peer_servers[NGX_HTTP_TFS_DATA_SERVER];
152 |
153 | case NGX_HTTP_TFS_STATE_REMOVE_DONE:
154 | return t->tfs_peer;
155 |
156 | default:
157 | return NULL;
158 | }
159 | break;
160 | case NGX_HTTP_TFS_ACTION_READ_FILE:
161 | switch (t->state) {
162 | case NGX_HTTP_TFS_STATE_READ_START:
163 | t->create_request = ngx_http_tfs_create_rcs_request;
164 | t->process_request_body = ngx_http_tfs_process_rcs;
165 | t->input_filter = NULL;
166 | return &t->tfs_peer_servers[NGX_HTTP_TFS_RC_SERVER];
167 |
168 | case NGX_HTTP_TFS_STATE_READ_GET_BLK_INFO:
169 | t->create_request = ngx_http_tfs_create_ns_request;
170 | t->process_request_body = ngx_http_tfs_process_ns;
171 | t->input_filter = NULL;
172 | t->retry_handler = ngx_http_tfs_retry_ns;
173 | return &t->tfs_peer_servers[NGX_HTTP_TFS_NAME_SERVER];
174 |
175 | case NGX_HTTP_TFS_STATE_READ_READ_DATA:
176 | t->create_request = ngx_http_tfs_create_ds_request;
177 | t->process_request_body = ngx_http_tfs_process_ds_read;
178 | t->input_filter = ngx_http_tfs_process_ds_input_filter;
179 | t->retry_handler = ngx_http_tfs_retry_ds;
180 | return &t->tfs_peer_servers[NGX_HTTP_TFS_DATA_SERVER];
181 |
182 | case NGX_HTTP_TFS_STATE_READ_DONE:
183 | t->input_filter = NULL;
184 | return t->tfs_peer;
185 |
186 | default:
187 | return NULL;
188 | }
189 | break;
190 | case NGX_HTTP_TFS_ACTION_WRITE_FILE:
191 | switch (t->state) {
192 | case NGX_HTTP_TFS_STATE_WRITE_START:
193 | t->create_request = ngx_http_tfs_create_rcs_request;
194 | t->process_request_body = ngx_http_tfs_process_rcs;
195 | t->input_filter = NULL;
196 | return &t->tfs_peer_servers[NGX_HTTP_TFS_RC_SERVER];
197 |
198 | case NGX_HTTP_TFS_STATE_WRITE_CLUSTER_ID_NS:
199 | case NGX_HTTP_TFS_STATE_WRITE_GET_BLK_INFO:
200 | t->create_request = ngx_http_tfs_create_ns_request;
201 | t->process_request_body = ngx_http_tfs_process_ns;
202 | t->input_filter = NULL;
203 | t->retry_handler = ngx_http_tfs_retry_ns;
204 | return &t->tfs_peer_servers[NGX_HTTP_TFS_NAME_SERVER];
205 |
206 | case NGX_HTTP_TFS_STATE_WRITE_STAT_DUP_FILE:
207 | case NGX_HTTP_TFS_STATE_WRITE_CREATE_FILE_NAME:
208 | case NGX_HTTP_TFS_STATE_WRITE_WRITE_DATA:
209 | case NGX_HTTP_TFS_STATE_WRITE_CLOSE_FILE:
210 | t->create_request = ngx_http_tfs_create_ds_request;
211 | t->process_request_body = ngx_http_tfs_process_ds;
212 | t->input_filter = NULL;
213 | /* FIXME: it's better to retry_ns instead of ds when write failed */
214 | t->retry_handler = ngx_http_tfs_retry_ds;
215 | return &t->tfs_peer_servers[NGX_HTTP_TFS_DATA_SERVER];
216 |
217 | case NGX_HTTP_TFS_STATE_WRITE_DONE:
218 | t->input_filter = NULL;
219 | return t->tfs_peer;
220 | default:
221 | return NULL;
222 | }
223 | break;
224 | case NGX_HTTP_TFS_ACTION_STAT_FILE:
225 | switch (t->state) {
226 | case NGX_HTTP_TFS_STATE_STAT_START:
227 | t->create_request = ngx_http_tfs_create_rcs_request;
228 | t->process_request_body = ngx_http_tfs_process_rcs;
229 | t->input_filter = NULL;
230 | return &t->tfs_peer_servers[NGX_HTTP_TFS_RC_SERVER];
231 |
232 | case NGX_HTTP_TFS_STATE_STAT_GET_BLK_INFO:
233 | t->create_request = ngx_http_tfs_create_ns_request;
234 | t->process_request_body = ngx_http_tfs_process_ns;
235 | t->input_filter = NULL;
236 | t->retry_handler = ngx_http_tfs_retry_ns;
237 | return &t->tfs_peer_servers[NGX_HTTP_TFS_NAME_SERVER];
238 |
239 | case NGX_HTTP_TFS_STATE_STAT_STAT_FILE:
240 | t->create_request = ngx_http_tfs_create_ds_request;
241 | t->process_request_body = ngx_http_tfs_process_ds;
242 | t->input_filter = NULL;
243 | t->retry_handler = ngx_http_tfs_retry_ds;
244 | return &t->tfs_peer_servers[NGX_HTTP_TFS_DATA_SERVER];
245 |
246 | default:
247 | return NULL;
248 | }
249 | break;
250 |
251 | case NGX_HTTP_TFS_ACTION_KEEPALIVE:
252 | t->create_request = ngx_http_tfs_create_rcs_request;
253 | t->process_request_body = ngx_http_tfs_process_rcs;
254 | t->input_filter = NULL;
255 | return &t->tfs_peer_servers[NGX_HTTP_TFS_RC_SERVER];
256 |
257 | default:
258 | break;
259 | }
260 |
261 | return NULL;
262 | }
263 |
264 |
265 | static ngx_http_tfs_peer_connection_t *
266 | ngx_http_tfs_select_peer_v2(ngx_http_tfs_t *t)
267 | {
268 | switch (t->r_ctx.action.code) {
269 | case NGX_HTTP_TFS_ACTION_GET_APPID:
270 | t->create_request = ngx_http_tfs_create_rcs_request;
271 | t->process_request_body = ngx_http_tfs_process_rcs;
272 | return &t->tfs_peer_servers[NGX_HTTP_TFS_RC_SERVER];
273 |
274 | case NGX_HTTP_TFS_ACTION_REMOVE_FILE:
275 | switch (t->state) {
276 | case NGX_HTTP_TFS_STATE_REMOVE_START:
277 | t->create_request = ngx_http_tfs_create_rcs_request;
278 | t->process_request_body = ngx_http_tfs_process_rcs;
279 | return &t->tfs_peer_servers[NGX_HTTP_TFS_RC_SERVER];
280 |
281 | case NGX_HTTP_TFS_STATE_REMOVE_GET_META_TABLE:
282 | t->create_request = ngx_http_tfs_create_rs_request;
283 | t->process_request_body = ngx_http_tfs_process_rs;
284 | return &t->tfs_peer_servers[NGX_HTTP_TFS_ROOT_SERVER];
285 |
286 | case NGX_HTTP_TFS_STATE_REMOVE_NOTIFY_MS:
287 | case NGX_HTTP_TFS_STATE_REMOVE_GET_FRAG_INFO:
288 | t->create_request = ngx_http_tfs_create_ms_request;
289 | t->process_request_body = ngx_http_tfs_process_ms;
290 | return &t->tfs_peer_servers[NGX_HTTP_TFS_META_SERVER];
291 |
292 | case NGX_HTTP_TFS_STATE_REMOVE_GET_GROUP_COUNT:
293 | case NGX_HTTP_TFS_STATE_REMOVE_GET_GROUP_SEQ:
294 | case NGX_HTTP_TFS_STATE_REMOVE_GET_BLK_INFO:
295 | t->create_request = ngx_http_tfs_create_ns_request;
296 | t->process_request_body = ngx_http_tfs_process_ns;
297 | return &t->tfs_peer_servers[NGX_HTTP_TFS_NAME_SERVER];
298 |
299 | case NGX_HTTP_TFS_STATE_REMOVE_DELETE_DATA:
300 | t->create_request = ngx_http_tfs_create_ds_request;
301 | t->process_request_body = ngx_http_tfs_process_ds;
302 | return &t->tfs_peer_servers[NGX_HTTP_TFS_DATA_SERVER];
303 |
304 | case NGX_HTTP_TFS_STATE_REMOVE_DONE:
305 | return t->tfs_peer;
306 | default:
307 | return NULL;
308 | }
309 | break;
310 | case NGX_HTTP_TFS_ACTION_READ_FILE:
311 | switch (t->state) {
312 | case NGX_HTTP_TFS_STATE_READ_START:
313 | t->create_request = ngx_http_tfs_create_rcs_request;
314 | t->process_request_body = ngx_http_tfs_process_rcs;
315 | t->input_filter = NULL;
316 | t->retry_handler = NULL;
317 | return &t->tfs_peer_servers[NGX_HTTP_TFS_RC_SERVER];
318 |
319 | case NGX_HTTP_TFS_STATE_READ_GET_META_TABLE:
320 | t->create_request = ngx_http_tfs_create_rs_request;
321 | t->process_request_body = ngx_http_tfs_process_rs;
322 | t->input_filter = NULL;
323 | t->retry_handler = NULL;
324 | return &t->tfs_peer_servers[NGX_HTTP_TFS_ROOT_SERVER];
325 |
326 | case NGX_HTTP_TFS_STATE_READ_GET_FRAG_INFO:
327 | t->create_request = ngx_http_tfs_create_ms_request;
328 | t->process_request_body = ngx_http_tfs_process_ms;
329 | t->input_filter = NULL;
330 | t->retry_handler = NULL;
331 | return &t->tfs_peer_servers[NGX_HTTP_TFS_META_SERVER];
332 |
333 | case NGX_HTTP_TFS_STATE_READ_GET_BLK_INFO:
334 | t->create_request = ngx_http_tfs_create_ns_request;
335 | t->process_request_body = ngx_http_tfs_process_ns;
336 | t->input_filter = NULL;
337 | t->retry_handler = ngx_http_tfs_retry_ns;
338 | return &t->tfs_peer_servers[NGX_HTTP_TFS_NAME_SERVER];
339 |
340 | case NGX_HTTP_TFS_STATE_READ_READ_DATA:
341 | t->create_request = ngx_http_tfs_create_ds_request;
342 | t->process_request_body = ngx_http_tfs_process_ds_read;
343 | t->input_filter = ngx_http_tfs_process_ds_input_filter;
344 | t->retry_handler = ngx_http_tfs_retry_ds;
345 | return &t->tfs_peer_servers[NGX_HTTP_TFS_DATA_SERVER];
346 |
347 | case NGX_HTTP_TFS_STATE_READ_DONE:
348 | t->input_filter = NULL;
349 | t->retry_handler = NULL;
350 | return t->tfs_peer;
351 | default:
352 | return NULL;
353 | }
354 | break;
355 | case NGX_HTTP_TFS_ACTION_WRITE_FILE:
356 | switch (t->state) {
357 | case NGX_HTTP_TFS_STATE_WRITE_START:
358 | t->create_request = ngx_http_tfs_create_rcs_request;
359 | t->process_request_body = ngx_http_tfs_process_rcs;
360 | t->input_filter = NULL;
361 | t->retry_handler = NULL;
362 | return &t->tfs_peer_servers[NGX_HTTP_TFS_RC_SERVER];
363 |
364 | case NGX_HTTP_TFS_STATE_WRITE_GET_META_TABLE:
365 | t->create_request = ngx_http_tfs_create_rs_request;
366 | t->process_request_body = ngx_http_tfs_process_rs;
367 | t->input_filter = NULL;
368 | t->retry_handler = NULL;
369 | return &t->tfs_peer_servers[NGX_HTTP_TFS_ROOT_SERVER];
370 |
371 | case NGX_HTTP_TFS_STATE_WRITE_CLUSTER_ID_MS:
372 | case NGX_HTTP_TFS_STATE_WRITE_WRITE_MS:
373 | t->create_request = ngx_http_tfs_create_ms_request;
374 | t->process_request_body = ngx_http_tfs_process_ms;
375 | t->input_filter = NULL;
376 | t->retry_handler = NULL;
377 | return &t->tfs_peer_servers[NGX_HTTP_TFS_META_SERVER];
378 |
379 | case NGX_HTTP_TFS_STATE_WRITE_CLUSTER_ID_NS:
380 | case NGX_HTTP_TFS_STATE_WRITE_GET_BLK_INFO:
381 | t->create_request = ngx_http_tfs_create_ns_request;
382 | t->process_request_body = ngx_http_tfs_process_ns;
383 | t->input_filter = NULL;
384 | t->retry_handler = ngx_http_tfs_retry_ns;
385 | return &t->tfs_peer_servers[NGX_HTTP_TFS_NAME_SERVER];
386 |
387 | case NGX_HTTP_TFS_STATE_WRITE_CREATE_FILE_NAME:
388 | case NGX_HTTP_TFS_STATE_WRITE_WRITE_DATA:
389 | case NGX_HTTP_TFS_STATE_WRITE_CLOSE_FILE:
390 | t->create_request = ngx_http_tfs_create_ds_request;
391 | t->process_request_body = ngx_http_tfs_process_ds;
392 | t->input_filter = NULL;
393 | /* FIXME: it's better to retry_ns instead of ds when write failed */
394 | t->retry_handler = ngx_http_tfs_retry_ds;
395 | return &t->tfs_peer_servers[NGX_HTTP_TFS_DATA_SERVER];
396 |
397 | case NGX_HTTP_TFS_STATE_WRITE_DONE:
398 | t->input_filter = NULL;
399 | t->retry_handler = NULL;
400 | return t->tfs_peer;
401 | default:
402 | return NULL;
403 | }
404 | break;
405 | case NGX_HTTP_TFS_ACTION_CREATE_FILE:
406 | case NGX_HTTP_TFS_ACTION_CREATE_DIR:
407 | case NGX_HTTP_TFS_ACTION_LS_FILE:
408 | case NGX_HTTP_TFS_ACTION_LS_DIR:
409 | case NGX_HTTP_TFS_ACTION_MOVE_DIR:
410 | case NGX_HTTP_TFS_ACTION_MOVE_FILE:
411 | case NGX_HTTP_TFS_ACTION_REMOVE_DIR:
412 | switch (t->state) {
413 | case NGX_HTTP_TFS_STATE_ACTION_START:
414 | t->create_request = ngx_http_tfs_create_rcs_request;
415 | t->process_request_body = ngx_http_tfs_process_rcs;
416 | t->input_filter = NULL;
417 | return &t->tfs_peer_servers[NGX_HTTP_TFS_RC_SERVER];
418 |
419 | case NGX_HTTP_TFS_STATE_ACTION_GET_META_TABLE:
420 | t->create_request = ngx_http_tfs_create_rs_request;
421 | t->process_request_body = ngx_http_tfs_process_rs;
422 | t->input_filter = NULL;
423 | return &t->tfs_peer_servers[NGX_HTTP_TFS_ROOT_SERVER];
424 |
425 | case NGX_HTTP_TFS_STATE_ACTION_PROCESS:
426 | t->create_request = ngx_http_tfs_create_ms_request;
427 | if (t->r_ctx.action.code == NGX_HTTP_TFS_ACTION_LS_DIR) {
428 | t->process_request_body = ngx_http_tfs_process_ms_ls_dir;
429 | t->input_filter = ngx_http_tfs_process_ms_input_filter;
430 | } else {
431 | t->process_request_body = ngx_http_tfs_process_ms;
432 | t->input_filter = NULL;
433 | }
434 | return &t->tfs_peer_servers[NGX_HTTP_TFS_META_SERVER];
435 |
436 | case NGX_HTTP_TFS_STATE_ACTION_DONE:
437 | t->input_filter = NULL;
438 | return t->tfs_peer;
439 | default:
440 | return NULL;
441 | }
442 | break;
443 | default:
444 | break;
445 | }
446 |
447 | return NULL;
448 | }
449 |
450 |
451 | ngx_http_tfs_peer_connection_t *
452 | ngx_http_tfs_select_peer(ngx_http_tfs_t *t)
453 | {
454 | if (t->r_ctx.version == 1) {
455 | return ngx_http_tfs_select_peer_v1(t);
456 | }
457 |
458 | if (t->r_ctx.version == 2) {
459 | return ngx_http_tfs_select_peer_v2(t);
460 | }
461 |
462 | return NULL;
463 | }
464 |
465 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_peer_connection.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #ifndef _NGX_HTTP_TFS_PEER_CONNECTION_INCLUDED_
8 | #define _NGX_HTTP_TFS_PEER_CONNECTION_INCLUDED_
9 |
10 |
11 | #include
12 | #include
13 | #include
14 |
15 |
16 | struct ngx_http_tfs_peer_connection_s {
17 | ngx_peer_connection_t peer;
18 | u_char peer_addr_text[24];
19 | ngx_buf_t body_buffer;
20 | ngx_pool_t *pool;
21 | };
22 |
23 |
24 | ngx_int_t ngx_http_tfs_peer_init(ngx_http_tfs_t *t);
25 | ngx_http_tfs_peer_connection_t *ngx_http_tfs_select_peer(ngx_http_tfs_t *t);
26 |
27 |
28 | #endif /* _NGX_HTTP_TFS_PEER_CONNECTION_INCLUDED_ */
29 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_protocol.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #ifndef _NGX_HTTP_TFS_PROTOCOL_H_
8 | #define _NGX_HTTP_TFS_PROTOCOL_H_
9 |
10 |
11 | #define NGX_PACKED __attribute__ ((__packed__))
12 |
13 | #define NGX_HTTP_TFS_PACKET_FLAG 0x4E534654 /* TFSN */
14 | #define NGX_HTTP_TFS_PACKET_VERSION 2
15 |
16 | #define NGX_HTTP_TFS_READ 0
17 | #define NGX_HTTP_TFS_READ_V2 1
18 |
19 | #define NGX_HTTP_TFS_RAW_FILE_INFO_SIZE sizeof(ngx_http_tfs_raw_file_info_t)
20 | #define NGX_HTTP_TFS_READ_V2_TAIL_LEN \
21 | sizeof(ngx_http_tfs_ds_readv2_response_tail_t)
22 |
23 | typedef enum
24 | {
25 | NGX_HTTP_TFS_STATUS_MESSAGE = 1,
26 | NGX_HTTP_TFS_GET_BLOCK_INFO_MESSAGE = 2,
27 | NGX_HTTP_TFS_SET_BLOCK_INFO_MESSAGE = 3,
28 | NGX_HTTP_TFS_CARRY_BLOCK_MESSAGE = 4,
29 | NGX_HTTP_TFS_SET_DATASERVER_MESSAGE = 5,
30 | NGX_HTTP_TFS_UPDATE_BLOCK_INFO_MESSAGE = 6,
31 | NGX_HTTP_TFS_READ_DATA_MESSAGE = 7,
32 | NGX_HTTP_TFS_RESP_READ_DATA_MESSAGE = 8,
33 | NGX_HTTP_TFS_WRITE_DATA_MESSAGE = 9,
34 | NGX_HTTP_TFS_CLOSE_FILE_MESSAGE = 10,
35 | NGX_HTTP_TFS_UNLINK_FILE_MESSAGE = 11,
36 | NGX_HTTP_TFS_REPLICATE_BLOCK_MESSAGE = 12,
37 | NGX_HTTP_TFS_COMPACT_BLOCK_MESSAGE = 13,
38 | NGX_HTTP_TFS_GET_SERVER_STATUS_MESSAGE = 14,
39 | NGX_HTTP_TFS_SHOW_SERVER_INFORMATION_MESSAGE = 15,
40 | NGX_HTTP_TFS_SUSPECT_DATASERVER_MESSAGE = 16,
41 | NGX_HTTP_TFS_FILE_INFO_MESSAGE = 17,
42 | NGX_HTTP_TFS_RESP_FILE_INFO_MESSAGE = 18,
43 | NGX_HTTP_TFS_RENAME_FILE_MESSAGE = 19,
44 | NGX_HTTP_TFS_CLIENT_CMD_MESSAGE = 20,
45 | NGX_HTTP_TFS_CREATE_FILENAME_MESSAGE = 21,
46 | NGX_HTTP_TFS_RESP_CREATE_FILENAME_MESSAGE = 22,
47 | NGX_HTTP_TFS_ROLLBACK_MESSAGE = 23,
48 | NGX_HTTP_TFS_RESP_HEART_MESSAGE = 24,
49 | NGX_HTTP_TFS_RESET_BLOCK_VERSION_MESSAGE = 25,
50 | NGX_HTTP_TFS_BLOCK_FILE_INFO_MESSAGE = 26,
51 | NGX_HTTP_TFS_LEGACY_UNIQUE_FILE_MESSAGE = 27,
52 | NGX_HTTP_TFS_LEGACY_RETRY_COMMAND_MESSAGE = 28,
53 | NGX_HTTP_TFS_NEW_BLOCK_MESSAGE = 29,
54 | NGX_HTTP_TFS_REMOVE_BLOCK_MESSAGE = 30,
55 | NGX_HTTP_TFS_LIST_BLOCK_MESSAGE = 31,
56 | NGX_HTTP_TFS_RESP_LIST_BLOCK_MESSAGE = 32,
57 | NGX_HTTP_TFS_BLOCK_WRITE_COMPLETE_MESSAGE = 33,
58 | NGX_HTTP_TFS_BLOCK_RAW_META_MESSAGE = 34,
59 | NGX_HTTP_TFS_WRITE_RAW_DATA_MESSAGE = 35,
60 | NGX_HTTP_TFS_WRITE_INFO_BATCH_MESSAGE = 36,
61 | NGX_HTTP_TFS_BLOCK_COMPACT_COMPLETE_MESSAGE = 37,
62 | NGX_HTTP_TFS_READ_DATA_MESSAGE_V2 = 38,
63 | NGX_HTTP_TFS_RESP_READ_DATA_MESSAGE_V2 = 39,
64 | NGX_HTTP_TFS_LIST_BITMAP_MESSAGE =40,
65 | NGX_HTTP_TFS_RESP_LIST_BITMAP_MESSAGE = 41,
66 | NGX_HTTP_TFS_RELOAD_CONFIG_MESSAGE = 42,
67 | NGX_HTTP_TFS_SERVER_META_INFO_MESSAGE = 43,
68 | NGX_HTTP_TFS_RESP_SERVER_META_INFO_MESSAGE = 44,
69 | NGX_HTTP_TFS_READ_RAW_DATA_MESSAGE = 45,
70 | NGX_HTTP_TFS_RESP_READ_RAW_DATA_MESSAGE = 46,
71 | NGX_HTTP_TFS_REPLICATE_INFO_MESSAGE = 47,
72 | NGX_HTTP_TFS_ACCESS_STAT_INFO_MESSAGE = 48,
73 | NGX_HTTP_TFS_READ_SCALE_IMAGE_MESSAGE = 49,
74 | NGX_HTTP_TFS_OPLOG_SYNC_MESSAGE = 50,
75 | NGX_HTTP_TFS_OPLOG_SYNC_RESPONSE_MESSAGE = 51,
76 | NGX_HTTP_TFS_MASTER_AND_SLAVE_HEART_MESSAGE = 52,
77 | NGX_HTTP_TFS_MASTER_AND_SLAVE_HEART_RESPONSE_MESSAGE = 53,
78 | NGX_HTTP_TFS_HEARTBEAT_AND_NS_HEART_MESSAGE = 54,
79 | NGX_HTTP_TFS_OWNER_CHECK_MESSAGE = 55,
80 | NGX_HTTP_TFS_GET_BLOCK_LIST_MESSAGE = 56,
81 | NGX_HTTP_TFS_CRC_ERROR_MESSAGE = 57,
82 | NGX_HTTP_TFS_ADMIN_CMD_MESSAGE = 58,
83 | NGX_HTTP_TFS_BATCH_GET_BLOCK_INFO_MESSAGE = 59,
84 | NGX_HTTP_TFS_BATCH_SET_BLOCK_INFO_MESSAGE = 60,
85 | NGX_HTTP_TFS_REMOVE_BLOCK_RESPONSE_MESSAGE = 61,
86 | NGX_HTTP_TFS_READ_DATA_MESSAGE_V3 = 62,
87 | NGX_HTTP_TFS_RESP_READ_DATA_MESSAGE_V3 = 63,
88 | NGX_HTTP_TFS_DUMP_PLAN_MESSAGE = 64,
89 | NGX_HTTP_TFS_DUMP_PLAN_RESPONSE_MESSAGE = 65,
90 | NGX_HTTP_TFS_REQ_RC_LOGIN_MESSAGE = 66,
91 | NGX_HTTP_TFS_RSP_RC_LOGIN_MESSAGE = 67,
92 | NGX_HTTP_TFS_REQ_RC_KEEPALIVE_MESSAGE = 68,
93 | NGX_HTTP_TFS_RSP_RC_KEEPALIVE_MESSAGE = 69,
94 | NGX_HTTP_TFS_REQ_RC_LOGOUT_MESSAGE = 70,
95 | NGX_HTTP_TFS_REQ_RC_RELOAD_MESSAGE = 71,
96 | NGX_HTTP_TFS_GET_DATASERVER_INFORMATION_MESSAGE = 72,
97 | NGX_HTTP_TFS_GET_DATASERVER_INFORMATION_RESPONSE_MESSAGE = 73,
98 | NGX_HTTP_TFS_FILEPATH_ACTION_MESSAGE = 74,
99 | NGX_HTTP_TFS_WRITE_FILEPATH_MESSAGE = 75,
100 | NGX_HTTP_TFS_READ_FILEPATH_MESSAGE = 76,
101 | NGX_HTTP_TFS_RESP_READ_FILEPATH_MESSAGE = 77,
102 | NGX_HTTP_TFS_LS_FILEPATH_MESSAGE = 78,
103 | NGX_HTTP_TFS_RESP_LS_FILEPATH_MESSAGE = 79,
104 | NGX_HTTP_TFS_REQ_RT_UPDATE_TABLE_MESSAGE = 80,
105 | NGX_HTTP_TFS_RSP_RT_UPDATE_TABLE_MESSAGE = 81,
106 | NGX_HTTP_TFS_REQ_RT_MS_KEEPALIVE_MESSAGE = 82,
107 | NGX_HTTP_TFS_RSP_RT_MS_KEEPALIVE_MESSAGE = 83,
108 | NGX_HTTP_TFS_REQ_RT_GET_TABLE_MESSAGE = 84,
109 | NGX_HTTP_TFS_RSP_RT_GET_TABLE_MESSAGE = 85,
110 | NGX_HTTP_TFS_REQ_RT_RS_KEEPALIVE_MESSAGE = 86,
111 | NGX_HTTP_TFS_RSP_RT_RS_KEEPALIVE_MESSAGE = 87,
112 | NGX_HTTP_TFS_LOCAL_PACKET = 500
113 | } ngx_http_tfs_status_msg_e;
114 |
115 |
116 | typedef enum
117 | {
118 | NGX_HTTP_TFS_STATUS_MESSAGE_OK = 0,
119 | NGX_HTTP_TFS_STATUS_MESSAGE_ERROR,
120 | NGX_HTTP_TFS_STATUS_NEED_SEND_BLOCK_INFO,
121 | NGX_HTTP_TFS_STATUS_MESSAGE_PING,
122 | NGX_HTTP_TFS_STATUS_MESSAGE_REMOVE,
123 | NGX_HTTP_TFS_STATUS_MESSAGE_BLOCK_FULL,
124 | NGX_HTTP_TFS_STATUS_MESSAGE_ACCESS_DENIED
125 | } ngx_http_tfs_message_status_t;
126 |
127 |
128 | typedef enum
129 | {
130 | NGX_HTTP_TFS_ACTION_NON = 0,
131 | NGX_HTTP_TFS_ACTION_CREATE_DIR = 1,
132 | NGX_HTTP_TFS_ACTION_CREATE_FILE = 2,
133 | NGX_HTTP_TFS_ACTION_REMOVE_DIR = 3,
134 | NGX_HTTP_TFS_ACTION_REMOVE_FILE = 4,
135 | NGX_HTTP_TFS_ACTION_MOVE_DIR = 5,
136 | NGX_HTTP_TFS_ACTION_MOVE_FILE = 6,
137 | NGX_HTTP_TFS_ACTION_READ_FILE = 7,
138 | NGX_HTTP_TFS_ACTION_LS_DIR = 8,
139 | NGX_HTTP_TFS_ACTION_LS_FILE = 9,
140 | NGX_HTTP_TFS_ACTION_WRITE_FILE = 10,
141 | NGX_HTTP_TFS_ACTION_STAT_FILE = 11,
142 | NGX_HTTP_TFS_ACTION_KEEPALIVE = 12,
143 | NGX_HTTP_TFS_ACTION_GET_APPID = 13,
144 | } ngx_http_tfs_action_e;
145 |
146 |
147 | typedef enum
148 | {
149 | NGX_HTTP_TFS_OPEN_MODE_DEFAULT = 0,
150 | NGX_HTTP_TFS_OPEN_MODE_READ = 1,
151 | NGX_HTTP_TFS_OPEN_MODE_WRITE = 2,
152 | NGX_HTTP_TFS_OPEN_MODE_CREATE = 4,
153 | NGX_HTTP_TFS_OPEN_MODE_NEWBLK = 8,
154 | NGX_HTTP_TFS_OPEN_MODE_NOLEASE = 16,
155 | NGX_HTTP_TFS_OPEN_MODE_STAT = 32,
156 | NGX_HTTP_TFS_OPEN_MODE_LARGE = 64,
157 | NGX_HTTP_TFS_OPEN_MODE_UNLINK = 128
158 | } ngx_http_tfs_open_mode_e;
159 |
160 |
161 | typedef enum
162 | {
163 | NGX_HTTP_TFS_CUSTOM_FT_FILE = 1,
164 | NGX_HTTP_TFS_CUSTOM_FT_DIR,
165 | NGX_HTTP_TFS_CUSTOM_FT_PWRITE_FILE
166 | } ngx_http_tfs_custom_file_type_e;
167 |
168 |
169 | typedef enum
170 | {
171 | NGX_HTTP_TFS_CLIENT_CMD_EXPBLK = 1,
172 | NGX_HTTP_TFS_CLIENT_CMD_LOADBLK,
173 | NGX_HTTP_TFS_CLIENT_CMD_COMPACT,
174 | NGX_HTTP_TFS_CLIENT_CMD_IMMEDIATELY_REPL,
175 | NGX_HTTP_TFS_CLIENT_CMD_REPAIR_GROUP,
176 | NGX_HTTP_TFS_CLIENT_CMD_SET_PARAM,
177 | NGX_HTTP_TFS_CLIENT_CMD_UNLOADBLK,
178 | NGX_HTTP_TFS_CLIENT_CMD_FORCE_DATASERVER_REPORT,
179 | NGX_HTTP_TFS_CLIENT_CMD_ROTATE_LOG,
180 | NGX_HTTP_TFS_CLIENT_CMD_GET_BALANCE_PERCENT,
181 | NGX_HTTP_TFS_CLIENT_CMD_SET_BALANCE_PERCENT
182 | } ngx_http_tfs_ns_ctl_type_e;
183 |
184 |
185 | typedef enum
186 | {
187 | NGX_HTTP_TFS_CLOSE_FILE_MASTER = 100,
188 | NGX_HTTP_TFS_CLOSE_FILE_SLAVER
189 | } ngx_http_tfs_close_mode_e;
190 |
191 |
192 | typedef enum
193 | {
194 | NGX_HTTP_TFS_REMOVE_FILE_MASTER = 0,
195 | NGX_HTTP_TFS_REMOVE_FILE_SLAVER
196 | } ngx_http_tfs_remove_mode_e;
197 |
198 |
199 | typedef enum
200 | {
201 | NGX_HTTP_TFS_FILE_DEFAULT_OPTION = 0,
202 | NGX_HTTP_TFS_FILE_NO_SYNC_LOG = 1,
203 | NGX_HTTP_TFS_FILE_CLOSE_FLAG_WRITE_DATA_FAILED = 2
204 | } ngx_http_tfs_close_option_e;
205 |
206 |
207 | typedef enum
208 | {
209 | NGX_HTTP_TFS_UNLINK_DELETE = 0,
210 | NGX_HTTP_TFS_UNLINK_UNDELETE = 2,
211 | NGX_HTTP_TFS_UNLINK_CONCEAL = 4,
212 | NGX_HTTP_TFS_UNLINK_REVEAL = 6
213 | } ngx_http_tfs_unlink_type_e;
214 |
215 |
216 | typedef enum
217 | {
218 | NGX_HTTP_TFS_FILE_NORMAL = 0,
219 | NGX_HTTP_TFS_FILE_DELETED = 1,
220 | NGX_HTTP_TFS_FILE_INVALID = 2,
221 | NGX_HTTP_TFS_FILE_CONCEAL = 4
222 | } ngx_http_tfs_file_status_e;
223 |
224 |
225 | typedef enum
226 | {
227 | NGX_HTTP_TFS_ACCESS_FORBIDEN = 0,
228 | NGX_HTTP_TFS_ACCESS_READ_ONLY = 1,
229 | NGX_HTTP_TFS_ACCESS_READ_AND_WRITE = 2,
230 | } ngx_http_tfs_access_type_e;
231 |
232 |
233 | typedef struct {
234 | uint32_t flag;
235 | uint32_t len;
236 | uint16_t type;
237 | uint16_t version;
238 | uint64_t id;
239 | uint32_t crc;
240 | } NGX_PACKED ngx_http_tfs_header_t;
241 |
242 |
243 | typedef struct {
244 | int32_t code;
245 | uint32_t error_len;
246 | u_char error_str[];
247 | } NGX_PACKED ngx_http_tfs_status_msg_t;
248 |
249 |
250 | /* root server */
251 | typedef struct {
252 | ngx_http_tfs_header_t header;
253 | uint8_t reserse;
254 | } NGX_PACKED ngx_http_tfs_rs_request_t;
255 |
256 |
257 | typedef struct {
258 | uint64_t version;
259 | uint64_t length;
260 | u_char table[];
261 | } NGX_PACKED ngx_http_tfs_rs_response_t;
262 |
263 |
264 | /* meta server */
265 | typedef struct {
266 | uint32_t block_id;
267 | uint64_t file_id;
268 | int64_t offset;
269 | uint32_t size;
270 | } NGX_PACKED ngx_http_tfs_meta_frag_meta_info_t;
271 |
272 |
273 | typedef struct {
274 | uint32_t cluster_id;
275 |
276 | /* highest is split flag */
277 | uint32_t frag_count;
278 | ngx_http_tfs_meta_frag_meta_info_t frag_meta[];
279 | } NGX_PACKED ngx_http_tfs_meta_frag_info_t;
280 |
281 |
282 | typedef struct {
283 | ngx_http_tfs_header_t header;
284 | uint64_t app_id;
285 | uint64_t user_id;
286 | uint32_t file_len;
287 | u_char file_path_s[];
288 | } NGX_PACKED ngx_http_tfs_ms_base_msg_header_t;
289 |
290 |
291 | typedef struct {
292 | ngx_http_tfs_header_t header;
293 | uint64_t app_id;
294 | uint64_t user_id;
295 | int64_t pid;
296 | uint32_t file_len;
297 | u_char file_path[];
298 | } NGX_PACKED ngx_http_tfs_ms_ls_msg_header_t;
299 |
300 |
301 | typedef struct {
302 | /* ignore header */
303 | uint8_t still_have;
304 | uint32_t count;
305 | } NGX_PACKED ngx_http_tfs_ms_ls_response_t;
306 |
307 |
308 | typedef struct {
309 | /* ignore header */
310 | uint8_t still_have;
311 | ngx_http_tfs_meta_frag_info_t frag_info;
312 | } NGX_PACKED ngx_http_tfs_ms_read_response_t;
313 |
314 |
315 | /* rc server */
316 | typedef struct {
317 | ngx_http_tfs_header_t header;
318 | uint32_t appkey_len;
319 | u_char appkey[];
320 | /* uint64_t app_ip */
321 | } NGX_PACKED ngx_http_tfs_rcs_login_msg_header_t;
322 |
323 |
324 | /* name server */
325 | typedef struct {
326 | ngx_http_tfs_header_t header;
327 | uint32_t mode;
328 |
329 | uint32_t block_id;
330 | uint32_t fs_count;
331 | u_char fs_id[];
332 | } NGX_PACKED ngx_http_tfs_ns_block_info_request_t;
333 |
334 |
335 | typedef struct {
336 | ngx_http_tfs_header_t header;
337 | uint32_t mode;
338 |
339 | uint32_t block_count;
340 | uint32_t block_ids[];
341 | } NGX_PACKED ngx_http_tfs_ns_batch_block_info_request_t;
342 |
343 |
344 | typedef struct {
345 | /* ignore header */
346 | uint32_t block_id;
347 | uint32_t ds_count;
348 | uint64_t ds_addrs[];
349 | } NGX_PACKED ngx_http_tfs_ns_block_info_response_t;
350 |
351 |
352 | typedef struct {
353 | /* ignore header */
354 | uint32_t block_count;
355 | } NGX_PACKED ngx_http_tfs_ns_batch_block_info_response_t;
356 |
357 |
358 | typedef struct {
359 | ngx_http_tfs_header_t header;
360 |
361 | int32_t cmd;
362 | int64_t value1;
363 | int32_t value2;
364 | int32_t value3;
365 | int64_t value4;
366 | } NGX_PACKED ngx_http_tfs_ns_ctl_request_t;
367 |
368 |
369 | /* data server */
370 | typedef struct {
371 | ngx_http_tfs_header_t base_header;
372 | uint32_t block_id;
373 | uint64_t file_id;
374 | } NGX_PACKED ngx_http_tfs_ds_msg_header_t;
375 |
376 |
377 | typedef struct {
378 | ngx_http_tfs_ds_msg_header_t header;
379 | int32_t offset;
380 | uint32_t length;
381 | uint8_t flag;
382 | } NGX_PACKED ngx_http_tfs_ds_read_request_t;
383 |
384 |
385 | typedef struct {
386 | ngx_http_tfs_header_t header;
387 | int32_t data_len;
388 | } NGX_PACKED ngx_http_tfs_ds_read_response_t;
389 |
390 |
391 | typedef struct {
392 | /* ignore header */
393 | uint32_t block_id;
394 | uint64_t file_id;
395 | uint64_t file_number;
396 | } NGX_PACKED ngx_http_tfs_ds_cf_reponse_t;
397 |
398 |
399 | typedef struct {
400 | ngx_http_tfs_ds_msg_header_t header;
401 | int32_t offset;
402 | uint32_t length;
403 | int32_t is_server;
404 | uint64_t file_number;
405 | } NGX_PACKED ngx_http_tfs_ds_write_request_t;
406 |
407 |
408 | typedef struct {
409 | ngx_http_tfs_ds_msg_header_t header;
410 | uint32_t server_mode;
411 | } NGX_PACKED ngx_http_tfs_ds_unlink_request_t;
412 |
413 |
414 | typedef struct {
415 | ngx_http_tfs_ds_msg_header_t header;
416 | int32_t mode;
417 | uint32_t crc;
418 | uint64_t file_number;
419 | } NGX_PACKED ngx_http_tfs_ds_close_request_t;
420 |
421 |
422 | typedef struct {
423 | int64_t pid;
424 | int64_t id;
425 | uint32_t create_time;
426 | uint32_t modify_time;
427 | uint64_t size;
428 | uint16_t ver_no;
429 | } NGX_PACKED ngx_http_tfs_custom_file_info_t;
430 |
431 |
432 | typedef struct {
433 | uint64_t id;
434 | int32_t offset;
435 | int32_t size;
436 | int32_t u_size;
437 | int32_t modify_time;
438 | int32_t create_time;
439 | int32_t flag;
440 | uint32_t crc;
441 | } NGX_PACKED ngx_http_tfs_raw_file_info_t;
442 |
443 |
444 | typedef struct {
445 | ngx_http_tfs_ds_msg_header_t header;
446 | uint32_t mode;
447 | } NGX_PACKED ngx_http_tfs_ds_stat_request_t;
448 |
449 |
450 | typedef struct {
451 | /* ignore header */
452 | uint32_t data_len;
453 | ngx_http_tfs_raw_file_info_t file_info;
454 | } NGX_PACKED ngx_http_tfs_ds_stat_response_t;
455 |
456 |
457 | typedef struct {
458 | uint32_t file_info_len;
459 | ngx_http_tfs_raw_file_info_t file_info;
460 | } NGX_PACKED ngx_http_tfs_ds_readv2_response_tail_t;
461 |
462 |
463 | typedef struct {
464 | uint32_t count; /* segment count */
465 |
466 | /* total size of all data segments */
467 | uint64_t size;
468 | u_char reserve[64];
469 | } NGX_PACKED ngx_http_tfs_segment_head_t;
470 |
471 |
472 | typedef struct {
473 | /* ignore header */
474 | int32_t data_len;
475 | ngx_http_tfs_segment_head_t seg_head;
476 | uint32_t file_info_len;
477 | ngx_http_tfs_raw_file_info_t file_info;
478 | } NGX_PACKED ngx_http_tfs_ds_sp_readv2_response_t;
479 |
480 |
481 | typedef struct {
482 | ngx_str_t file_name;
483 | ngx_http_tfs_custom_file_info_t file_info;
484 | } ngx_http_tfs_custom_file_t;
485 |
486 |
487 | typedef struct ngx_http_tfs_custom_meta_info_s ngx_http_tfs_custom_meta_info_t;
488 |
489 | struct ngx_http_tfs_custom_meta_info_s {
490 | uint32_t file_count;
491 | uint32_t rest_file_count;
492 | uint32_t file_index;
493 | ngx_http_tfs_custom_file_t *files;
494 | ngx_http_tfs_custom_meta_info_t *next;
495 | };
496 |
497 |
498 | typedef struct {
499 | uint64_t offset;
500 | uint64_t length;
501 | } ngx_http_tfs_file_hole_info_t;
502 |
503 |
504 |
505 |
506 | #endif /* _NGX_HTTP_TFS_PROTOCOL_H_ */
507 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_raw_fsname.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #include
8 |
9 | #define NGX_HTTP_TFS_KEY_MASK_LEN 10 /* strlen(NGX_HTTP_TFS_KEY_MASK) */
10 |
11 | static const u_char* NGX_HTTP_TFS_KEY_MASK = (u_char *)"Taobao-inc";
12 |
13 | static const u_char enc_table[] = "0JoU8EaN3xf19hIS2d.6p"
14 | "ZRFBYurMDGw7K5m4CyXsbQjg_vTOAkcHVtzqWilnLPe";
15 |
16 | static const u_char dec_table[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
17 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,0,0,11,16,8, \
18 | 36,34,19,32,4,12,0,0,0,0,0,0,0,49,24,37,29,5,23,30,52,14,1,33,61,28,7, \
19 | 48,62,42,22,15,47,3,53,57,39,25,21,0,0,0,0,45,0,6,41,51,17,63,10,44,13,\
20 | 58,43,50,59,35,60,2,20,56,27,40,54,26,46,31,9,38,55,0,0,0,0,0,0,0,0,0, \
21 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
22 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
23 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
24 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
25 |
26 |
27 | static void
28 | xor_mask(const u_char* source, const int32_t len, u_char* target)
29 | {
30 | int32_t i = 0;
31 |
32 | for (; i < len; i++) {
33 | target[i] =
34 | source[i] ^ NGX_HTTP_TFS_KEY_MASK[i % NGX_HTTP_TFS_KEY_MASK_LEN];
35 | }
36 | }
37 |
38 |
39 | ngx_int_t
40 | ngx_http_tfs_raw_fsname_parse(ngx_str_t *tfs_name, ngx_str_t *suffix,
41 | ngx_http_tfs_raw_fsname_t* fsname)
42 | {
43 | ngx_uint_t suffix_len;
44 |
45 | if (fsname != NULL && tfs_name->data != NULL && tfs_name->data[0] != '\0') {
46 | ngx_memzero(fsname, sizeof(ngx_http_tfs_raw_fsname_t));
47 | fsname->file_type = ngx_http_tfs_raw_fsname_check_file_type(tfs_name);
48 | if (fsname->file_type == NGX_HTTP_TFS_INVALID_FILE_TYPE) {
49 | return NGX_ERROR;
50 | } else {
51 | /* if two suffix exist, check consistency */
52 | if (suffix != NULL
53 | && suffix->data != NULL
54 | && tfs_name->len > NGX_HTTP_TFS_FILE_NAME_LEN)
55 | {
56 | suffix_len = tfs_name->len - NGX_HTTP_TFS_FILE_NAME_LEN;
57 | if (suffix->len != suffix_len) {
58 | return NGX_ERROR;
59 | }
60 | suffix_len = suffix->len > suffix_len ? suffix_len :suffix->len;
61 | if (ngx_memcmp(suffix->data,
62 | tfs_name->data + NGX_HTTP_TFS_FILE_NAME_LEN,
63 | suffix_len))
64 | {
65 | return NGX_ERROR;
66 | }
67 | }
68 |
69 | ngx_http_tfs_raw_fsname_decode(tfs_name->data + 2,
70 | (u_char*) &(fsname->file));
71 | if (suffix != NULL && suffix->data == NULL) {
72 | suffix->data = tfs_name->data + NGX_HTTP_TFS_FILE_NAME_LEN;
73 | suffix->len = tfs_name->len - NGX_HTTP_TFS_FILE_NAME_LEN;
74 | }
75 |
76 | ngx_http_tfs_raw_fsname_set_suffix(fsname, suffix);
77 | if (fsname->cluster_id == 0) {
78 | fsname->cluster_id = tfs_name->data[1] - '0';
79 | }
80 | }
81 | }
82 |
83 | return NGX_OK;
84 | }
85 |
86 |
87 | u_char*
88 | ngx_http_tfs_raw_fsname_get_name(ngx_http_tfs_raw_fsname_t* fsname,
89 | unsigned large_flag, ngx_int_t simple_name)
90 | {
91 | if (fsname != NULL) {
92 | if (simple_name) {
93 | /* zero suffix */
94 | fsname->file.suffix = 0;
95 | }
96 |
97 | ngx_http_tfs_raw_fsname_encode((u_char*) &(fsname->file),
98 | fsname->file_name + 2);
99 |
100 | if (large_flag) {
101 | fsname->file_name[0] = NGX_HTTP_TFS_LARGE_FILE_KEY_CHAR;
102 |
103 | } else {
104 | fsname->file_name[0] = NGX_HTTP_TFS_SMALL_FILE_KEY_CHAR;
105 | }
106 | fsname->file_name[1] = (u_char) ('0' + fsname->cluster_id);
107 | fsname->file_name[NGX_HTTP_TFS_FILE_NAME_LEN] = '\0';
108 |
109 | return fsname->file_name;
110 | }
111 |
112 | return NULL;
113 | }
114 |
115 |
116 | ngx_http_tfs_raw_file_type_e
117 | ngx_http_tfs_raw_fsname_check_file_type(ngx_str_t *tfs_name)
118 | {
119 | ngx_http_tfs_raw_file_type_e file_type = NGX_HTTP_TFS_INVALID_FILE_TYPE;
120 |
121 | if (tfs_name->data != NULL
122 | && tfs_name->len >= NGX_HTTP_TFS_FILE_NAME_LEN)
123 | {
124 | if (tfs_name->data[0] == NGX_HTTP_TFS_LARGE_FILE_KEY_CHAR) {
125 | file_type = NGX_HTTP_TFS_LARGE_FILE_TYPE;
126 |
127 | } else if (tfs_name->data[0] == NGX_HTTP_TFS_SMALL_FILE_KEY_CHAR) {
128 | file_type = NGX_HTTP_TFS_SMALL_FILE_TYPE;
129 | }
130 | }
131 |
132 | return file_type;
133 | }
134 |
135 |
136 | void
137 | ngx_http_tfs_raw_fsname_encode(u_char *input, u_char *output)
138 | {
139 | u_char buffer[NGX_HTTP_TFS_FILE_NAME_EXCEPT_SUFFIX_LEN];
140 | uint32_t value;
141 | ngx_uint_t i, k;
142 |
143 | k = 0;
144 |
145 | if (input != NULL && output != NULL) {
146 | xor_mask(input, NGX_HTTP_TFS_FILE_NAME_EXCEPT_SUFFIX_LEN, buffer);
147 | for (i = 0; i < NGX_HTTP_TFS_FILE_NAME_EXCEPT_SUFFIX_LEN; i += 3) {
148 | value = ((buffer[i] << 16) & 0xff0000)
149 | + ((buffer[i + 1] << 8) & 0xff00) + (buffer[i + 2] & 0xff);
150 | output[k++] = enc_table[value >> 18];
151 | output[k++] = enc_table[(value >> 12) & 0x3f];
152 | output[k++] = enc_table[(value >> 6) & 0x3f];
153 | output[k++] = enc_table[value & 0x3f];
154 | }
155 | }
156 | }
157 |
158 |
159 | void
160 | ngx_http_tfs_raw_fsname_decode(u_char *input, u_char *output)
161 | {
162 | u_char buffer[NGX_HTTP_TFS_FILE_NAME_EXCEPT_SUFFIX_LEN];
163 | uint32_t value;
164 | ngx_uint_t i, k;
165 |
166 | k = 0;
167 |
168 | if (input != NULL && output != NULL) {
169 | for (i = 0; i < NGX_HTTP_TFS_FILE_NAME_LEN - 2; i += 4) {
170 | value = (dec_table[input[i] & 0xff] << 18)
171 | + (dec_table[input[i + 1] & 0xff] << 12)
172 | + (dec_table[input[i + 2] & 0xff] << 6)
173 | + dec_table[input[i + 3] & 0xff];
174 | buffer[k++] = (u_char) ((value >> 16) & 0xff);
175 | buffer[k++] = (u_char) ((value >> 8) & 0xff);
176 | buffer[k++] = (u_char) (value & 0xff);
177 | }
178 | xor_mask(buffer, NGX_HTTP_TFS_FILE_NAME_EXCEPT_SUFFIX_LEN, output);
179 | }
180 | }
181 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_raw_fsname.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #ifndef _NGX_HTTP_TFS_RAW_FSNAME_H_INCLUDED_
8 | #define _NGX_HTTP_TFS_RAW_FSNAME_H_INCLUDED_
9 |
10 |
11 | #include
12 | #include
13 | #include
14 |
15 |
16 | typedef enum
17 | {
18 | NGX_HTTP_TFS_INVALID_FILE_TYPE = 0,
19 | NGX_HTTP_TFS_SMALL_FILE_TYPE,
20 | NGX_HTTP_TFS_LARGE_FILE_TYPE
21 | } ngx_http_tfs_raw_file_type_e;
22 |
23 |
24 | typedef struct {
25 | uint32_t block_id;
26 | uint32_t seq_id;
27 | uint32_t suffix;
28 | } ngx_http_tfs_raw_fsname_filebits_t;
29 |
30 |
31 | typedef struct {
32 | u_char file_name[NGX_HTTP_TFS_FILE_NAME_BUFF_LEN];
33 |
34 | ngx_http_tfs_raw_fsname_filebits_t file;
35 |
36 | uint32_t cluster_id;
37 | ngx_http_tfs_raw_file_type_e file_type;
38 | } ngx_http_tfs_raw_fsname_t;
39 |
40 |
41 | #define ngx_http_tfs_raw_fsname_set_suffix(fsname, fs_suffix) do { \
42 | if ((fs_suffix != NULL) \
43 | && (fs_suffix->data != NULL) \
44 | && (fs_suffix->len != 0)) \
45 | { \
46 | fsname->file.suffix = ngx_http_tfs_raw_fsname_hash(fs_suffix->data, \
47 | fs_suffix->len); \
48 | } \
49 | } while(0)
50 |
51 |
52 | #define ngx_http_tfs_raw_fsname_set_file_id(fsname, id) \
53 | fsname->file.suffix = (id >> 32); \
54 | fsname->file.seq_id = (id & 0xFFFFFFFF)
55 |
56 |
57 | #define ngx_http_tfs_raw_fsname_get_file_id(fsname) \
58 | ((((uint64_t)(fsname.file.suffix)) << 32) | fsname.file.seq_id)
59 |
60 |
61 | #define ngx_http_tfs_group_seq_match(block_id, group_count, group_seq) \
62 | ((block_id % group_count) == (ngx_uint_t) group_seq)
63 |
64 |
65 | ngx_http_tfs_raw_file_type_e ngx_http_tfs_raw_fsname_check_file_type(
66 | ngx_str_t *tfs_name);
67 | void ngx_http_tfs_raw_fsname_encode(u_char * input, u_char *output);
68 | void ngx_http_tfs_raw_fsname_decode(u_char * input, u_char *output);
69 |
70 | ngx_int_t ngx_http_tfs_raw_fsname_parse(ngx_str_t *tfs_name, ngx_str_t *suffix,
71 | ngx_http_tfs_raw_fsname_t *fsname);
72 | u_char* ngx_http_tfs_raw_fsname_get_name(ngx_http_tfs_raw_fsname_t *fsname,
73 | unsigned large_flag, ngx_int_t no_suffix);
74 |
75 |
76 | #endif /* _NGX_HTTP_TFS_RAW_FSNAME_H_INCLUDED_ */
77 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_rc_server_info.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #include
8 |
9 |
10 | static void ngx_http_tfs_rcs_rbtree_insert_value(ngx_rbtree_node_t *temp,
11 | ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
12 |
13 |
14 | ngx_http_tfs_rcs_info_t *
15 | ngx_http_tfs_rcs_lookup(ngx_http_request_t *r, ngx_http_tfs_rc_ctx_t *ctx,
16 | ngx_str_t appkey)
17 | {
18 | ngx_int_t rc;
19 | ngx_uint_t hash;
20 | ngx_rbtree_node_t *node, *sentinel;
21 | ngx_http_tfs_rcs_info_t *tr;
22 |
23 | node = ctx->sh->rbtree.root;
24 | sentinel = ctx->sh->rbtree.sentinel;
25 |
26 | hash = ngx_murmur_hash2(appkey.data, appkey.len);
27 |
28 | while (node != sentinel) {
29 |
30 | if (hash < node->key) {
31 | node = node->left;
32 | continue;
33 | }
34 |
35 | if (hash > node->key) {
36 | node = node->right;
37 | continue;
38 | }
39 |
40 | /* hash == node->key */
41 |
42 | tr = (ngx_http_tfs_rcs_info_t *) &node->color;
43 | rc = ngx_memn2cmp(appkey.data, tr->appkey.data, appkey.len,
44 | tr->appkey.len);
45 |
46 | if (rc == 0) {
47 | ngx_queue_remove(&tr->queue);
48 | ngx_queue_insert_head(&ctx->sh->queue, &tr->queue);
49 |
50 | return tr;
51 | }
52 |
53 | node = (rc < 0) ? node->left : node->right;
54 | }
55 |
56 | return NULL;
57 | }
58 |
59 |
60 | void
61 | ngx_http_tfs_rc_server_destroy_node(ngx_http_tfs_rc_ctx_t *rc_ctx,
62 | ngx_http_tfs_rcs_info_t *rc_info_node)
63 | {
64 | ngx_str_t *block_cache_info;
65 | ngx_uint_t i, j;
66 | ngx_rbtree_node_t *node;
67 | ngx_http_tfs_group_info_t *group_info;
68 | ngx_http_tfs_logical_cluster_t *logical_cluster;
69 | ngx_http_tfs_physical_cluster_t *physical_cluster;
70 | ngx_http_tfs_cluster_group_info_t *cluster_group_info;
71 | ngx_http_tfs_tair_server_addr_info_t *dup_server_info;
72 |
73 | if (rc_info_node == NULL) {
74 | return;
75 | }
76 |
77 | if (rc_info_node->session_id.len <= 0
78 | || rc_info_node->session_id.data == NULL)
79 | {
80 | goto last_free;
81 | }
82 |
83 | ngx_slab_free_locked(rc_ctx->shpool, rc_info_node->session_id.data);
84 | ngx_str_null(&rc_info_node->session_id);
85 |
86 | if (rc_info_node->rc_servers_count <= 0
87 | || rc_info_node->rc_servers == NULL)
88 | {
89 | goto last_free;
90 | }
91 |
92 | ngx_slab_free_locked(rc_ctx->shpool, rc_info_node->rc_servers);
93 | block_cache_info = &rc_info_node->remote_block_cache_info;
94 | rc_info_node->rc_servers = NULL;
95 |
96 | logical_cluster = rc_info_node->logical_clusters;
97 | for (i = 0; i < rc_info_node->logical_cluster_count; i++) {
98 | if (logical_cluster->need_duplicate) {
99 | dup_server_info = &logical_cluster->dup_server_info;
100 |
101 | for (i = 0; i < NGX_HTTP_TFS_TAIR_SERVER_ADDR_PART_COUNT; i++) {
102 | if (dup_server_info->server[i].data == NULL) {
103 | goto last_free;
104 | }
105 | ngx_slab_free_locked(rc_ctx->shpool,
106 | dup_server_info->server[i].data);
107 | ngx_str_null(&dup_server_info->server[i]);
108 | }
109 | }
110 |
111 | physical_cluster = logical_cluster->rw_clusters;
112 | for (j = 0; j < logical_cluster->rw_cluster_count; j++) {
113 | if (physical_cluster[j].cluster_id_text.len <= 0
114 | || physical_cluster[j].cluster_id_text.data == NULL)
115 | {
116 | goto last_free;
117 | }
118 | ngx_slab_free_locked(rc_ctx->shpool,
119 | physical_cluster[j].cluster_id_text.data);
120 | ngx_str_null(&physical_cluster[j].cluster_id_text);
121 | physical_cluster[j].cluster_id = 0;
122 |
123 | if (physical_cluster[j].ns_vip_text.len <= 0
124 | || physical_cluster[j].ns_vip_text.data == NULL)
125 | {
126 | goto last_free;
127 | }
128 | ngx_slab_free_locked(rc_ctx->shpool,
129 | physical_cluster[j].ns_vip_text.data);
130 | ngx_str_null(&physical_cluster[j].ns_vip_text);
131 | physical_cluster++;
132 | }
133 | logical_cluster++;
134 | }
135 |
136 | if (block_cache_info->len <= 0 || block_cache_info->data == NULL)
137 | {
138 | goto last_free;
139 | }
140 |
141 | ngx_slab_free_locked(rc_ctx->shpool, block_cache_info->data);
142 | ngx_str_null(&rc_info_node->remote_block_cache_info);
143 |
144 | cluster_group_info = rc_info_node->unlink_clusters;
145 | for (i = 0; i < rc_info_node->unlink_cluster_count; i++) {
146 | for (j = 0; j < cluster_group_info[i].info_count; j++) {
147 | group_info = &cluster_group_info[i].group_info[j];
148 | if (group_info->ns_vip_text.len <= 0
149 | || group_info->ns_vip_text.data == NULL)
150 | {
151 | break;
152 | }
153 | ngx_slab_free_locked(rc_ctx->shpool, group_info->ns_vip_text.data);
154 | ngx_str_null(&group_info->ns_vip_text);
155 | }
156 | }
157 |
158 | last_free:
159 | node = (ngx_rbtree_node_t *)
160 | ((u_char *) rc_info_node - offsetof(ngx_rbtree_node_t, color));
161 | ngx_slab_free_locked(rc_ctx->shpool, node);
162 | }
163 |
164 |
165 | void
166 | ngx_http_tfs_rc_server_expire(ngx_http_tfs_rc_ctx_t *ctx)
167 | {
168 | ngx_queue_t *q, *kp_q;
169 | ngx_rbtree_node_t *node;
170 | ngx_http_tfs_rcs_info_t *rc_info_node;
171 |
172 | if (ngx_queue_empty(&ctx->sh->queue)) {
173 | return;
174 | }
175 |
176 | q = ngx_queue_last(&ctx->sh->queue);
177 |
178 | rc_info_node = ngx_queue_data(q, ngx_http_tfs_rcs_info_t, queue);
179 | kp_q = &rc_info_node->kp_queue;
180 |
181 | ngx_queue_remove(q);
182 | ngx_queue_remove(kp_q);
183 |
184 | node = (ngx_rbtree_node_t *)
185 | ((u_char *) rc_info_node - offsetof(ngx_rbtree_node_t, color));
186 |
187 | ngx_rbtree_delete(&ctx->sh->rbtree, node);
188 |
189 | ngx_http_tfs_rc_server_destroy_node(ctx, rc_info_node);
190 | }
191 |
192 |
193 | ngx_int_t
194 | ngx_http_tfs_rc_server_init_zone(ngx_shm_zone_t *shm_zone, void *data)
195 | {
196 | ngx_http_tfs_rc_ctx_t *octx = data;
197 |
198 | size_t len;
199 | ngx_http_tfs_rc_ctx_t *ctx;
200 |
201 | ctx = shm_zone->data;
202 |
203 | if (octx) {
204 |
205 | ctx->sh = octx->sh;
206 | ctx->shpool = octx->shpool;
207 |
208 | return NGX_OK;
209 | }
210 |
211 | ctx->shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
212 |
213 | if (shm_zone->shm.exists) {
214 | ctx->sh = ctx->shpool->data;
215 |
216 | return NGX_OK;
217 | }
218 |
219 | ctx->sh = ngx_slab_alloc(ctx->shpool, sizeof(ngx_http_tfs_rc_shctx_t));
220 | if (ctx->sh == NULL) {
221 | return NGX_ERROR;
222 | }
223 |
224 | ctx->shpool->data = ctx->sh;
225 |
226 | ngx_rbtree_init(&ctx->sh->rbtree, &ctx->sh->sentinel,
227 | ngx_http_tfs_rcs_rbtree_insert_value);
228 | ngx_queue_init(&ctx->sh->queue);
229 | ngx_queue_init(&ctx->sh->kp_queue);
230 |
231 | len = sizeof(" in tfs rc servers zone \"\"") + shm_zone->shm.name.len;
232 |
233 | ctx->shpool->log_ctx = ngx_slab_alloc(ctx->shpool, len);
234 | if (ctx->shpool->log_ctx == NULL) {
235 | return NGX_ERROR;
236 | }
237 |
238 | ngx_sprintf(ctx->shpool->log_ctx, " in tfs rc servers zone \"%V\"%Z",
239 | &shm_zone->shm.name);
240 |
241 | return NGX_OK;
242 | }
243 |
244 |
245 | static void
246 | ngx_http_tfs_rcs_rbtree_insert_value(ngx_rbtree_node_t *temp,
247 | ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
248 | {
249 | ngx_int_t rc;
250 | ngx_rbtree_node_t **p;
251 | ngx_http_tfs_rcs_info_t *trn, *trnt;
252 |
253 | for ( ;; ) {
254 |
255 | if (node->key < temp->key) {
256 |
257 | p = &temp->left;
258 |
259 | } else if (node->key > temp->key) {
260 |
261 | p = &temp->right;
262 |
263 | } else { /* node->key == temp->key */
264 |
265 | trn = (ngx_http_tfs_rcs_info_t *) &node->color;
266 | trnt = (ngx_http_tfs_rcs_info_t *) &temp->color;
267 |
268 | rc = ngx_memn2cmp(trn->appkey.data, trnt->appkey.data,
269 | trn->appkey.len, trn->appkey.len);
270 | if (rc < 0) {
271 | p = &temp->left;
272 |
273 | } else if (rc > 0) {
274 | p = &temp->right;
275 |
276 | } else {
277 | return;
278 | }
279 | }
280 |
281 | if (*p == sentinel) {
282 | break;
283 | }
284 |
285 | temp = *p;
286 | }
287 |
288 | *p = node;
289 | node->parent = temp;
290 | node->left = sentinel;
291 | node->right = sentinel;
292 | ngx_rbt_red(node);
293 | }
294 |
295 |
296 | void
297 | ngx_http_tfs_rcs_set_group_info_by_addr(ngx_http_tfs_rcs_info_t *rc_info,
298 | ngx_int_t group_count, ngx_int_t group_seq, ngx_http_tfs_inet_t addr)
299 | {
300 | ngx_uint_t i, j;
301 | ngx_http_tfs_group_info_t *group_info;
302 | ngx_http_tfs_cluster_group_info_t *cluster_group_info;
303 |
304 | cluster_group_info = rc_info->unlink_clusters;
305 |
306 | for (i = 0; i < rc_info->unlink_cluster_count; i++) {
307 | group_info = cluster_group_info[i].group_info;
308 |
309 | for (j = 0; j < cluster_group_info[i].info_count; j++) {
310 |
311 | if (group_info[j].group_seq >= 0) {
312 | continue;
313 | }
314 |
315 | if (ngx_memcmp(&group_info[j].ns_vip, &addr,
316 | sizeof(ngx_http_tfs_inet_t)) == 0)
317 | {
318 | group_info[j].group_seq = group_seq;
319 | cluster_group_info[i].group_count = group_count;
320 | return;
321 | }
322 | }
323 | }
324 | }
325 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_rc_server_info.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #ifndef _NGX_HTTP_TFS_RC_SERVER_INFO_H_INCLUDED_
8 | #define _NGX_HTTP_TFS_RC_SERVER_INFO_H_INCLUDED_
9 |
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 |
18 | #define ngx_http_tfs_cluster_is_master(cluster_id) \
19 | (cluster_id[2] == 'M' || cluster_id[2] == 'm')
20 |
21 | #define ngx_http_tfs_get_cluster_id(cluster_id_data) \
22 | (cluster_id_data[1] - '0')
23 |
24 |
25 | typedef struct {
26 | int32_t group_seq; /* get from ns */
27 | ngx_str_t ns_vip_text;
28 | uint8_t is_master;
29 | ngx_http_tfs_inet_t ns_vip;
30 | } ngx_http_tfs_group_info_t;
31 |
32 |
33 | typedef struct {
34 | uint32_t cluster_id;
35 | int32_t group_count; /* get from ns */
36 | uint32_t info_count;
37 | ngx_http_tfs_group_info_t group_info[NGX_HTTP_TFS_MAX_CLUSTER_ID_COUNT];
38 | } ngx_http_tfs_cluster_group_info_t;
39 |
40 |
41 | typedef struct {
42 | uint32_t cluster_stat;
43 | uint32_t access_type;
44 | uint32_t cluster_id; /* get from ns */
45 | ngx_str_t cluster_id_text;
46 | ngx_str_t ns_vip_text;
47 | ngx_http_tfs_inet_t ns_vip;
48 | } ngx_http_tfs_physical_cluster_t;
49 |
50 |
51 | typedef struct {
52 | uint8_t need_duplicate;
53 | uint32_t dup_server_addr_hash;
54 | ngx_http_tfs_tair_server_addr_info_t dup_server_info;
55 |
56 | /* for read and write */
57 | uint32_t rw_cluster_count;
58 | ngx_http_tfs_physical_cluster_t rw_clusters[NGX_HTTP_TFS_MAX_CLUSTER_COUNT];
59 | } ngx_http_tfs_logical_cluster_t;
60 |
61 |
62 | typedef struct {
63 | u_char color;
64 | u_char dummy;
65 | ngx_queue_t queue;
66 | /* for keep alive, fixed sequence */
67 | ngx_queue_t kp_queue;
68 |
69 | ngx_str_t appkey;
70 | uint64_t app_id;
71 | ngx_str_t session_id;
72 | uint32_t rc_servers_count;
73 | uint64_t *rc_servers;
74 |
75 | /* logical cluster */
76 | uint32_t logical_cluster_count;
77 | ngx_http_tfs_logical_cluster_t logical_clusters[NGX_HTTP_TFS_MAX_CLUSTER_COUNT];
78 |
79 | uint8_t need_duplicate;
80 |
81 | uint32_t report_interval;
82 | uint64_t modify_time;
83 | uint64_t meta_root_server;
84 | ngx_str_t remote_block_cache_info;
85 |
86 | /* for unlink & update */
87 | uint8_t unlink_cluster_count;
88 | ngx_http_tfs_cluster_group_info_t unlink_clusters[NGX_HTTP_TFS_MAX_CLUSTER_COUNT];
89 |
90 | uint32_t use_remote_block_cache;
91 | } ngx_http_tfs_rcs_info_t;
92 |
93 |
94 | typedef struct {
95 | ngx_rbtree_t rbtree;
96 | ngx_rbtree_node_t sentinel;
97 | ngx_queue_t queue;
98 | /* for keep alive, fixed sequence */
99 | ngx_queue_t kp_queue;
100 | } ngx_http_tfs_rc_shctx_t;
101 |
102 |
103 | typedef struct {
104 | ngx_http_tfs_rc_shctx_t *sh;
105 | ngx_slab_pool_t *shpool;
106 | } ngx_http_tfs_rc_ctx_t;
107 |
108 |
109 | ngx_int_t ngx_http_tfs_rc_server_update(ngx_http_request_t *r,
110 | ngx_http_tfs_rc_ctx_t *t, ngx_http_tfs_rcs_info_t *info);
111 | ngx_int_t ngx_http_tfs_rc_server_init_zone(ngx_shm_zone_t *shm_zone,
112 | void *data);
113 | void ngx_http_tfs_rc_server_expire(ngx_http_tfs_rc_ctx_t *ctx);
114 | ngx_http_tfs_rcs_info_t *ngx_http_tfs_rcs_lookup(ngx_http_request_t *r,
115 | ngx_http_tfs_rc_ctx_t *ctx, ngx_str_t appkey);
116 | void ngx_http_tfs_rc_server_destroy_node(ngx_http_tfs_rc_ctx_t *ctx,
117 | ngx_http_tfs_rcs_info_t *rc_info_node);
118 | void ngx_http_tfs_rcs_set_group_info_by_addr(ngx_http_tfs_rcs_info_t *rc_info,
119 | ngx_int_t group_count, ngx_int_t seq_id, ngx_http_tfs_inet_t addr);
120 |
121 |
122 | #endif /* _NGX_HTTP_TFS_RC_SERVER_INFO_H_INCLUDED_ */
123 |
124 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_rc_server_message.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #ifndef _NGX_TFS_RC_SERVER_MESSAGE_H_INCLUDED_
8 | #define _NGX_TFS_RC_SERVER_MESSAGE_H_INCLUDED_
9 |
10 |
11 | #include
12 |
13 |
14 | ngx_chain_t *ngx_http_tfs_rc_server_create_message(ngx_http_tfs_t *t);
15 | ngx_int_t ngx_http_tfs_rc_server_parse_message(ngx_http_tfs_t *t);
16 |
17 |
18 | #endif /* _NGX_TFS_RC_SERVER_MESSAGE_H_INCLUDED_ */
19 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_remote_block_cache.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 |
13 | static void ngx_http_tfs_remote_block_cache_get_handler(
14 | ngx_http_tair_key_value_t *kv, ngx_int_t rc, void *data);
15 | static void ngx_http_tfs_remote_block_cache_dummy_handler(ngx_int_t rc,
16 | void *data);
17 |
18 | static void ngx_http_tfs_remote_block_cache_mget_handler(ngx_array_t *kvs,
19 | ngx_int_t rc, void *data);
20 |
21 | ngx_int_t
22 | ngx_http_tfs_remote_block_cache_lookup(
23 | ngx_http_tfs_remote_block_cache_ctx_t *ctx,
24 | ngx_pool_t *pool, ngx_log_t *log, ngx_http_tfs_block_cache_key_t* key)
25 | {
26 | ngx_int_t rc;
27 | ngx_http_tair_data_t tair_key;
28 |
29 | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, log, 0,
30 | "lookup remote block cache, ns addr: %uL, block id: %uD",
31 | key->ns_addr, key->block_id);
32 |
33 | tair_key.type = NGX_HTTP_TAIR_INT;
34 | tair_key.data = (u_char *)key;
35 | tair_key.len = NGX_HTTP_TFS_BLOCK_CACHE_KEY_SIZE;
36 |
37 | rc = ngx_http_tfs_tair_get_helper(
38 | ctx->tair_instance,
39 | pool, log,
40 | &tair_key,
41 | ngx_http_tfs_remote_block_cache_get_handler,
42 | (void *)ctx);
43 |
44 | return rc;
45 | }
46 |
47 |
48 | static void
49 | ngx_http_tfs_remote_block_cache_get_handler(ngx_http_tair_key_value_t *kv,
50 | ngx_int_t rc, void *data)
51 | {
52 | u_char *p, *q;
53 | uint32_t ds_count;
54 | ngx_http_tfs_t *t;
55 | ngx_http_tfs_inet_t *addr;
56 | ngx_http_tfs_segment_data_t *segment_data;
57 | ngx_http_tfs_block_cache_key_t key;
58 | ngx_http_tfs_block_cache_value_t value;
59 | ngx_http_tfs_remote_block_cache_ctx_t *ctx = data;
60 |
61 | t = ctx->data;
62 | segment_data = &t->file.segment_data[t->file.segment_index];
63 | if (rc == NGX_HTTP_ETAIR_SUCCESS) {
64 | q = kv->key.data;
65 | p = kv->value->data;
66 | if (p != NULL
67 | && (kv->value->len
68 | > NGX_HTTP_TFS_REMOTE_BLOCK_CACHE_VALUE_BASE_SIZE))
69 | {
70 | key.ns_addr = *(uint64_t *)q;
71 | q += sizeof(uint64_t);
72 | key.block_id = *(uint32_t *)q;
73 |
74 | ds_count = *(uint32_t *)p;
75 | p += sizeof(uint32_t);
76 |
77 | if (ds_count > 0) {
78 | segment_data->block_info.ds_count = ds_count;
79 | segment_data->block_info.ds_addrs = ngx_pcalloc(t->pool,
80 | sizeof(ngx_http_tfs_inet_t) * ds_count);
81 | if (segment_data->block_info.ds_addrs == NULL) {
82 | ngx_http_tfs_finalize_request(t->data, t,
83 | NGX_HTTP_INTERNAL_SERVER_ERROR);
84 | return;
85 | }
86 | ngx_memcpy(segment_data->block_info.ds_addrs, p,
87 | ds_count * sizeof(ngx_http_tfs_inet_t));
88 |
89 | /* insert local block cache */
90 | if (t->block_cache_ctx.use_cache
91 | & NGX_HTTP_TFS_LOCAL_BLOCK_CACHE)
92 | {
93 | value.ds_count = ds_count;
94 | value.ds_addrs =
95 | (uint64_t *)segment_data->block_info.ds_addrs;
96 | ngx_http_tfs_local_block_cache_insert(
97 | t->block_cache_ctx.local_ctx,
98 | t->log, &key, &value);
99 | }
100 |
101 | /* skip GET_BLK_INFO state */
102 | t->state += 1;
103 |
104 | segment_data->cache_hit = NGX_HTTP_TFS_REMOTE_BLOCK_CACHE;
105 | segment_data->block_info_src = NGX_HTTP_TFS_FROM_CACHE;
106 |
107 | /* select data server */
108 | addr = ngx_http_tfs_select_data_server(t, segment_data);
109 |
110 | ngx_http_tfs_peer_set_addr(t->pool,
111 | &t->tfs_peer_servers[NGX_HTTP_TFS_DATA_SERVER],
112 | addr);
113 |
114 | } else {
115 | /* remote block cache invalid, need remove it */
116 | ngx_http_tfs_remote_block_cache_remove(ctx, t->pool, t->log,
117 | &key);
118 | }
119 | }
120 |
121 | } else {
122 | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, t->log, 0,
123 | "lookup remote block cache, "
124 | "ns addr: %V, block id: %uD not found",
125 | &t->name_server_addr_text,
126 | segment_data->segment_info.block_id);
127 | }
128 |
129 | ngx_http_tfs_finalize_state(t, NGX_OK);
130 | }
131 |
132 |
133 | ngx_int_t
134 | ngx_http_tfs_remote_block_cache_insert(
135 | ngx_http_tfs_remote_block_cache_ctx_t *ctx,
136 | ngx_pool_t *pool, ngx_log_t *log,
137 | ngx_http_tfs_block_cache_key_t *key,
138 | ngx_http_tfs_block_cache_value_t *value)
139 | {
140 | ngx_int_t rc;
141 | ngx_pool_t *tmp_pool;
142 | ngx_http_tair_data_t tair_key;
143 | ngx_http_tair_data_t tair_value;
144 |
145 | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, log, 0,
146 | "insert remote block cache, "
147 | "ns addr: %uL, block id: %uD",
148 | key->ns_addr, key->block_id);
149 |
150 | tair_key.type = NGX_HTTP_TAIR_INT;
151 | tair_key.data = (u_char *)key;
152 | tair_key.len = NGX_HTTP_TFS_BLOCK_CACHE_KEY_SIZE;
153 |
154 | tair_value.len = NGX_HTTP_TFS_REMOTE_BLOCK_CACHE_VALUE_BASE_SIZE
155 | + value->ds_count * sizeof(uint64_t);
156 | tair_value.data = ngx_pcalloc(pool, tair_value.len);
157 | if (tair_value.data == NULL) {
158 | return NGX_ERROR;
159 | }
160 | *(uint32_t*)tair_value.data = value->ds_count;
161 | ngx_memcpy(tair_value.data+ NGX_HTTP_TFS_REMOTE_BLOCK_CACHE_VALUE_BASE_SIZE,
162 | value->ds_addrs, value->ds_count * sizeof(uint64_t));
163 | tair_value.type = NGX_HTTP_TAIR_INT;
164 |
165 | /* since we do not care returns,
166 | * we make a tmp pool and destroy it in callback */
167 | tmp_pool = ngx_create_pool(4096, log);
168 | if (tmp_pool == NULL) {
169 | return NGX_ERROR;
170 | }
171 |
172 | rc = ngx_http_tfs_tair_put_helper(
173 | ctx->tair_instance,
174 | tmp_pool, log,
175 | &tair_key, &tair_value,
176 | 0/*expire*/, 0/* do not care version */,
177 | ngx_http_tfs_remote_block_cache_dummy_handler,
178 | (void *)tmp_pool);
179 |
180 | return rc;
181 | }
182 |
183 |
184 | static void
185 | ngx_http_tfs_remote_block_cache_dummy_handler(ngx_int_t rc, void *data)
186 | {
187 | ngx_pool_t *pool = (ngx_pool_t *)data;
188 | ngx_destroy_pool(pool);
189 |
190 | return;
191 | }
192 |
193 |
194 | void
195 | ngx_http_tfs_remote_block_cache_remove(
196 | ngx_http_tfs_remote_block_cache_ctx_t *ctx,
197 | ngx_pool_t *pool, ngx_log_t *log, ngx_http_tfs_block_cache_key_t* key)
198 | {
199 | ngx_int_t rc;
200 | ngx_pool_t *tmp_pool;
201 | ngx_array_t tair_keys;
202 | ngx_http_tair_data_t *tair_key;
203 |
204 | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, log, 0,
205 | "remove remote block cache, ns addr: %uL, block id: %uD",
206 | key->ns_addr, key->block_id);
207 |
208 | rc = ngx_array_init(&tair_keys, pool, 1, sizeof(ngx_http_tair_data_t));
209 | if (rc == NGX_ERROR) {
210 | return;
211 | }
212 | tair_key = (ngx_http_tair_data_t*) ngx_array_push(&tair_keys);
213 |
214 | tair_key->type = NGX_HTTP_TAIR_INT;
215 | tair_key->data = (u_char *)key;
216 | tair_key->len = NGX_HTTP_TFS_BLOCK_CACHE_KEY_SIZE;
217 |
218 | /* since we do not care returns,
219 | * we make a tmp pool and destroy it in callback */
220 | tmp_pool = ngx_create_pool(4096, log);
221 | if (tmp_pool == NULL) {
222 | return;
223 | }
224 |
225 | (void) ngx_http_tfs_tair_delete_helper(
226 | ctx->tair_instance,
227 | tmp_pool, log,
228 | &tair_keys,
229 | ngx_http_tfs_remote_block_cache_dummy_handler,
230 | (void *)tmp_pool);
231 |
232 | }
233 |
234 |
235 | ngx_int_t
236 | ngx_http_tfs_remote_block_cache_batch_lookup(
237 | ngx_http_tfs_remote_block_cache_ctx_t *ctx,
238 | ngx_pool_t *pool, ngx_log_t *log, ngx_array_t* keys)
239 | {
240 | ngx_int_t rc;
241 | ngx_uint_t i;
242 | ngx_array_t *tair_kvs;
243 | ngx_http_tair_key_value_t *tair_kv;
244 | ngx_http_tfs_block_cache_key_t *key;
245 |
246 | tair_kvs = ngx_array_create(pool, keys->nelts,
247 | sizeof(ngx_http_tair_key_value_t));
248 | if (tair_kvs == NULL) {
249 | return NGX_ERROR;
250 | }
251 |
252 | key = keys->elts;
253 | for (i = 0; i < keys->nelts; i++, key++) {
254 | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, log, 0,
255 | "batch lookup remote block cache, "
256 | "ns addr: %uL, block id: %uD",
257 | key->ns_addr, key->block_id);
258 |
259 | tair_kv = (ngx_http_tair_key_value_t *)ngx_array_push(tair_kvs);
260 | if (tair_kv == NULL) {
261 | return NGX_ERROR;
262 | }
263 |
264 | tair_kv->key.type = NGX_HTTP_TAIR_INT;
265 | tair_kv->key.data = (u_char *)key;
266 | tair_kv->key.len = NGX_HTTP_TFS_BLOCK_CACHE_KEY_SIZE;
267 | }
268 |
269 | rc = ngx_http_tfs_tair_mget_helper(
270 | ctx->tair_instance,
271 | pool, log,
272 | tair_kvs,
273 | ngx_http_tfs_remote_block_cache_mget_handler,
274 | (void *)ctx);
275 | return rc;
276 | }
277 |
278 |
279 | static void
280 | ngx_http_tfs_remote_block_cache_mget_handler(ngx_array_t *kvs, ngx_int_t rc,
281 | void *data)
282 | {
283 | u_char *p, *q;
284 | uint32_t ds_count, block_count;
285 | ngx_uint_t i, j, hit_count;
286 | ngx_http_tfs_t *t;
287 | ngx_http_tair_key_value_t *kv;
288 | ngx_http_tfs_segment_data_t *segment_data;
289 | ngx_http_tfs_block_cache_key_t key;
290 | ngx_http_tfs_block_cache_value_t value;
291 | ngx_http_tfs_remote_block_cache_ctx_t *ctx = data;
292 |
293 | t = ctx->data;
294 |
295 | segment_data = &t->file.segment_data[t->file.segment_index];
296 | block_count = t->file.segment_count - t->file.segment_index;
297 | if (block_count > NGX_HTTP_TFS_MAX_SEND_FRAG_COUNT) {
298 | block_count = NGX_HTTP_TFS_MAX_SEND_FRAG_COUNT;
299 | }
300 |
301 | if (rc == NGX_OK) {
302 | kv = kvs->elts;
303 | hit_count = 0;
304 | for (i = 0; i < kvs->nelts; i++, kv++) {
305 | if (kv->rc != NGX_HTTP_ETAIR_SUCCESS) {
306 | continue;
307 | }
308 | q = kv->key.data;
309 | p = kv->value->data;
310 | if (p != NULL
311 | && (kv->value->len
312 | > NGX_HTTP_TFS_REMOTE_BLOCK_CACHE_VALUE_BASE_SIZE))
313 | {
314 | key.ns_addr = *(uint64_t *)q;
315 | q += sizeof(uint64_t);
316 | key.block_id = *(uint32_t *)q;
317 |
318 | ds_count = *(uint32_t *)p;
319 | p += sizeof(uint32_t);
320 |
321 | if (ds_count > 0) {
322 | /* find out segment */
323 | for (j = 0; j < block_count; j++) {
324 | if(segment_data[j].segment_info.block_id == key.block_id
325 | && segment_data[j].block_info.ds_addrs == NULL)
326 | {
327 | break;
328 | }
329 | }
330 | /* not found, some error happen */
331 | if (j == block_count) {
332 | continue;
333 | }
334 |
335 | segment_data[j].block_info.ds_count = ds_count;
336 | segment_data[j].block_info.ds_addrs = ngx_pcalloc(t->pool,
337 | ds_count * sizeof(ngx_http_tfs_inet_t));
338 | if (segment_data[j].block_info.ds_addrs == NULL) {
339 | ngx_http_tfs_finalize_request(t->data, t,
340 | NGX_HTTP_INTERNAL_SERVER_ERROR);
341 | return;
342 | }
343 | ngx_memcpy(segment_data[j].block_info.ds_addrs, p,
344 | ds_count * sizeof(ngx_http_tfs_inet_t));
345 |
346 | if (t->block_cache_ctx.use_cache
347 | & NGX_HTTP_TFS_LOCAL_BLOCK_CACHE)
348 | {
349 | value.ds_count = ds_count;
350 | value.ds_addrs =
351 | (uint64_t *)segment_data[j].block_info.ds_addrs;
352 | ngx_http_tfs_local_block_cache_insert(
353 | t->block_cache_ctx.local_ctx, t->log, &key, &value);
354 | }
355 |
356 | hit_count++;
357 | segment_data[j].cache_hit = NGX_HTTP_TFS_REMOTE_BLOCK_CACHE;
358 | segment_data[j].block_info_src = NGX_HTTP_TFS_FROM_CACHE;
359 |
360 | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, t->log, 0,
361 | "remote block cache hit, "
362 | "ns addr: %V, block id: %uD",
363 | &t->name_server_addr_text,
364 | segment_data[j].segment_info.block_id);
365 |
366 | } else {
367 | /* remote block cache invalid, need remove it */
368 | ngx_http_tfs_remote_block_cache_remove(ctx, t->pool, t->log,
369 | &key);
370 | }
371 | }
372 | }
373 |
374 | if (hit_count > 0) {
375 | ngx_log_debug1(NGX_LOG_DEBUG_HTTP, t->log, 0,
376 | "batch lookup remote block cache, hit_count: %ui",
377 | hit_count);
378 |
379 | if (hit_count == kvs->nelts) {
380 | /* all cache hit, start batch process */
381 | rc = ngx_http_tfs_batch_process_start(t);
382 | if (rc == NGX_ERROR) {
383 | ngx_http_tfs_finalize_request(t->data, t,
384 | NGX_HTTP_INTERNAL_SERVER_ERROR);
385 | return;
386 | }
387 | return;
388 | }
389 | }
390 |
391 | } else {
392 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, t->log, 0,
393 | "remote block cache miss");
394 | }
395 |
396 | ngx_http_tfs_finalize_state(t, NGX_OK);
397 | }
398 |
399 |
400 | #ifdef NGX_HTTP_TFS_USE_TAIR
401 | ngx_int_t
402 | ngx_http_tfs_get_remote_block_cache_instance(
403 | ngx_http_tfs_remote_block_cache_ctx_t *ctx,
404 | ngx_str_t *server_addr)
405 | {
406 | size_t server_addr_len;
407 | uint32_t server_addr_hash;
408 | ngx_int_t rc, i;
409 | ngx_str_t *st;
410 | ngx_array_t config_server;
411 | ngx_http_tfs_t *t;
412 | ngx_http_tfs_tair_instance_t *instance;
413 | ngx_http_etair_server_conf_t *server;
414 | ngx_http_tfs_tair_server_addr_info_t server_addr_info;
415 |
416 | if (server_addr->len == 0
417 | || server_addr->data == NULL)
418 | {
419 | return NGX_ERROR;
420 | }
421 |
422 | t = ctx->data;
423 | server_addr_len = server_addr->len;
424 | server_addr_hash = ngx_murmur_hash2(server_addr->data, server_addr_len);
425 |
426 | instance = ctx->tair_instance;
427 | if (instance->server != NULL) {
428 | if (instance->server_addr_hash == server_addr_hash) {
429 | return NGX_OK;
430 | }
431 |
432 | ngx_http_etair_destory_server(instance->server,
433 | (ngx_cycle_t *) ngx_cycle);
434 | instance->server = NULL;
435 | }
436 |
437 | rc = ngx_http_tfs_parse_tair_server_addr_info(&server_addr_info,
438 | server_addr->data,
439 | server_addr_len,
440 | t->pool, 0);
441 | if (rc == NGX_ERROR) {
442 | return NGX_ERROR;
443 | }
444 |
445 | rc = ngx_array_init(&config_server, t->pool,
446 | NGX_HTTP_TFS_TAIR_CONFIG_SERVER_COUNT,
447 | sizeof(ngx_str_t));
448 | if (rc == NGX_ERROR) {
449 | return NGX_ERROR;
450 | }
451 |
452 | for (i = 0; i < NGX_HTTP_TFS_TAIR_CONFIG_SERVER_COUNT; i++) {
453 | if (server_addr_info.server[i].len > 0 ) {
454 | st = (ngx_str_t *) ngx_array_push(&config_server);
455 | *st = server_addr_info.server[i];
456 | }
457 | }
458 |
459 | server = &server_addr_info.server[NGX_HTTP_TFS_TAIR_CONFIG_SERVER_COUNT];
460 | instance->server = ngx_http_etair_create_server(server,
461 | &config_server,
462 | t->main_conf->tair_timeout,
463 | (ngx_cycle_t *) ngx_cycle);
464 | if (instance->server == NULL) {
465 | return NGX_ERROR;
466 | }
467 | instance->server_addr_hash = server_addr_hash;
468 | instance->area = server_addr_info.area;
469 |
470 | return NGX_OK;
471 | }
472 |
473 | #else
474 |
475 | ngx_int_t
476 | ngx_http_tfs_get_remote_block_cache_instance(
477 | ngx_http_tfs_remote_block_cache_ctx_t *ctx,
478 | ngx_str_t *server_addr)
479 | {
480 | return NGX_ERROR;
481 | }
482 |
483 | #endif
484 |
485 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_remote_block_cache.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #ifndef _NGX_HTTP_TFS_REMOTE_BLOCK_CACHE_H_INCLUDED_
8 | #define _NGX_HTTP_TFS_REMOTE_BLOCK_CACHE_H_INCLUDED_
9 |
10 |
11 | #include
12 |
13 |
14 | ngx_int_t ngx_http_tfs_remote_block_cache_lookup(
15 | ngx_http_tfs_remote_block_cache_ctx_t *ctx,
16 | ngx_pool_t *pool, ngx_log_t *log, ngx_http_tfs_block_cache_key_t* key);
17 |
18 | ngx_int_t ngx_http_tfs_remote_block_cache_insert(
19 | ngx_http_tfs_remote_block_cache_ctx_t *ctx,
20 | ngx_pool_t *pool, ngx_log_t *log, ngx_http_tfs_block_cache_key_t *key,
21 | ngx_http_tfs_block_cache_value_t *value);
22 |
23 | void ngx_http_tfs_remote_block_cache_remove(
24 | ngx_http_tfs_remote_block_cache_ctx_t *ctx,
25 | ngx_pool_t *pool, ngx_log_t *log, ngx_http_tfs_block_cache_key_t *key);
26 |
27 | ngx_int_t ngx_http_tfs_remote_block_cache_batch_lookup(
28 | ngx_http_tfs_remote_block_cache_ctx_t *ctx,
29 | ngx_pool_t *pool, ngx_log_t *log, ngx_array_t* keys);
30 |
31 | ngx_int_t ngx_http_tfs_remote_block_cache_batch_insert(
32 | ngx_http_tfs_remote_block_cache_ctx_t *ctx,
33 | ngx_pool_t *pool, ngx_log_t *log, ngx_array_t *kvs);
34 |
35 | ngx_int_t ngx_http_tfs_get_remote_block_cache_instance(
36 | ngx_http_tfs_remote_block_cache_ctx_t *ctx,
37 | ngx_str_t *server_addr);
38 |
39 |
40 | #endif /* _NGX_HTTP_TFS_REMOTE_BLOCK_CACHE_H_INCLUDED_ */
41 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_restful.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #ifndef _NGX_HTTP_TFS_RESTFUL_H_INCLUDED_
8 | #define _NGX_HTTP_TFS_RESTFUL_H_INCLUDED_
9 |
10 |
11 | #include
12 | #include
13 | #include
14 |
15 |
16 | typedef struct {
17 | ngx_str_t file_path_s;
18 | ngx_str_t file_path_d;
19 |
20 | ngx_str_t file_suffix;
21 | ngx_http_tfs_raw_fsname_t fsname;
22 |
23 | ngx_str_t appkey;
24 | uint64_t app_id;
25 | uint64_t user_id;
26 |
27 | /* action */
28 | ngx_http_tfs_action_t action;
29 | int64_t offset;
30 | uint64_t size;
31 |
32 | ngx_int_t unlink_type;
33 | ngx_int_t simple_name;
34 | uint8_t version;
35 | uint8_t file_type;
36 | ngx_int_t large_file;
37 |
38 | ngx_int_t read_stat_type;
39 | ngx_int_t write_meta_segment;
40 | ngx_int_t no_dedup;
41 | ngx_int_t chk_file_hole;
42 |
43 | unsigned meta:1;
44 | unsigned get_appid:1;
45 | unsigned chk_exist:1;
46 | unsigned recursive:1;
47 | } ngx_http_tfs_restful_ctx_t;
48 |
49 |
50 | ngx_int_t ngx_http_restful_parse(ngx_http_request_t *r,
51 | ngx_http_tfs_restful_ctx_t *ctx);
52 |
53 |
54 | #endif /* _NGX_HTTP_TFS_RESTFUL_H_INCLUDED_ */
55 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_root_server_message.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #include
8 | #include
9 |
10 |
11 | ngx_chain_t *
12 | ngx_http_tfs_root_server_create_message(ngx_pool_t *pool)
13 | {
14 | ngx_buf_t *b;
15 | ngx_chain_t *cl;
16 | ngx_http_tfs_rs_request_t *req;
17 |
18 | b = ngx_create_temp_buf(pool, sizeof(ngx_http_tfs_rs_request_t));
19 | if (b == NULL) {
20 | return NULL;
21 | }
22 |
23 | req = (ngx_http_tfs_rs_request_t *) b->pos;
24 | req->header.flag = NGX_HTTP_TFS_PACKET_FLAG;
25 | req->header.len = sizeof(uint8_t);
26 | req->header.type = NGX_HTTP_TFS_REQ_RT_GET_TABLE_MESSAGE;
27 | req->header.version = NGX_HTTP_TFS_PACKET_VERSION;
28 | req->header.crc = ngx_http_tfs_crc(NGX_HTTP_TFS_PACKET_FLAG,
29 | (const char *) (&req->header + 1),
30 | req->header.len);
31 | req->header.id = ngx_http_tfs_generate_packet_id();
32 |
33 | b->last += sizeof(ngx_http_tfs_rs_request_t);
34 |
35 | cl = ngx_alloc_chain_link(pool);
36 | if (cl == NULL) {
37 | return NULL;
38 | }
39 |
40 | cl->buf = b;
41 | cl->next = NULL;
42 |
43 | return cl;
44 | }
45 |
46 |
47 | ngx_int_t
48 | ngx_http_tfs_root_server_parse_message(ngx_http_tfs_t *t)
49 | {
50 | ngx_int_t rc;
51 | ngx_http_tfs_peer_connection_t *tp;
52 | ngx_http_tfs_rs_response_t *resp;
53 | uLongf table_length;
54 |
55 | tp = t->tfs_peer;
56 | resp = (ngx_http_tfs_rs_response_t *) (tp->body_buffer.pos);
57 | table_length = NGX_HTTP_TFS_METASERVER_COUNT * sizeof(uint64_t);
58 |
59 | rc = uncompress((Bytef *) (t->loc_conf->meta_server_table.table),
60 | &table_length, resp->table, resp->length);
61 | if (rc != Z_OK) {
62 | ngx_log_error(NGX_LOG_ERR, t->log, errno, "uncompress error");
63 | return NGX_ERROR;
64 | }
65 |
66 | t->loc_conf->meta_server_table.version = resp->version;
67 |
68 | return NGX_OK;
69 | }
70 |
71 |
72 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_root_server_message.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #ifndef _NGX_HTTP_TFS_ROOT_SERVER_MESSAGE_H_INCLUDED_
8 | #define _NGX_HTTP_TFS_ROOT_SERVER_MESSAGE_H_INCLUDED_
9 |
10 |
11 | #include
12 |
13 |
14 | ngx_chain_t *ngx_http_tfs_root_server_create_message(ngx_pool_t *pool);
15 | ngx_int_t ngx_http_tfs_root_server_parse_message(ngx_http_tfs_t *t);
16 |
17 |
18 | #endif /* _NGX_HTTP_TFS_ROOT_SERVER_MESSAGE_H_INCLUDED_ */
19 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_server_handler.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #ifndef _NGX_HTTP_TFS_SERVER_HANDLER_H_INCLUDED_
8 | #define _NGX_HTTP_TFS_SERVER_HANDLER_H_INCLUDED_
9 |
10 |
11 | #include
12 |
13 |
14 | /* root server */
15 | ngx_int_t ngx_http_tfs_create_rs_request(ngx_http_tfs_t *t);
16 | ngx_int_t ngx_http_tfs_process_rs(ngx_http_tfs_t *t);
17 |
18 |
19 | /* meta server */
20 | ngx_int_t ngx_http_tfs_create_ms_request(ngx_http_tfs_t *t);
21 | ngx_int_t ngx_http_tfs_process_ms_input_filter(ngx_http_tfs_t *t);
22 | ngx_int_t ngx_http_tfs_process_ms(ngx_http_tfs_t *t);
23 | ngx_int_t ngx_http_tfs_process_ms_ls_dir(ngx_http_tfs_t *t);
24 |
25 |
26 | /* rc server */
27 | ngx_int_t ngx_http_tfs_create_rcs_request(ngx_http_tfs_t *t);
28 | ngx_int_t ngx_http_tfs_process_rcs(ngx_http_tfs_t *t);
29 |
30 |
31 | /* name server */
32 | ngx_int_t ngx_http_tfs_create_ns_request(ngx_http_tfs_t *t);
33 | ngx_int_t ngx_http_tfs_process_ns(ngx_http_tfs_t *t);
34 |
35 |
36 | /* data server */
37 | ngx_int_t ngx_http_tfs_create_ds_request(ngx_http_tfs_t *t);
38 | ngx_int_t ngx_http_tfs_process_ds_input_filter(ngx_http_tfs_t *t);
39 | ngx_int_t ngx_http_tfs_process_ds(ngx_http_tfs_t *t);
40 | ngx_int_t ngx_http_tfs_process_ds_read(ngx_http_tfs_t *t);
41 |
42 | ngx_int_t ngx_http_tfs_retry_ds(ngx_http_tfs_t *t);
43 | ngx_int_t ngx_http_tfs_retry_ns(ngx_http_tfs_t *t);
44 |
45 |
46 | #endif /* */
47 |
48 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_tair_helper.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #include
8 |
9 |
10 | #ifdef NGX_HTTP_TFS_USE_TAIR
11 |
12 | ngx_int_t
13 | ngx_http_tfs_tair_get_helper(ngx_http_tfs_tair_instance_t *instance,
14 | ngx_pool_t *pool, ngx_log_t *log,
15 | ngx_http_tair_data_t *key, ngx_http_tair_get_handler_pt callback,
16 | void *data)
17 | {
18 | ngx_int_t rc;
19 |
20 | if (instance == NULL || key == NULL) {
21 | return NGX_ERROR;
22 | }
23 |
24 | rc = ngx_http_tair_get(instance->server, pool, log, *key,
25 | instance->area, callback, data);
26 |
27 | if (rc != NGX_OK) {
28 | return NGX_ERROR;
29 | }
30 |
31 | return NGX_DECLINED;
32 | }
33 |
34 |
35 | ngx_int_t ngx_http_tfs_tair_mget_helper(ngx_http_tfs_tair_instance_t *instance,
36 | ngx_pool_t *pool, ngx_log_t *log,
37 | ngx_array_t *kvs, ngx_http_tair_mget_handler_pt callback, void *data)
38 | {
39 | ngx_int_t rc;
40 |
41 | if (instance == NULL || kvs == NULL) {
42 | return NGX_ERROR;
43 | }
44 |
45 | rc = ngx_http_tair_mget(instance->server, pool, log, kvs,
46 | instance->area, callback, data);
47 |
48 | if (rc != NGX_OK) {
49 | return NGX_ERROR;
50 | }
51 |
52 | return NGX_DECLINED;
53 | }
54 |
55 |
56 | ngx_int_t
57 | ngx_http_tfs_tair_put_helper(ngx_http_tfs_tair_instance_t *instance,
58 | ngx_pool_t *pool, ngx_log_t *log,
59 | ngx_http_tair_data_t *key, ngx_http_tair_data_t *value,
60 | ngx_int_t expire, ngx_int_t version,
61 | ngx_http_tair_handler_pt callback, void *data)
62 | {
63 | ngx_int_t rc;
64 |
65 | if (instance == NULL || key == NULL || value == NULL) {
66 | return NGX_ERROR;
67 | }
68 |
69 | rc = ngx_http_tair_put(instance->server, pool, log, *key,
70 | *value, instance->area, 0/*nx*/, expire,
71 | version, callback, data);
72 |
73 | if (rc != NGX_OK) {
74 | return NGX_ERROR;
75 | }
76 |
77 | return NGX_DECLINED;
78 | }
79 |
80 |
81 | ngx_int_t
82 | ngx_http_tfs_tair_delete_helper(ngx_http_tfs_tair_instance_t *instance,
83 | ngx_pool_t *pool, ngx_log_t *log,
84 | ngx_array_t *keys, ngx_http_tair_handler_pt callback, void *data)
85 | {
86 | ngx_int_t rc;
87 |
88 | if (instance == NULL || keys == NULL) {
89 | return NGX_ERROR;
90 | }
91 |
92 | rc = ngx_http_tair_delete(instance->server, pool, log, keys,
93 | instance->area, callback, data);
94 |
95 | if (rc != NGX_OK) {
96 | return NGX_ERROR;
97 | }
98 |
99 | return NGX_DECLINED;
100 | }
101 |
102 | #else
103 |
104 | ngx_int_t
105 | ngx_http_tfs_tair_get_helper(ngx_http_tfs_tair_instance_t *instance,
106 | ngx_pool_t *pool, ngx_log_t *log,
107 | ngx_http_tair_data_t *key, ngx_http_tair_get_handler_pt callback,
108 | void *data)
109 | {
110 | return NGX_ERROR;
111 | }
112 |
113 |
114 | ngx_int_t ngx_http_tfs_tair_mget_helper(ngx_http_tfs_tair_instance_t *instance,
115 | ngx_pool_t *pool, ngx_log_t *log,
116 | ngx_array_t *kvs, ngx_http_tair_mget_handler_pt callback, void *data)
117 | {
118 | return NGX_ERROR;
119 | }
120 |
121 |
122 | ngx_int_t
123 | ngx_http_tfs_tair_put_helper(ngx_http_tfs_tair_instance_t *instance,
124 | ngx_pool_t *pool, ngx_log_t *log,
125 | ngx_http_tair_data_t *key, ngx_http_tair_data_t *value,
126 | ngx_int_t expire, ngx_int_t version,
127 | ngx_http_tair_handler_pt callback, void *data)
128 | {
129 | return NGX_ERROR;
130 | }
131 |
132 |
133 | ngx_int_t
134 | ngx_http_tfs_tair_delete_helper(ngx_http_tfs_tair_instance_t *instance,
135 | ngx_pool_t *pool, ngx_log_t *log,
136 | ngx_array_t *keys, ngx_http_tair_handler_pt callback, void *data)
137 | {
138 | return NGX_ERROR;
139 | }
140 |
141 | #endif
142 |
143 |
144 | ngx_int_t
145 | ngx_http_tfs_parse_tair_server_addr_info(
146 | ngx_http_tfs_tair_server_addr_info_t *info,
147 | u_char *addr, uint32_t len, void *pool, uint8_t shared_memory)
148 | {
149 | u_char *temp, *p;
150 | ssize_t info_size;
151 | ngx_int_t i;
152 |
153 | p = addr;
154 |
155 | for (i = 0; i < NGX_HTTP_TFS_TAIR_SERVER_ADDR_PART_COUNT; i++) {
156 | temp = ngx_strlchr(p, p + len, ';');
157 | if (temp == NULL) {
158 | return NGX_ERROR;
159 | }
160 |
161 | info_size = temp - p;
162 | if (shared_memory) {
163 | info->server[i].data =
164 | ngx_slab_alloc_locked((ngx_slab_pool_t *)pool, info_size);
165 | } else {
166 | info->server[i].data = ngx_pcalloc((ngx_pool_t *)pool, info_size);
167 | }
168 | if (info->server[i].data == NULL) {
169 | return NGX_ERROR;
170 | }
171 | info->server[i].len = info_size;
172 | memcpy(info->server[i].data, p, info_size);
173 |
174 | p += info_size + 1;
175 | len -= (info_size + 1);
176 | if (len <= 0) {
177 | return NGX_ERROR;
178 | }
179 | }
180 |
181 | info->area = ngx_atoi(p, len);
182 | if (info->area == NGX_ERROR) {
183 | return NGX_ERROR;
184 | }
185 |
186 | return NGX_OK;
187 | }
188 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_tair_helper.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #ifndef _NGX_HTTP_TFS_TAIR_HELPER_H_INCLUDED_
8 | #define _NGX_HTTP_TFS_TAIR_HELPER_H_INCLUDED_
9 |
10 |
11 | #include
12 | #ifdef NGX_HTTP_TFS_USE_TAIR
13 | #include
14 | #endif
15 |
16 |
17 | typedef struct {
18 | uint32_t server_addr_hash;
19 | ngx_int_t area;
20 | #ifdef NGX_HTTP_TFS_USE_TAIR
21 | ngx_http_etair_server_conf_t *server;
22 | #endif
23 | } ngx_http_tfs_tair_instance_t;
24 |
25 |
26 | typedef struct {
27 | ngx_str_t server[NGX_HTTP_TFS_TAIR_SERVER_ADDR_PART_COUNT];
28 | ngx_int_t area;
29 | } ngx_http_tfs_tair_server_addr_info_t;
30 |
31 | #ifndef NGX_HTTP_TFS_USE_TAIR
32 |
33 | #define NGX_HTTP_TAIR_BYTEARRAY 9
34 | #define NGX_HTTP_TAIR_INT 1
35 | #define NGX_HTTP_ETAIR_SUCCESS 0
36 |
37 | typedef struct {
38 |
39 | size_t len;
40 | u_char *data;
41 |
42 | ngx_uint_t type;
43 | } ngx_http_tair_data_t;
44 |
45 | typedef struct {
46 | ngx_http_tair_data_t key;
47 | ngx_http_tair_data_t *value;
48 |
49 | ngx_int_t version;
50 | ngx_int_t exptime;
51 |
52 | ngx_int_t rc;
53 | } ngx_http_tair_key_value_t;
54 |
55 | typedef void (*ngx_http_tair_handler_pt)(ngx_int_t rc, void *data);
56 | typedef void (*ngx_http_tair_get_handler_pt)(ngx_http_tair_key_value_t *kv,
57 | ngx_int_t rc, void *data);
58 | typedef void (*ngx_http_tair_mget_handler_pt)(ngx_array_t *kvs, ngx_int_t rc,
59 | void *data);
60 |
61 | #endif
62 |
63 | ngx_int_t ngx_http_tfs_tair_get_helper(ngx_http_tfs_tair_instance_t *instance,
64 | ngx_pool_t *pool, ngx_log_t *log,
65 | ngx_http_tair_data_t *key, ngx_http_tair_get_handler_pt callback,
66 | void *data);
67 |
68 | ngx_int_t ngx_http_tfs_tair_mget_helper(ngx_http_tfs_tair_instance_t *instance,
69 | ngx_pool_t *pool, ngx_log_t *log,
70 | ngx_array_t *kvs, ngx_http_tair_mget_handler_pt callback, void *data);
71 |
72 | ngx_int_t
73 | ngx_http_tfs_tair_put_helper(ngx_http_tfs_tair_instance_t *instance,
74 | ngx_pool_t *pool, ngx_log_t *log,
75 | ngx_http_tair_data_t *key, ngx_http_tair_data_t *value,
76 | ngx_int_t expire, ngx_int_t version,
77 | ngx_http_tair_handler_pt callback, void *data);
78 |
79 | ngx_int_t
80 | ngx_http_tfs_tair_delete_helper(ngx_http_tfs_tair_instance_t *instance,
81 | ngx_pool_t *pool, ngx_log_t *log,
82 | ngx_array_t *keys, ngx_http_tair_handler_pt callback, void *data);
83 |
84 | ngx_int_t
85 | ngx_http_tfs_parse_tair_server_addr_info(
86 | ngx_http_tfs_tair_server_addr_info_t *info,
87 | u_char *addr, uint32_t len, void* pool, uint8_t shared_memory);
88 |
89 |
90 |
91 | #endif /* _NGX_HTTP_TFS_TAIR_HELPER_H_INCLUDED_ */
92 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_timers.c:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #include
8 | #include
9 |
10 |
11 | static void ngx_http_tfs_timeout_handler(ngx_event_t *event);
12 |
13 |
14 | ngx_http_tfs_timers_lock_t *
15 | ngx_http_tfs_timers_init(ngx_cycle_t *cycle,
16 | u_char *lock_file)
17 | {
18 | u_char *shared;
19 | size_t size;
20 | ngx_shm_t shm;
21 | ngx_http_tfs_timers_lock_t *lock;
22 |
23 | /* cl should be equal or bigger than cache line size */
24 |
25 | size = 128; /* ngx_http_tfs_kp_mutex */
26 |
27 | shm.size = size;
28 | shm.name.len = sizeof("nginx_tfs_keepalive_zone");
29 | shm.name.data = (u_char *) "nginx_tfs_keepalive_zone";
30 | shm.log = cycle->log;
31 |
32 | if (ngx_shm_alloc(&shm) != NGX_OK) {
33 | return NULL;
34 | }
35 |
36 | shared = shm.addr;
37 |
38 | lock = ngx_palloc(cycle->pool, sizeof(ngx_http_tfs_timers_lock_t));
39 | if (lock == NULL) {
40 | return NULL;
41 | }
42 |
43 | lock->ngx_http_tfs_kp_mutex_ptr = (ngx_atomic_t *) shared;
44 | lock->ngx_http_tfs_kp_mutex.spin = (ngx_uint_t) -1;
45 |
46 | #if defined(nginx_version) && (nginx_version > 1001008)
47 |
48 | if (ngx_shmtx_create(&lock->ngx_http_tfs_kp_mutex,
49 | (ngx_shmtx_sh_t *) shared, lock_file)
50 | != NGX_OK)
51 | {
52 | return NULL;
53 | }
54 |
55 | #else
56 |
57 | if (ngx_shmtx_create(&lock->ngx_http_tfs_kp_mutex, shared, lock_file)
58 | != NGX_OK)
59 | {
60 | return NULL;
61 | }
62 | #endif
63 |
64 | return lock;
65 | }
66 |
67 |
68 | ngx_int_t
69 | ngx_http_tfs_add_rcs_timers(ngx_cycle_t *cycle,
70 | ngx_http_tfs_timers_data_t *data)
71 | {
72 | ngx_event_t *ev;
73 |
74 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cycle->log, 0,
75 | "http check tfs rc servers");
76 |
77 | ev = ngx_pcalloc(cycle->pool, sizeof(ngx_event_t));
78 | if (ev == NULL) {
79 | return NGX_ERROR;
80 | }
81 |
82 | ev->handler = ngx_http_tfs_timeout_handler;
83 | ev->log = cycle->log;
84 | ev->data = data;
85 | ev->timer_set = 0;
86 |
87 | ngx_add_timer(ev, data->upstream->rcs_interval);
88 |
89 | return NGX_OK;
90 | }
91 |
92 |
93 | ngx_int_t
94 | ngx_http_tfs_timers_finalize_request_handler(ngx_http_tfs_t *t)
95 | {
96 | ngx_event_t *event;
97 | ngx_http_tfs_timers_data_t *data;
98 |
99 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, t->log, 0, "http tfs timers finalize");
100 |
101 | event = t->finalize_data;
102 | data = event->data;
103 |
104 | ngx_destroy_pool(t->pool);
105 | ngx_shmtx_unlock(&data->lock->ngx_http_tfs_kp_mutex);
106 | ngx_add_timer(event, data->upstream->rcs_interval);
107 | return NGX_OK;
108 | }
109 |
110 |
111 | static void
112 | ngx_http_tfs_timeout_handler(ngx_event_t *event)
113 | {
114 | ngx_int_t rc;
115 | ngx_pool_t *pool;
116 | ngx_http_tfs_t *t;
117 | ngx_http_request_t *r;
118 | ngx_http_tfs_timers_data_t *data;
119 |
120 | data = event->data;
121 | if (ngx_shmtx_trylock(&data->lock->ngx_http_tfs_kp_mutex)) {
122 | if (ngx_queue_empty(&data->upstream->rc_ctx->sh->kp_queue)) {
123 | ngx_log_debug0(NGX_LOG_DEBUG_EVENT, event->log, 0,
124 | "empty rc keepalive queue");
125 | ngx_shmtx_unlock(&data->lock->ngx_http_tfs_kp_mutex);
126 | ngx_add_timer(event, data->upstream->rcs_interval);
127 | return;
128 | }
129 |
130 | pool = ngx_create_pool(8192, event->log);
131 | if (pool == NULL) {
132 | ngx_shmtx_unlock(&data->lock->ngx_http_tfs_kp_mutex);
133 | return;
134 | }
135 |
136 | /* fake ngx_http_request_t */
137 | r = ngx_pcalloc(pool, sizeof(ngx_http_request_t));
138 | if (r == NULL) {
139 | ngx_shmtx_unlock(&data->lock->ngx_http_tfs_kp_mutex);
140 | return;
141 | }
142 |
143 | r->pool = pool;
144 | r->connection = ngx_pcalloc(pool, sizeof(ngx_connection_t));
145 | if (r->connection == NULL) {
146 | ngx_shmtx_unlock(&data->lock->ngx_http_tfs_kp_mutex);
147 | return;
148 | }
149 | r->connection->log = event->log;
150 | /* in order to return from ngx_http_run_posted_requests() */
151 | r->connection->destroyed = 1;
152 |
153 | t = ngx_pcalloc(pool, sizeof(ngx_http_tfs_t));
154 | if (t == NULL) {
155 | ngx_shmtx_unlock(&data->lock->ngx_http_tfs_kp_mutex);
156 | return;
157 | }
158 |
159 | t->pool = pool;
160 | t->data = r;
161 | t->log = event->log;
162 | t->finalize_request = ngx_http_tfs_timers_finalize_request_handler;
163 | t->finalize_data = event;
164 |
165 | t->r_ctx.action.code = NGX_HTTP_TFS_ACTION_KEEPALIVE;
166 | t->r_ctx.version = 1;
167 | t->loc_conf = ngx_pcalloc(pool, sizeof(ngx_http_tfs_loc_conf_t));
168 | if (t->loc_conf == NULL) {
169 | ngx_shmtx_unlock(&data->lock->ngx_http_tfs_kp_mutex);
170 | return;
171 | }
172 | t->loc_conf->upstream = data->upstream;
173 | t->main_conf = data->main_conf;
174 |
175 | rc = ngx_http_tfs_init(t);
176 | if (rc == NGX_ERROR) {
177 | ngx_destroy_pool(pool);
178 | ngx_shmtx_unlock(&data->lock->ngx_http_tfs_kp_mutex);
179 | }
180 |
181 | } else {
182 | ngx_log_debug0(NGX_LOG_DEBUG_EVENT, event->log, 0,
183 | "tfs kp mutex lock failed");
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/src/ngx_http_tfs_timers.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #ifndef _NGX_HTTP_TFS_TIMERS_H_INCLUDED_
8 | #define _NGX_HTTP_TFS_TIMERS_H_INCLUDED_
9 |
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 |
17 | struct ngx_http_tfs_timers_lock_s {
18 | ngx_atomic_t *ngx_http_tfs_kp_mutex_ptr;
19 | ngx_shmtx_t ngx_http_tfs_kp_mutex;
20 | };
21 |
22 |
23 | struct ngx_http_tfs_timers_data_s {
24 | ngx_http_tfs_main_conf_t *main_conf;
25 | ngx_http_tfs_upstream_t *upstream;
26 | ngx_http_tfs_timers_lock_t *lock;
27 | };
28 |
29 | ngx_int_t ngx_http_tfs_add_rcs_timers(ngx_cycle_t *cycle,
30 | ngx_http_tfs_timers_data_t *data);
31 | ngx_http_tfs_timers_lock_t *ngx_http_tfs_timers_init(ngx_cycle_t *cycle,
32 | u_char *lock_file);
33 |
34 |
35 | #endif /* _NGX_HTTP_TFS_TIMERS_H_INCLUDED_ */
36 |
--------------------------------------------------------------------------------
/src/ngx_tfs_common.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) 2010-2013 Alibaba Group Holding Limited
4 | */
5 |
6 |
7 | #ifndef _NGX_HTTP_TFS_COMMON_H_INCLUDED_
8 | #define _NGX_HTTP_TFS_COMMON_H_INCLUDED_
9 |
10 |
11 | #include
12 | #include
13 |
14 | #define NGX_HTTP_TFS_HEADER 0
15 | #define NGX_HTTP_TFS_BODY 1
16 | #define NGX_HTTP_TFS_METASERVER_COUNT 10240
17 |
18 | #define NGX_HTTP_TFS_YES 1
19 | #define NGX_HTTP_TFS_NO 0
20 | #define NGX_HTTP_TFS_AGAIN -20
21 |
22 | #define NGX_HTTP_TFS_NGINX_APPKEY "tfs"
23 | #define NGX_HTTP_TFS_DEFAULT_APPID 1
24 | #define NGX_HTTP_TFS_RCS_LOCK_FILE "nginx_rcs.lock"
25 |
26 | #define NGX_HTTP_TFS_MD5_RESULT_LEN 16
27 | #define NGX_HTTP_TFS_DUPLICATE_KEY_SIZE \
28 | (sizeof(uint32_t) + NGX_HTTP_TFS_MD5_RESULT_LEN)
29 | #define NGX_HTTP_TFS_DUPLICATE_VALUE_BASE_SIZE sizeof(int32_t)
30 | #define NGX_HTTP_TFS_DUPLICATE_INITIAL_MAGIC_VERSION 0x0fffffff
31 |
32 | /* rcs, ns, ds, rs, ms */
33 | #define NGX_HTTP_TFS_SERVER_COUNT 5
34 | /* master_conifg_server;slave_config_server;group */
35 | #define NGX_HTTP_TFS_TAIR_SERVER_ADDR_PART_COUNT 3
36 | /* master && slave */
37 | #define NGX_HTTP_TFS_TAIR_CONFIG_SERVER_COUNT 2
38 |
39 | #define NGX_HTTP_TFS_KEEPALIVE_ACTION "keepalive"
40 |
41 | #define NGX_HTTP_TFS_MAX_READ_FILE_SIZE (512 * 1024)
42 | #define NGX_HTTP_TFS_USE_LARGE_FILE_SIZE (15 * 1024 * 1024)
43 | #define NGX_HTTP_TFS_MAX_SIZE (ULLONG_MAX - 1)
44 |
45 | #define NGX_HTTP_TFS_ZERO_BUF_SIZE (512 * 1024)
46 | #define NGX_HTTP_TFS_INIT_FILE_HOLE_COUNT 5
47 |
48 | #define NGX_HTTP_TFS_APPEND_OFFSET -1
49 |
50 | /* tfs file name standard name length */
51 | #define NGX_HTTP_TFS_SMALL_FILE_KEY_CHAR 'T'
52 | #define NGX_HTTP_TFS_LARGE_FILE_KEY_CHAR 'L'
53 | #define NGX_HTTP_TFS_FILE_NAME_LEN 18
54 | #define NGX_HTTP_TFS_FILE_NAME_BUFF_LEN 19
55 | #define NGX_HTTP_TFS_FILE_NAME_EXCEPT_SUFFIX_LEN 12
56 | #define NGX_HTTP_TFS_MAX_FILE_NAME_LEN 256
57 | #define NGX_HTTP_TFS_MAX_SUFFIX_LEN 109 /* 128 - 19 */
58 |
59 |
60 | #define NGX_HTTP_TFS_MAX_CLUSTER_COUNT 10
61 | #define NGX_HTTP_TFS_MAX_CLUSTER_ID_COUNT 5
62 |
63 | #define NGX_HTTP_TFS_CMD_GET_CLUSTER_ID_NS 20
64 | #define NGX_HTTP_TFS_CMD_GET_GROUP_COUNT 22
65 | #define NGX_HTTP_TFS_CMD_GET_GROUP_SEQ 23
66 |
67 | #define NGX_HTTP_TFS_GMT_TIME_SIZE \
68 | (sizeof("Mon, 28 Sep 1970 06:00:00 UTC+0800") - 1)
69 |
70 | #define NGX_HTTP_TFS_MAX_FRAGMENT_SIZE (2 * 1024 * 1024)
71 | #define NGX_HTTP_TFS_MAX_SEND_FRAG_COUNT 8
72 |
73 |
74 | #define NGX_HTTP_TFS_MUR_HASH_SEED 97
75 |
76 | #define NGX_HTTP_TFS_CLIENT_VERSION "NGINX"
77 |
78 | #define NGX_HTTP_TFS_MIN_TIMER_DELAY 1000
79 |
80 | #define NGX_HTTP_TFS_READ_STAT_NORMAL 0
81 | #define NGX_HTTP_TFS_READ_STAT_FORCE 1
82 |
83 | #define NGX_BSWAP_64(x) \
84 | ((((x) & 0xff00000000000000ull) >> 56) \
85 | | (((x) & 0x00ff000000000000ull) >> 40) \
86 | | (((x) & 0x0000ff0000000000ull) >> 24) \
87 | | (((x) & 0x000000ff00000000ull) >> 8) \
88 | | (((x) & 0x00000000ff000000ull) << 8) \
89 | | (((x) & 0x0000000000ff0000ull) << 24) \
90 | | (((x) & 0x000000000000ff00ull) << 40) \
91 | | (((x) & 0x00000000000000ffull) << 56))
92 |
93 | #define ngx_http_tfs_clear_buf(b) \
94 | (b)->pos = (b)->start; \
95 | (b)->last = (b)->start;
96 |
97 | #if (NGX_HAVE_BIG_ENDIAN)
98 |
99 | #define ngx_hton64(x) x
100 |
101 | #define ngx_ntoh64(x) x
102 |
103 | #else
104 |
105 | #define ngx_hton64(x) \
106 | NGX_BSWAP_64(x)
107 |
108 | #define ngx_ntoh64(x) \
109 | NGX_BSWAP_64(x)
110 |
111 |
112 | #endif
113 |
114 | typedef struct ngx_http_tfs_s ngx_http_tfs_t;
115 | typedef struct ngx_http_tfs_peer_connection_s ngx_http_tfs_peer_connection_t;
116 |
117 | typedef struct ngx_http_tfs_main_conf_s ngx_http_tfs_main_conf_t;
118 | typedef struct ngx_http_tfs_loc_conf_s ngx_http_tfs_loc_conf_t;
119 | typedef struct ngx_http_tfs_upstream_s ngx_http_tfs_upstream_t;
120 |
121 | typedef struct ngx_http_tfs_inet_s ngx_http_tfs_inet_t;
122 | typedef struct ngx_http_tfs_meta_hh_s ngx_http_tfs_meta_hh_t;
123 |
124 | typedef struct ngx_http_tfs_segment_data_s ngx_http_tfs_segment_data_t;
125 |
126 | typedef struct ngx_http_tfs_timers_lock_s ngx_http_tfs_timers_lock_t;
127 | typedef struct ngx_http_tfs_timers_data_s ngx_http_tfs_timers_data_t;
128 |
129 | typedef struct {
130 | uint64_t size;
131 | } ngx_http_tfs_stat_info_t;
132 |
133 |
134 | typedef struct {
135 | uint32_t crc;
136 | uint32_t data_crc;
137 | } ngx_http_tfs_crc_t;
138 |
139 |
140 | typedef struct {
141 | uint16_t code;
142 | ngx_str_t msg;
143 | } ngx_http_tfs_action_t;
144 |
145 |
146 | struct ngx_http_tfs_meta_hh_s {
147 | uint64_t app_id;
148 | uint64_t user_id;
149 | };
150 |
151 |
152 | struct ngx_http_tfs_inet_s {
153 | uint32_t ip;
154 | uint32_t port;
155 | };
156 |
157 | typedef struct {
158 | ngx_http_tfs_inet_t table[NGX_HTTP_TFS_METASERVER_COUNT];
159 | uint64_t version;
160 | } ngx_http_tfs_meta_table_t;
161 |
162 |
163 | typedef enum {
164 | NGX_HTTP_TFS_RC_SERVER = 0,
165 | NGX_HTTP_TFS_NAME_SERVER,
166 | NGX_HTTP_TFS_DATA_SERVER,
167 | NGX_HTTP_TFS_ROOT_SERVER,
168 | NGX_HTTP_TFS_META_SERVER,
169 | } ngx_http_tfs_peer_server_e;
170 |
171 |
172 | typedef enum {
173 | NGX_HTTP_TFS_STATE_WRITE_START = 0,
174 | NGX_HTTP_TFS_STATE_WRITE_GET_META_TABLE,
175 | NGX_HTTP_TFS_STATE_WRITE_CLUSTER_ID_MS,
176 | NGX_HTTP_TFS_STATE_WRITE_CLUSTER_ID_NS,
177 | NGX_HTTP_TFS_STATE_WRITE_GET_BLK_INFO,
178 | NGX_HTTP_TFS_STATE_WRITE_STAT_DUP_FILE,
179 | NGX_HTTP_TFS_STATE_WRITE_CREATE_FILE_NAME,
180 | NGX_HTTP_TFS_STATE_WRITE_WRITE_DATA,
181 | NGX_HTTP_TFS_STATE_WRITE_CLOSE_FILE,
182 | NGX_HTTP_TFS_STATE_WRITE_WRITE_MS,
183 | NGX_HTTP_TFS_STATE_WRITE_DONE,
184 | } ngx_http_tfs_state_write_e;
185 |
186 |
187 | typedef enum {
188 | NGX_HTTP_TFS_STATE_READ_START = 0,
189 | NGX_HTTP_TFS_STATE_READ_GET_META_TABLE,
190 | NGX_HTTP_TFS_STATE_READ_GET_FRAG_INFO,
191 | NGX_HTTP_TFS_STATE_READ_GET_BLK_INFO,
192 | NGX_HTTP_TFS_STATE_READ_READ_DATA,
193 | NGX_HTTP_TFS_STATE_READ_DONE,
194 | } ngx_http_tfs_state_read_e;
195 |
196 |
197 | typedef enum {
198 | NGX_HTTP_TFS_STATE_REMOVE_START = 0,
199 | NGX_HTTP_TFS_STATE_REMOVE_GET_META_TABLE,
200 | NGX_HTTP_TFS_STATE_REMOVE_GET_FRAG_INFO,
201 | NGX_HTTP_TFS_STATE_REMOVE_GET_GROUP_COUNT,
202 | NGX_HTTP_TFS_STATE_REMOVE_GET_GROUP_SEQ,
203 | NGX_HTTP_TFS_STATE_REMOVE_GET_BLK_INFO,
204 | NGX_HTTP_TFS_STATE_REMOVE_STAT_FILE,
205 | NGX_HTTP_TFS_STATE_REMOVE_READ_META_SEGMENT,
206 | NGX_HTTP_TFS_STATE_REMOVE_DELETE_DATA,
207 | NGX_HTTP_TFS_STATE_REMOVE_NOTIFY_MS,
208 | NGX_HTTP_TFS_STATE_REMOVE_DONE,
209 | } ngx_http_tfs_state_remove_e;
210 |
211 |
212 | typedef enum {
213 | NGX_HTTP_TFS_STATE_STAT_START = 0,
214 | NGX_HTTP_TFS_STATE_STAT_GET_BLK_INFO,
215 | NGX_HTTP_TFS_STATE_STAT_STAT_FILE,
216 | NGX_HTTP_TFS_STATE_STAT_DONE,
217 | } ngx_http_tfs_state_stat_e;
218 |
219 |
220 | typedef enum {
221 | NGX_HTTP_TFS_STATE_ACTION_START = 0,
222 | NGX_HTTP_TFS_STATE_ACTION_GET_META_TABLE,
223 | NGX_HTTP_TFS_STATE_ACTION_PROCESS,
224 | NGX_HTTP_TFS_STATE_ACTION_DONE,
225 | } ngx_http_tfs_state_action_e;
226 |
227 |
228 | static inline uint32_t
229 | ngx_http_tfs_crc(uint32_t crc, const char *data, size_t len)
230 | {
231 | size_t i;
232 |
233 | for (i = 0; i < len; ++i) {
234 | crc = (crc >> 8) ^ ngx_crc32_table256[(crc ^ *data++) & 0xff];
235 | }
236 |
237 | return crc;
238 | }
239 |
240 | ngx_chain_t *ngx_http_tfs_alloc_chains(ngx_pool_t *pool, size_t count);
241 | void ngx_http_tfs_free_chains(ngx_chain_t **free, ngx_chain_t **out);
242 |
243 | ngx_int_t ngx_http_tfs_test_connect(ngx_connection_t *c);
244 | uint64_t ngx_http_tfs_generate_packet_id(void);
245 |
246 | ngx_int_t ngx_http_tfs_parse_headerin(ngx_http_request_t *r,
247 | ngx_str_t *header_name, ngx_str_t *value);
248 |
249 | ngx_int_t ngx_http_tfs_compute_buf_crc(ngx_http_tfs_crc_t *t_crc, ngx_buf_t *b,
250 | size_t size, ngx_log_t *log);
251 |
252 | ngx_int_t ngx_http_tfs_peer_set_addr(ngx_pool_t *pool,
253 | ngx_http_tfs_peer_connection_t *p, ngx_http_tfs_inet_t *addr);
254 |
255 | uint32_t ngx_http_tfs_murmur_hash(u_char *data, size_t len);
256 |
257 | ngx_int_t ngx_http_tfs_parse_inet(ngx_str_t *u, ngx_http_tfs_inet_t *addr);
258 | int32_t ngx_http_tfs_raw_fsname_hash(const u_char *str, const int32_t len);
259 | ngx_int_t ngx_http_tfs_get_local_ip(ngx_str_t device, struct sockaddr_in *addr);
260 | ngx_buf_t *ngx_http_tfs_copy_buf_chain(ngx_pool_t *pool, ngx_chain_t *in);
261 | ngx_int_t ngx_http_tfs_sum_md5(ngx_chain_t *body, u_char *md5_final,
262 | ssize_t *body_size, ngx_log_t *log);
263 | u_char *ngx_http_tfs_time(u_char *buf, time_t t);
264 |
265 | ngx_int_t ngx_http_tfs_status_message(ngx_buf_t *b, ngx_str_t *action,
266 | ngx_log_t *log);
267 | ngx_int_t ngx_http_tfs_get_parent_dir(ngx_str_t *file_path,
268 | ngx_int_t *dir_level);
269 | ngx_int_t ngx_http_tfs_set_output_file_name(ngx_http_tfs_t *t);
270 | long long ngx_http_tfs_atoll(u_char *line, size_t n);
271 | ngx_int_t ngx_http_tfs_atoull(u_char *line, size_t n,
272 | unsigned long long *value);
273 | void *ngx_http_tfs_prealloc(ngx_pool_t *pool, void *p, size_t old_size,
274 | size_t new_size);
275 | uint64_t ngx_http_tfs_get_chain_buf_size(ngx_chain_t *data);
276 |
277 | void ngx_http_tfs_dump_segment_data(ngx_http_tfs_segment_data_t *segment,
278 | ngx_log_t *log);
279 | ngx_http_tfs_t *ngx_http_tfs_alloc_st(ngx_http_tfs_t *t);
280 |
281 | #define ngx_http_tfs_free_st(t) \
282 | t->next = t->parent->free_sts; \
283 | t->parent->free_sts = t; \
284 |
285 |
286 | #endif /* _NGX_HTTP_TFS_COMMON_H_INCLUDED_ */
287 |
--------------------------------------------------------------------------------