nutcracker 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +22 -0
- data/Rakefile +55 -0
- data/bin/nutcracker +2 -0
- data/ext/nutcracker/ChangeLog +66 -0
- data/ext/nutcracker/LICENSE +177 -0
- data/ext/nutcracker/Makefile.am +7 -0
- data/ext/nutcracker/Makefile.in +726 -0
- data/ext/nutcracker/NOTICE +124 -0
- data/ext/nutcracker/README.md +240 -0
- data/ext/nutcracker/aclocal.m4 +956 -0
- data/ext/nutcracker/conf/nutcracker.leaf.yml +10 -0
- data/ext/nutcracker/conf/nutcracker.root.yml +8 -0
- data/ext/nutcracker/conf/nutcracker.yml +67 -0
- data/ext/nutcracker/config.h.in +316 -0
- data/ext/nutcracker/config/config.guess +1561 -0
- data/ext/nutcracker/config/config.sub +1686 -0
- data/ext/nutcracker/config/depcomp +630 -0
- data/ext/nutcracker/config/install-sh +520 -0
- data/ext/nutcracker/config/ltmain.sh +8413 -0
- data/ext/nutcracker/config/missing +376 -0
- data/ext/nutcracker/configure +18862 -0
- data/ext/nutcracker/configure.ac +155 -0
- data/ext/nutcracker/contrib/Makefile.am +3 -0
- data/ext/nutcracker/contrib/Makefile.in +560 -0
- data/ext/nutcracker/contrib/yaml-0.1.4.tar.gz +0 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/LICENSE +19 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/Makefile.am +20 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/Makefile.in +736 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/README +27 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/aclocal.m4 +956 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config.h.in +80 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/config.guess +1561 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/config.sub +1686 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/depcomp +630 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/install-sh +520 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/ltmain.sh +8406 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/missing +376 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/configure +13085 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/configure.ac +75 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/doc/doxygen.cfg +222 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/include/yaml.h +1971 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/libtool.m4 +7357 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltoptions.m4 +368 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltsugar.m4 +123 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltversion.m4 +23 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/lt~obsolete.m4 +92 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/Makefile.am +4 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/Makefile.in +484 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/api.c +1392 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/dumper.c +394 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/emitter.c +2329 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/loader.c +432 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/parser.c +1374 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/reader.c +465 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/scanner.c +3570 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/writer.c +141 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/yaml_private.h +640 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/Makefile.am +8 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/Makefile.in +675 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-deconstructor-alt.c +800 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-deconstructor.c +1130 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-reformatter-alt.c +217 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-reformatter.c +202 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-dumper.c +311 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-emitter.c +327 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-loader.c +63 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-parser.c +63 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-scanner.c +63 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/test-reader.c +354 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/test-version.c +29 -0
- data/ext/nutcracker/extconf.rb +5 -0
- data/ext/nutcracker/m4/libtool.m4 +7376 -0
- data/ext/nutcracker/m4/ltoptions.m4 +368 -0
- data/ext/nutcracker/m4/ltsugar.m4 +123 -0
- data/ext/nutcracker/m4/ltversion.m4 +23 -0
- data/ext/nutcracker/m4/lt~obsolete.m4 +92 -0
- data/ext/nutcracker/notes/c-styleguide.txt +425 -0
- data/ext/nutcracker/notes/debug.txt +96 -0
- data/ext/nutcracker/notes/memcache.txt +123 -0
- data/ext/nutcracker/notes/recommendation.md +118 -0
- data/ext/nutcracker/notes/redis.md +415 -0
- data/ext/nutcracker/notes/socket.txt +131 -0
- data/ext/nutcracker/scripts/multi_get.sh +26 -0
- data/ext/nutcracker/scripts/nutcracker.init +73 -0
- data/ext/nutcracker/scripts/nutcracker.spec +52 -0
- data/ext/nutcracker/scripts/pipelined_read.sh +23 -0
- data/ext/nutcracker/scripts/pipelined_write.sh +29 -0
- data/ext/nutcracker/scripts/populate_memcached.sh +24 -0
- data/ext/nutcracker/scripts/redis-check.py +23 -0
- data/ext/nutcracker/scripts/redis-check.sh +564 -0
- data/ext/nutcracker/src/Makefile.am +46 -0
- data/ext/nutcracker/src/Makefile.in +726 -0
- data/ext/nutcracker/src/hashkit/Makefile.am +22 -0
- data/ext/nutcracker/src/hashkit/Makefile.in +501 -0
- data/ext/nutcracker/src/hashkit/nc_crc32.c +105 -0
- data/ext/nutcracker/src/hashkit/nc_fnv.c +82 -0
- data/ext/nutcracker/src/hashkit/nc_hashkit.h +74 -0
- data/ext/nutcracker/src/hashkit/nc_hsieh.c +93 -0
- data/ext/nutcracker/src/hashkit/nc_jenkins.c +230 -0
- data/ext/nutcracker/src/hashkit/nc_ketama.c +240 -0
- data/ext/nutcracker/src/hashkit/nc_md5.c +379 -0
- data/ext/nutcracker/src/hashkit/nc_modula.c +144 -0
- data/ext/nutcracker/src/hashkit/nc_murmur.c +99 -0
- data/ext/nutcracker/src/hashkit/nc_one_at_a_time.c +51 -0
- data/ext/nutcracker/src/hashkit/nc_random.c +146 -0
- data/ext/nutcracker/src/nc.c +573 -0
- data/ext/nutcracker/src/nc_array.c +204 -0
- data/ext/nutcracker/src/nc_array.h +73 -0
- data/ext/nutcracker/src/nc_client.c +189 -0
- data/ext/nutcracker/src/nc_client.h +28 -0
- data/ext/nutcracker/src/nc_conf.c +1766 -0
- data/ext/nutcracker/src/nc_conf.h +134 -0
- data/ext/nutcracker/src/nc_connection.c +392 -0
- data/ext/nutcracker/src/nc_connection.h +99 -0
- data/ext/nutcracker/src/nc_core.c +334 -0
- data/ext/nutcracker/src/nc_core.h +131 -0
- data/ext/nutcracker/src/nc_event.c +214 -0
- data/ext/nutcracker/src/nc_event.h +39 -0
- data/ext/nutcracker/src/nc_log.c +254 -0
- data/ext/nutcracker/src/nc_log.h +120 -0
- data/ext/nutcracker/src/nc_mbuf.c +285 -0
- data/ext/nutcracker/src/nc_mbuf.h +67 -0
- data/ext/nutcracker/src/nc_message.c +828 -0
- data/ext/nutcracker/src/nc_message.h +253 -0
- data/ext/nutcracker/src/nc_proxy.c +359 -0
- data/ext/nutcracker/src/nc_proxy.h +34 -0
- data/ext/nutcracker/src/nc_queue.h +788 -0
- data/ext/nutcracker/src/nc_rbtree.c +348 -0
- data/ext/nutcracker/src/nc_rbtree.h +47 -0
- data/ext/nutcracker/src/nc_request.c +588 -0
- data/ext/nutcracker/src/nc_response.c +332 -0
- data/ext/nutcracker/src/nc_server.c +841 -0
- data/ext/nutcracker/src/nc_server.h +143 -0
- data/ext/nutcracker/src/nc_signal.c +131 -0
- data/ext/nutcracker/src/nc_signal.h +34 -0
- data/ext/nutcracker/src/nc_stats.c +1188 -0
- data/ext/nutcracker/src/nc_stats.h +206 -0
- data/ext/nutcracker/src/nc_string.c +109 -0
- data/ext/nutcracker/src/nc_string.h +112 -0
- data/ext/nutcracker/src/nc_util.c +619 -0
- data/ext/nutcracker/src/nc_util.h +214 -0
- data/ext/nutcracker/src/proto/Makefile.am +14 -0
- data/ext/nutcracker/src/proto/Makefile.in +482 -0
- data/ext/nutcracker/src/proto/nc_memcache.c +1306 -0
- data/ext/nutcracker/src/proto/nc_proto.h +155 -0
- data/ext/nutcracker/src/proto/nc_redis.c +2102 -0
- data/lib/nutcracker.rb +7 -0
- data/lib/nutcracker/version.rb +3 -0
- metadata +194 -0
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* twemproxy - A fast and lightweight proxy for memcached protocol.
|
|
3
|
+
* Copyright (C) 2011 Twitter, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#include <unistd.h>
|
|
19
|
+
#include <sys/epoll.h>
|
|
20
|
+
|
|
21
|
+
#include <nc_core.h>
|
|
22
|
+
#include <nc_event.h>
|
|
23
|
+
|
|
24
|
+
int
|
|
25
|
+
event_init(struct context *ctx, int size)
|
|
26
|
+
{
|
|
27
|
+
int status, ep;
|
|
28
|
+
struct epoll_event *event;
|
|
29
|
+
|
|
30
|
+
ASSERT(ctx->ep < 0);
|
|
31
|
+
ASSERT(ctx->nevent != 0);
|
|
32
|
+
ASSERT(ctx->event == NULL);
|
|
33
|
+
|
|
34
|
+
ep = epoll_create(size);
|
|
35
|
+
if (ep < 0) {
|
|
36
|
+
log_error("epoll create of size %d failed: %s", size, strerror(errno));
|
|
37
|
+
return -1;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
event = nc_calloc(ctx->nevent, sizeof(*ctx->event));
|
|
41
|
+
if (event == NULL) {
|
|
42
|
+
status = close(ep);
|
|
43
|
+
if (status < 0) {
|
|
44
|
+
log_error("close e %d failed, ignored: %s", ep, strerror(errno));
|
|
45
|
+
}
|
|
46
|
+
return -1;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
ctx->ep = ep;
|
|
50
|
+
ctx->event = event;
|
|
51
|
+
|
|
52
|
+
log_debug(LOG_INFO, "e %d with nevent %d timeout %d", ctx->ep,
|
|
53
|
+
ctx->nevent, ctx->timeout);
|
|
54
|
+
|
|
55
|
+
return 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
void
|
|
59
|
+
event_deinit(struct context *ctx)
|
|
60
|
+
{
|
|
61
|
+
int status;
|
|
62
|
+
|
|
63
|
+
ASSERT(ctx->ep >= 0);
|
|
64
|
+
|
|
65
|
+
nc_free(ctx->event);
|
|
66
|
+
|
|
67
|
+
status = close(ctx->ep);
|
|
68
|
+
if (status < 0) {
|
|
69
|
+
log_error("close e %d failed, ignored: %s", ctx->ep, strerror(errno));
|
|
70
|
+
}
|
|
71
|
+
ctx->ep = -1;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
int
|
|
75
|
+
event_add_out(int ep, struct conn *c)
|
|
76
|
+
{
|
|
77
|
+
int status;
|
|
78
|
+
struct epoll_event event;
|
|
79
|
+
|
|
80
|
+
ASSERT(ep > 0);
|
|
81
|
+
ASSERT(c != NULL);
|
|
82
|
+
ASSERT(c->sd > 0);
|
|
83
|
+
ASSERT(c->recv_active);
|
|
84
|
+
|
|
85
|
+
if (c->send_active) {
|
|
86
|
+
return 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
event.events = (uint32_t)(EPOLLIN | EPOLLOUT | EPOLLET);
|
|
90
|
+
event.data.ptr = c;
|
|
91
|
+
|
|
92
|
+
status = epoll_ctl(ep, EPOLL_CTL_MOD, c->sd, &event);
|
|
93
|
+
if (status < 0) {
|
|
94
|
+
log_error("epoll ctl on e %d sd %d failed: %s", ep, c->sd,
|
|
95
|
+
strerror(errno));
|
|
96
|
+
} else {
|
|
97
|
+
c->send_active = 1;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return status;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
int
|
|
104
|
+
event_del_out(int ep, struct conn *c)
|
|
105
|
+
{
|
|
106
|
+
int status;
|
|
107
|
+
struct epoll_event event;
|
|
108
|
+
|
|
109
|
+
ASSERT(ep > 0);
|
|
110
|
+
ASSERT(c != NULL);
|
|
111
|
+
ASSERT(c->sd > 0);
|
|
112
|
+
ASSERT(c->recv_active);
|
|
113
|
+
|
|
114
|
+
if (!c->send_active) {
|
|
115
|
+
return 0;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
event.events = (uint32_t)(EPOLLIN | EPOLLET);
|
|
119
|
+
event.data.ptr = c;
|
|
120
|
+
|
|
121
|
+
status = epoll_ctl(ep, EPOLL_CTL_MOD, c->sd, &event);
|
|
122
|
+
if (status < 0) {
|
|
123
|
+
log_error("epoll ctl on e %d sd %d failed: %s", ep, c->sd,
|
|
124
|
+
strerror(errno));
|
|
125
|
+
} else {
|
|
126
|
+
c->send_active = 0;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return status;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
int
|
|
133
|
+
event_add_conn(int ep, struct conn *c)
|
|
134
|
+
{
|
|
135
|
+
int status;
|
|
136
|
+
struct epoll_event event;
|
|
137
|
+
|
|
138
|
+
ASSERT(ep > 0);
|
|
139
|
+
ASSERT(c != NULL);
|
|
140
|
+
ASSERT(c->sd > 0);
|
|
141
|
+
|
|
142
|
+
event.events = (uint32_t)(EPOLLIN | EPOLLOUT | EPOLLET);
|
|
143
|
+
event.data.ptr = c;
|
|
144
|
+
|
|
145
|
+
status = epoll_ctl(ep, EPOLL_CTL_ADD, c->sd, &event);
|
|
146
|
+
if (status < 0) {
|
|
147
|
+
log_error("epoll ctl on e %d sd %d failed: %s", ep, c->sd,
|
|
148
|
+
strerror(errno));
|
|
149
|
+
} else {
|
|
150
|
+
c->send_active = 1;
|
|
151
|
+
c->recv_active = 1;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return status;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
int
|
|
158
|
+
event_del_conn(int ep, struct conn *c)
|
|
159
|
+
{
|
|
160
|
+
int status;
|
|
161
|
+
|
|
162
|
+
ASSERT(ep > 0);
|
|
163
|
+
ASSERT(c != NULL);
|
|
164
|
+
ASSERT(c->sd > 0);
|
|
165
|
+
|
|
166
|
+
status = epoll_ctl(ep, EPOLL_CTL_DEL, c->sd, NULL);
|
|
167
|
+
if (status < 0) {
|
|
168
|
+
log_error("epoll ctl on e %d sd %d failed: %s", ep, c->sd,
|
|
169
|
+
strerror(errno));
|
|
170
|
+
} else {
|
|
171
|
+
c->recv_active = 0;
|
|
172
|
+
c->send_active = 0;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return status;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
int
|
|
179
|
+
event_wait(int ep, struct epoll_event *event, int nevent, int timeout)
|
|
180
|
+
{
|
|
181
|
+
int nsd;
|
|
182
|
+
|
|
183
|
+
ASSERT(ep > 0);
|
|
184
|
+
ASSERT(event != NULL);
|
|
185
|
+
ASSERT(nevent > 0);
|
|
186
|
+
|
|
187
|
+
for (;;) {
|
|
188
|
+
nsd = epoll_wait(ep, event, nevent, timeout);
|
|
189
|
+
if (nsd > 0) {
|
|
190
|
+
return nsd;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (nsd == 0) {
|
|
194
|
+
if (timeout == -1) {
|
|
195
|
+
log_error("epoll wait on e %d with %d events and %d timeout "
|
|
196
|
+
"returned no events", ep, nevent, timeout);
|
|
197
|
+
return -1;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return 0;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (errno == EINTR) {
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
log_error("epoll wait on e %d with %d events failed: %s", ep, nevent,
|
|
208
|
+
strerror(errno));
|
|
209
|
+
|
|
210
|
+
return -1;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
NOT_REACHED();
|
|
214
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* twemproxy - A fast and lightweight proxy for memcached protocol.
|
|
3
|
+
* Copyright (C) 2011 Twitter, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#ifndef _NC_EVENT_H_
|
|
19
|
+
#define _NC_EVENT_H_
|
|
20
|
+
|
|
21
|
+
#include <nc_core.h>
|
|
22
|
+
|
|
23
|
+
/*
|
|
24
|
+
* A hint to the kernel that is used to size the event backing store
|
|
25
|
+
* of a given epoll instance
|
|
26
|
+
*/
|
|
27
|
+
#define EVENT_SIZE_HINT 1024
|
|
28
|
+
|
|
29
|
+
int event_init(struct context *ctx, int size);
|
|
30
|
+
void event_deinit(struct context *ctx);
|
|
31
|
+
|
|
32
|
+
int event_add_out(int ep, struct conn *c);
|
|
33
|
+
int event_del_out(int ep, struct conn *c);
|
|
34
|
+
int event_add_conn(int ep, struct conn *c);
|
|
35
|
+
int event_del_conn(int ep, struct conn *c);
|
|
36
|
+
|
|
37
|
+
int event_wait(int ep, struct epoll_event *event, int nevent, int timeout);
|
|
38
|
+
|
|
39
|
+
#endif
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* twemproxy - A fast and lightweight proxy for memcached protocol.
|
|
3
|
+
* Copyright (C) 2011 Twitter, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#include <stdlib.h>
|
|
19
|
+
#include <stdarg.h>
|
|
20
|
+
#include <ctype.h>
|
|
21
|
+
#include <time.h>
|
|
22
|
+
#include <sys/stat.h>
|
|
23
|
+
#include <fcntl.h>
|
|
24
|
+
|
|
25
|
+
#include <nc_core.h>
|
|
26
|
+
|
|
27
|
+
static struct logger logger;
|
|
28
|
+
|
|
29
|
+
int
|
|
30
|
+
log_init(int level, char *name)
|
|
31
|
+
{
|
|
32
|
+
struct logger *l = &logger;
|
|
33
|
+
|
|
34
|
+
l->level = MAX(LOG_EMERG, MIN(level, LOG_PVERB));
|
|
35
|
+
l->name = name;
|
|
36
|
+
if (name == NULL || !strlen(name)) {
|
|
37
|
+
l->fd = STDERR_FILENO;
|
|
38
|
+
} else {
|
|
39
|
+
l->fd = open(name, O_WRONLY | O_APPEND | O_CREAT, 0644);
|
|
40
|
+
if (l->fd < 0) {
|
|
41
|
+
log_stderr("opening log file '%s' failed: %s", name,
|
|
42
|
+
strerror(errno));
|
|
43
|
+
return -1;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
void
|
|
51
|
+
log_deinit(void)
|
|
52
|
+
{
|
|
53
|
+
struct logger *l = &logger;
|
|
54
|
+
|
|
55
|
+
if (l->fd < 0 || l->fd == STDERR_FILENO) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
close(l->fd);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
void
|
|
63
|
+
log_reopen(void)
|
|
64
|
+
{
|
|
65
|
+
struct logger *l = &logger;
|
|
66
|
+
|
|
67
|
+
if (l->fd != STDERR_FILENO) {
|
|
68
|
+
close(l->fd);
|
|
69
|
+
l->fd = open(l->name, O_WRONLY | O_APPEND | O_CREAT, 0644);
|
|
70
|
+
if (l->fd < 0) {
|
|
71
|
+
log_stderr("reopening log file '%s' failed, ignored: %s", l->name,
|
|
72
|
+
strerror(errno));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
void
|
|
78
|
+
log_level_up(void)
|
|
79
|
+
{
|
|
80
|
+
struct logger *l = &logger;
|
|
81
|
+
|
|
82
|
+
if (l->level < LOG_PVERB) {
|
|
83
|
+
l->level++;
|
|
84
|
+
loga("up log level to %d", l->level);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
void
|
|
89
|
+
log_level_down(void)
|
|
90
|
+
{
|
|
91
|
+
struct logger *l = &logger;
|
|
92
|
+
|
|
93
|
+
if (l->level > LOG_EMERG) {
|
|
94
|
+
l->level--;
|
|
95
|
+
loga("down log level to %d", l->level);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
void
|
|
100
|
+
log_level_set(int level)
|
|
101
|
+
{
|
|
102
|
+
struct logger *l = &logger;
|
|
103
|
+
|
|
104
|
+
l->level = MAX(LOG_EMERG, MIN(level, LOG_PVERB));
|
|
105
|
+
loga("set log level to %d", l->level);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
int
|
|
109
|
+
log_loggable(int level)
|
|
110
|
+
{
|
|
111
|
+
struct logger *l = &logger;
|
|
112
|
+
|
|
113
|
+
if (level > l->level) {
|
|
114
|
+
return 0;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return 1;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
void
|
|
121
|
+
_log(const char *file, int line, int panic, const char *fmt, ...)
|
|
122
|
+
{
|
|
123
|
+
struct logger *l = &logger;
|
|
124
|
+
int len, size, errno_save;
|
|
125
|
+
char buf[LOG_MAX_LEN], *timestr;
|
|
126
|
+
va_list args;
|
|
127
|
+
struct tm *local;
|
|
128
|
+
time_t t;
|
|
129
|
+
ssize_t n;
|
|
130
|
+
|
|
131
|
+
if (l->fd < 0) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
errno_save = errno;
|
|
136
|
+
len = 0; /* length of output buffer */
|
|
137
|
+
size = LOG_MAX_LEN; /* size of output buffer */
|
|
138
|
+
|
|
139
|
+
t = time(NULL);
|
|
140
|
+
local = localtime(&t);
|
|
141
|
+
timestr = asctime(local);
|
|
142
|
+
|
|
143
|
+
len += nc_scnprintf(buf + len, size - len, "[%.*s] %s:%d ",
|
|
144
|
+
strlen(timestr) - 1, timestr, file, line);
|
|
145
|
+
|
|
146
|
+
va_start(args, fmt);
|
|
147
|
+
len += nc_vscnprintf(buf + len, size - len, fmt, args);
|
|
148
|
+
va_end(args);
|
|
149
|
+
|
|
150
|
+
buf[len++] = '\n';
|
|
151
|
+
|
|
152
|
+
n = nc_write(l->fd, buf, len);
|
|
153
|
+
if (n < 0) {
|
|
154
|
+
l->nerror++;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
errno = errno_save;
|
|
158
|
+
|
|
159
|
+
if (panic) {
|
|
160
|
+
abort();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
void
|
|
165
|
+
_log_stderr(const char *fmt, ...)
|
|
166
|
+
{
|
|
167
|
+
struct logger *l = &logger;
|
|
168
|
+
int len, size, errno_save;
|
|
169
|
+
char buf[4 * LOG_MAX_LEN];
|
|
170
|
+
va_list args;
|
|
171
|
+
ssize_t n;
|
|
172
|
+
|
|
173
|
+
errno_save = errno;
|
|
174
|
+
len = 0; /* length of output buffer */
|
|
175
|
+
size = 4 * LOG_MAX_LEN; /* size of output buffer */
|
|
176
|
+
|
|
177
|
+
va_start(args, fmt);
|
|
178
|
+
len += nc_vscnprintf(buf, size, fmt, args);
|
|
179
|
+
va_end(args);
|
|
180
|
+
|
|
181
|
+
buf[len++] = '\n';
|
|
182
|
+
|
|
183
|
+
n = nc_write(STDERR_FILENO, buf, len);
|
|
184
|
+
if (n < 0) {
|
|
185
|
+
l->nerror++;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
errno = errno_save;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/*
|
|
192
|
+
* Hexadecimal dump in the canonical hex + ascii display
|
|
193
|
+
* See -C option in man hexdump
|
|
194
|
+
*/
|
|
195
|
+
void
|
|
196
|
+
_log_hexdump(const char *file, int line, char *data, int datalen,
|
|
197
|
+
const char *fmt, ...)
|
|
198
|
+
{
|
|
199
|
+
struct logger *l = &logger;
|
|
200
|
+
char buf[8 * LOG_MAX_LEN];
|
|
201
|
+
int i, off, len, size, errno_save;
|
|
202
|
+
ssize_t n;
|
|
203
|
+
|
|
204
|
+
if (l->fd < 0) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/* log hexdump */
|
|
209
|
+
errno_save = errno;
|
|
210
|
+
off = 0; /* data offset */
|
|
211
|
+
len = 0; /* length of output buffer */
|
|
212
|
+
size = 8 * LOG_MAX_LEN; /* size of output buffer */
|
|
213
|
+
|
|
214
|
+
while (datalen != 0 && (len < size - 1)) {
|
|
215
|
+
char *save, *str;
|
|
216
|
+
unsigned char c;
|
|
217
|
+
int savelen;
|
|
218
|
+
|
|
219
|
+
len += nc_scnprintf(buf + len, size - len, "%08x ", off);
|
|
220
|
+
|
|
221
|
+
save = data;
|
|
222
|
+
savelen = datalen;
|
|
223
|
+
|
|
224
|
+
for (i = 0; datalen != 0 && i < 16; data++, datalen--, i++) {
|
|
225
|
+
c = (unsigned char)(*data);
|
|
226
|
+
str = (i == 7) ? " " : " ";
|
|
227
|
+
len += nc_scnprintf(buf + len, size - len, "%02x%s", c, str);
|
|
228
|
+
}
|
|
229
|
+
for ( ; i < 16; i++) {
|
|
230
|
+
str = (i == 7) ? " " : " ";
|
|
231
|
+
len += nc_scnprintf(buf + len, size - len, " %s", str);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
data = save;
|
|
235
|
+
datalen = savelen;
|
|
236
|
+
|
|
237
|
+
len += nc_scnprintf(buf + len, size - len, " |");
|
|
238
|
+
|
|
239
|
+
for (i = 0; datalen != 0 && i < 16; data++, datalen--, i++) {
|
|
240
|
+
c = (unsigned char)(isprint(*data) ? *data : '.');
|
|
241
|
+
len += nc_scnprintf(buf + len, size - len, "%c", c);
|
|
242
|
+
}
|
|
243
|
+
len += nc_scnprintf(buf + len, size - len, "|\n");
|
|
244
|
+
|
|
245
|
+
off += 16;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
n = nc_write(l->fd, buf, len);
|
|
249
|
+
if (n < 0) {
|
|
250
|
+
l->nerror++;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
errno = errno_save;
|
|
254
|
+
}
|