1 | |
2 | // vim:sw=2:ai |
3 | |
4 | /* |
5 | * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved. |
6 | * See COPYRIGHT.txt for details. |
7 | */ |
8 | |
9 | #include <my_global.h> |
10 | #include <memory> |
11 | #include <string> |
12 | #include <stdio.h> |
13 | |
14 | #include "config.hpp" |
15 | #include "hstcpsvr.hpp" |
16 | #include "string_util.hpp" |
17 | #include "mysql_incl.hpp" |
18 | |
19 | #define DBG_LOG \ |
20 | if (dena::verbose_level >= 100) { \ |
21 | fprintf(stderr, "%s %p\n", __PRETTY_FUNCTION__, this); \ |
22 | } |
23 | #define DBG_DO(x) if (dena::verbose_level >= 100) { x; } |
24 | |
25 | #define DBG_DIR(x) |
26 | |
27 | using namespace dena; |
28 | |
29 | static char *handlersocket_address = 0; |
30 | static char *handlersocket_port = 0; |
31 | static char *handlersocket_port_wr = 0; |
32 | static unsigned int handlersocket_epoll = 1; |
33 | static unsigned int handlersocket_threads = 32; |
34 | static unsigned int handlersocket_threads_wr = 1; |
35 | static unsigned int handlersocket_timeout = 30; |
36 | static unsigned int handlersocket_backlog = 32768; |
37 | static unsigned int handlersocket_sndbuf = 0; |
38 | static unsigned int handlersocket_rcvbuf = 0; |
39 | static unsigned int handlersocket_readsize = 0; |
40 | static unsigned int handlersocket_accept_balance = 0; |
41 | static unsigned int handlersocket_wrlock_timeout = 0; |
42 | static char *handlersocket_plain_secret = 0; |
43 | static char *handlersocket_plain_secret_wr = 0; |
44 | |
45 | struct daemon_handlersocket_data { |
46 | hstcpsvr_ptr hssvr_rd; |
47 | hstcpsvr_ptr hssvr_wr; |
48 | }; |
49 | |
50 | static int |
51 | daemon_handlersocket_init(void *p) |
52 | { |
53 | DENA_VERBOSE(10, fprintf(stderr, "handlersocket: initialized\n" )); |
54 | config conf; |
55 | conf["use_epoll" ] = handlersocket_epoll ? "1" : "0" ; |
56 | if (handlersocket_address) { |
57 | conf["host" ] = handlersocket_address; |
58 | } |
59 | if (handlersocket_port) { |
60 | conf["port" ] = handlersocket_port; |
61 | } |
62 | /* |
63 | * unix domain socket |
64 | * conf["host"] = "/"; |
65 | * conf["port"] = "/tmp/handlersocket"; |
66 | */ |
67 | if (handlersocket_threads > 0) { |
68 | conf["num_threads" ] = to_stdstring(handlersocket_threads); |
69 | } else { |
70 | conf["num_threads" ] = "1" ; |
71 | } |
72 | conf["timeout" ] = to_stdstring(handlersocket_timeout); |
73 | conf["listen_backlog" ] = to_stdstring(handlersocket_backlog); |
74 | conf["sndbuf" ] = to_stdstring(handlersocket_sndbuf); |
75 | conf["rcvbuf" ] = to_stdstring(handlersocket_rcvbuf); |
76 | conf["readsize" ] = to_stdstring(handlersocket_readsize); |
77 | conf["accept_balance" ] = to_stdstring(handlersocket_accept_balance); |
78 | conf["wrlock_timeout" ] = to_stdstring(handlersocket_wrlock_timeout); |
79 | std::auto_ptr<daemon_handlersocket_data> ap(new daemon_handlersocket_data); |
80 | if (handlersocket_port != 0 && handlersocket_port_wr != handlersocket_port) { |
81 | conf["port" ] = handlersocket_port; |
82 | if (handlersocket_plain_secret) { |
83 | conf["plain_secret" ] = handlersocket_plain_secret; |
84 | } |
85 | ap->hssvr_rd = hstcpsvr_i::create(conf); |
86 | ap->hssvr_rd->start_listen(); |
87 | } |
88 | if (handlersocket_port_wr != 0) { |
89 | if (handlersocket_threads_wr > 0) { |
90 | conf["num_threads" ] = to_stdstring(handlersocket_threads_wr); |
91 | } |
92 | conf["port" ] = handlersocket_port_wr; |
93 | conf["for_write" ] = "1" ; |
94 | conf["plain_secret" ] = "" ; |
95 | if (handlersocket_plain_secret_wr) { |
96 | conf["plain_secret" ] = handlersocket_plain_secret_wr; |
97 | } |
98 | ap->hssvr_wr = hstcpsvr_i::create(conf); |
99 | ap->hssvr_wr->start_listen(); |
100 | } |
101 | st_plugin_int *const plugin = static_cast<st_plugin_int *>(p); |
102 | plugin->data = ap.release(); |
103 | return 0; |
104 | } |
105 | |
106 | static int |
107 | daemon_handlersocket_deinit(void *p) |
108 | { |
109 | DENA_VERBOSE(10, fprintf(stderr, "handlersocket: terminated\n" )); |
110 | st_plugin_int *const plugin = static_cast<st_plugin_int *>(p); |
111 | daemon_handlersocket_data *ptr = |
112 | static_cast<daemon_handlersocket_data *>(plugin->data); |
113 | delete ptr; |
114 | return 0; |
115 | } |
116 | |
117 | static struct st_mysql_daemon daemon_handlersocket_plugin = { |
118 | MYSQL_DAEMON_INTERFACE_VERSION |
119 | }; |
120 | |
121 | static MYSQL_SYSVAR_UINT(verbose, dena::verbose_level, 0, |
122 | "0..10000" , 0, 0, 10 /* default */, 0, 10000, 0); |
123 | static MYSQL_SYSVAR_UINT(epoll, handlersocket_epoll, PLUGIN_VAR_READONLY, |
124 | "0..1" , 0, 0, 1 /* default */, 0, 1, 0); |
125 | static MYSQL_SYSVAR_STR(address, handlersocket_address, |
126 | PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC, "" , NULL, NULL, NULL); |
127 | static MYSQL_SYSVAR_STR(port, handlersocket_port, |
128 | PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC, "" , NULL, NULL, NULL); |
129 | static MYSQL_SYSVAR_STR(port_wr, handlersocket_port_wr, |
130 | PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC, "" , NULL, NULL, NULL); |
131 | static MYSQL_SYSVAR_UINT(threads, handlersocket_threads, PLUGIN_VAR_READONLY, |
132 | "1..3000" , 0, 0, 16 /* default */, 1, 3000, 0); |
133 | static MYSQL_SYSVAR_UINT(threads_wr, handlersocket_threads_wr, |
134 | PLUGIN_VAR_READONLY, "1..3000" , 0, 0, 1 /* default */, 1, 3000, 0); |
135 | static MYSQL_SYSVAR_UINT(timeout, handlersocket_timeout, PLUGIN_VAR_READONLY, |
136 | "30..3600" , 0, 0, 300 /* default */, 30, 3600, 0); |
137 | static MYSQL_SYSVAR_UINT(backlog, handlersocket_backlog, PLUGIN_VAR_READONLY, |
138 | "5..1000000" , 0, 0, 32768 /* default */, 5, 1000000, 0); |
139 | static MYSQL_SYSVAR_UINT(sndbuf, handlersocket_sndbuf, PLUGIN_VAR_READONLY, |
140 | "0..16777216" , 0, 0, 0 /* default */, 0, 16777216, 0); |
141 | static MYSQL_SYSVAR_UINT(rcvbuf, handlersocket_rcvbuf, PLUGIN_VAR_READONLY, |
142 | "0..16777216" , 0, 0, 0 /* default */, 0, 16777216, 0); |
143 | static MYSQL_SYSVAR_UINT(readsize, handlersocket_readsize, PLUGIN_VAR_READONLY, |
144 | "0..16777216" , 0, 0, 0 /* default */, 0, 16777216, 0); |
145 | static MYSQL_SYSVAR_UINT(accept_balance, handlersocket_accept_balance, |
146 | PLUGIN_VAR_READONLY, "0..10000" , 0, 0, 0 /* default */, 0, 10000, 0); |
147 | static MYSQL_SYSVAR_UINT(wrlock_timeout, handlersocket_wrlock_timeout, |
148 | PLUGIN_VAR_READONLY, "0..3600" , 0, 0, 12 /* default */, 0, 3600, 0); |
149 | static MYSQL_SYSVAR_STR(plain_secret, handlersocket_plain_secret, |
150 | PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC, "" , NULL, NULL, NULL); |
151 | static MYSQL_SYSVAR_STR(plain_secret_wr, handlersocket_plain_secret_wr, |
152 | PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC, "" , NULL, NULL, NULL); |
153 | |
154 | |
155 | /* warning: type-punning to incomplete type might break strict-aliasing |
156 | * rules */ |
157 | static struct st_mysql_sys_var *daemon_handlersocket_system_variables[] = { |
158 | MYSQL_SYSVAR(verbose), |
159 | MYSQL_SYSVAR(address), |
160 | MYSQL_SYSVAR(port), |
161 | MYSQL_SYSVAR(port_wr), |
162 | MYSQL_SYSVAR(epoll), |
163 | MYSQL_SYSVAR(threads), |
164 | MYSQL_SYSVAR(threads_wr), |
165 | MYSQL_SYSVAR(timeout), |
166 | MYSQL_SYSVAR(backlog), |
167 | MYSQL_SYSVAR(sndbuf), |
168 | MYSQL_SYSVAR(rcvbuf), |
169 | MYSQL_SYSVAR(readsize), |
170 | MYSQL_SYSVAR(accept_balance), |
171 | MYSQL_SYSVAR(wrlock_timeout), |
172 | MYSQL_SYSVAR(plain_secret), |
173 | MYSQL_SYSVAR(plain_secret_wr), |
174 | 0 |
175 | }; |
176 | |
177 | static SHOW_VAR hs_status_variables[] = { |
178 | {"table_open" , (char*) &open_tables_count, SHOW_LONGLONG}, |
179 | {"table_close" , (char*) &close_tables_count, SHOW_LONGLONG}, |
180 | {"table_lock" , (char*) &lock_tables_count, SHOW_LONGLONG}, |
181 | {"table_unlock" , (char*) &unlock_tables_count, SHOW_LONGLONG}, |
182 | #if 0 |
183 | {"index_exec" , (char*) &index_exec_count, SHOW_LONGLONG}, |
184 | #endif |
185 | {NullS, NullS, SHOW_LONG} |
186 | }; |
187 | |
188 | static int show_hs_vars(THD *thd, SHOW_VAR *var, char *buff) |
189 | { |
190 | var->type= SHOW_ARRAY; |
191 | var->value= (char *) &hs_status_variables; |
192 | return 0; |
193 | } |
194 | |
195 | static SHOW_VAR daemon_handlersocket_status_variables[] = { |
196 | {"Hs" , (char*) show_hs_vars, SHOW_FUNC}, |
197 | {NullS, NullS, SHOW_LONG} |
198 | }; |
199 | |
200 | |
201 | maria_declare_plugin(handlersocket) |
202 | { |
203 | MYSQL_DAEMON_PLUGIN, |
204 | &daemon_handlersocket_plugin, |
205 | "handlersocket" , |
206 | "higuchi dot akira at dena dot jp" , |
207 | "Direct access into InnoDB" , |
208 | PLUGIN_LICENSE_BSD, |
209 | daemon_handlersocket_init, |
210 | daemon_handlersocket_deinit, |
211 | 0x0100 /* 1.0 */, |
212 | daemon_handlersocket_status_variables, |
213 | daemon_handlersocket_system_variables, |
214 | "1.0" , |
215 | MariaDB_PLUGIN_MATURITY_BETA |
216 | } |
217 | maria_declare_plugin_end; |
218 | |