php_mysqlnd.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 7 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 2006-2018 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Authors: Andrey Hristov <andrey@php.net> |
  16. | Ulf Wendel <uw@php.net> |
  17. +----------------------------------------------------------------------+
  18. */
  19. #include "php.h"
  20. #include "mysqlnd.h"
  21. #include "mysqlnd_priv.h"
  22. #include "mysqlnd_debug.h"
  23. #include "mysqlnd_statistics.h"
  24. #include "mysqlnd_reverse_api.h"
  25. #include "ext/standard/info.h"
  26. #include "zend_smart_str.h"
  27. /* {{{ mysqlnd_functions[]
  28. *
  29. * Every user visible function must have an entry in mysqlnd_functions[].
  30. */
  31. static zend_function_entry mysqlnd_functions[] = {
  32. PHP_FE_END
  33. };
  34. /* }}} */
  35. /* {{{ mysqlnd_minfo_print_hash */
  36. PHPAPI void
  37. mysqlnd_minfo_print_hash(zval *values)
  38. {
  39. zval *values_entry;
  40. zend_string *string_key;
  41. ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(values), string_key, values_entry) {
  42. convert_to_string(values_entry);
  43. php_info_print_table_row(2, ZSTR_VAL(string_key), Z_STRVAL_P(values_entry));
  44. } ZEND_HASH_FOREACH_END();
  45. }
  46. /* }}} */
  47. /* {{{ mysqlnd_minfo_dump_plugin_stats */
  48. static int
  49. mysqlnd_minfo_dump_plugin_stats(zval *el, void * argument)
  50. {
  51. struct st_mysqlnd_plugin_header * plugin_header = (struct st_mysqlnd_plugin_header *)Z_PTR_P(el);
  52. if (plugin_header->plugin_stats.values) {
  53. char buf[64];
  54. zval values;
  55. snprintf(buf, sizeof(buf), "%s statistics", plugin_header->plugin_name);
  56. mysqlnd_fill_stats_hash(plugin_header->plugin_stats.values, plugin_header->plugin_stats.names, &values ZEND_FILE_LINE_CC);
  57. php_info_print_table_start();
  58. php_info_print_table_header(2, buf, "");
  59. mysqlnd_minfo_print_hash(&values);
  60. php_info_print_table_end();
  61. zend_array_destroy(Z_ARR(values));
  62. }
  63. return ZEND_HASH_APPLY_KEEP;
  64. }
  65. /* }}} */
  66. /* {{{ mysqlnd_minfo_dump_loaded_plugins */
  67. static int
  68. mysqlnd_minfo_dump_loaded_plugins(zval *el, void * buf)
  69. {
  70. smart_str * buffer = (smart_str *) buf;
  71. struct st_mysqlnd_plugin_header * plugin_header = (struct st_mysqlnd_plugin_header *)Z_PTR_P(el);
  72. if (plugin_header->plugin_name) {
  73. if (buffer->s) {
  74. smart_str_appendc(buffer, ',');
  75. }
  76. smart_str_appends(buffer, plugin_header->plugin_name);
  77. }
  78. return ZEND_HASH_APPLY_KEEP;
  79. }
  80. /* }}} */
  81. /* {{{ mysqlnd_minfo_dump_api_plugins */
  82. static void
  83. mysqlnd_minfo_dump_api_plugins(smart_str * buffer)
  84. {
  85. HashTable *ht = mysqlnd_reverse_api_get_api_list();
  86. MYSQLND_REVERSE_API *ext;
  87. ZEND_HASH_FOREACH_PTR(ht, ext) {
  88. if (buffer->s) {
  89. smart_str_appendc(buffer, ',');
  90. }
  91. smart_str_appends(buffer, ext->module->name);
  92. } ZEND_HASH_FOREACH_END();
  93. }
  94. /* }}} */
  95. /* {{{ PHP_MINFO_FUNCTION
  96. */
  97. PHP_MINFO_FUNCTION(mysqlnd)
  98. {
  99. char buf[32];
  100. php_info_print_table_start();
  101. php_info_print_table_header(2, "mysqlnd", "enabled");
  102. php_info_print_table_row(2, "Version", mysqlnd_get_client_info());
  103. php_info_print_table_row(2, "Compression",
  104. #ifdef MYSQLND_COMPRESSION_ENABLED
  105. "supported");
  106. #else
  107. "not supported");
  108. #endif
  109. php_info_print_table_row(2, "core SSL",
  110. #ifdef MYSQLND_SSL_SUPPORTED
  111. "supported");
  112. #else
  113. "not supported");
  114. #endif
  115. php_info_print_table_row(2, "extended SSL",
  116. #ifdef MYSQLND_HAVE_SSL
  117. "supported");
  118. #else
  119. "not supported");
  120. #endif
  121. snprintf(buf, sizeof(buf), ZEND_LONG_FMT, MYSQLND_G(net_cmd_buffer_size));
  122. php_info_print_table_row(2, "Command buffer size", buf);
  123. snprintf(buf, sizeof(buf), ZEND_LONG_FMT, MYSQLND_G(net_read_buffer_size));
  124. php_info_print_table_row(2, "Read buffer size", buf);
  125. snprintf(buf, sizeof(buf), ZEND_LONG_FMT, MYSQLND_G(net_read_timeout));
  126. php_info_print_table_row(2, "Read timeout", buf);
  127. php_info_print_table_row(2, "Collecting statistics", MYSQLND_G(collect_statistics)? "Yes":"No");
  128. php_info_print_table_row(2, "Collecting memory statistics", MYSQLND_G(collect_memory_statistics)? "Yes":"No");
  129. php_info_print_table_row(2, "Tracing", MYSQLND_G(debug)? MYSQLND_G(debug):"n/a");
  130. /* loaded plugins */
  131. {
  132. smart_str tmp_str = {0};
  133. mysqlnd_plugin_apply_with_argument(mysqlnd_minfo_dump_loaded_plugins, &tmp_str);
  134. smart_str_0(&tmp_str);
  135. php_info_print_table_row(2, "Loaded plugins", tmp_str.s? ZSTR_VAL(tmp_str.s) : "");
  136. smart_str_free(&tmp_str);
  137. mysqlnd_minfo_dump_api_plugins(&tmp_str);
  138. smart_str_0(&tmp_str);
  139. php_info_print_table_row(2, "API Extensions", tmp_str.s? ZSTR_VAL(tmp_str.s) : "");
  140. smart_str_free(&tmp_str);
  141. }
  142. php_info_print_table_end();
  143. /* Print client stats */
  144. mysqlnd_plugin_apply_with_argument(mysqlnd_minfo_dump_plugin_stats, NULL);
  145. }
  146. /* }}} */
  147. PHPAPI ZEND_DECLARE_MODULE_GLOBALS(mysqlnd)
  148. /* {{{ PHP_GINIT_FUNCTION
  149. */
  150. static PHP_GINIT_FUNCTION(mysqlnd)
  151. {
  152. #if defined(COMPILE_DL_MYSQLND) && defined(ZTS)
  153. ZEND_TSRMLS_CACHE_UPDATE();
  154. #endif
  155. mysqlnd_globals->collect_statistics = TRUE;
  156. mysqlnd_globals->collect_memory_statistics = FALSE;
  157. mysqlnd_globals->debug = NULL; /* The actual string */
  158. mysqlnd_globals->dbg = NULL; /* The DBG object*/
  159. mysqlnd_globals->trace_alloc_settings = NULL;
  160. mysqlnd_globals->trace_alloc = NULL;
  161. mysqlnd_globals->net_cmd_buffer_size = MYSQLND_NET_CMD_BUFFER_MIN_SIZE;
  162. mysqlnd_globals->net_read_buffer_size = 32768;
  163. mysqlnd_globals->net_read_timeout = 31536000;
  164. mysqlnd_globals->log_mask = 0;
  165. mysqlnd_globals->mempool_default_size = 16000;
  166. mysqlnd_globals->debug_emalloc_fail_threshold = -1;
  167. mysqlnd_globals->debug_ecalloc_fail_threshold = -1;
  168. mysqlnd_globals->debug_erealloc_fail_threshold = -1;
  169. mysqlnd_globals->debug_malloc_fail_threshold = -1;
  170. mysqlnd_globals->debug_calloc_fail_threshold = -1;
  171. mysqlnd_globals->debug_realloc_fail_threshold = -1;
  172. mysqlnd_globals->sha256_server_public_key = NULL;
  173. mysqlnd_globals->fetch_data_copy = FALSE;
  174. }
  175. /* }}} */
  176. /* {{{ PHP_INI_MH
  177. */
  178. static PHP_INI_MH(OnUpdateNetCmdBufferSize)
  179. {
  180. zend_long long_value;
  181. ZEND_ATOL(long_value, ZSTR_VAL(new_value));
  182. if (long_value < MYSQLND_NET_CMD_BUFFER_MIN_SIZE) {
  183. return FAILURE;
  184. }
  185. MYSQLND_G(net_cmd_buffer_size) = long_value;
  186. return SUCCESS;
  187. }
  188. /* }}} */
  189. /* {{{ PHP_INI_BEGIN
  190. */
  191. PHP_INI_BEGIN()
  192. STD_PHP_INI_BOOLEAN("mysqlnd.collect_statistics", "1", PHP_INI_ALL, OnUpdateBool, collect_statistics, zend_mysqlnd_globals, mysqlnd_globals)
  193. STD_PHP_INI_BOOLEAN("mysqlnd.collect_memory_statistics","0",PHP_INI_SYSTEM, OnUpdateBool, collect_memory_statistics, zend_mysqlnd_globals, mysqlnd_globals)
  194. STD_PHP_INI_ENTRY("mysqlnd.debug", NULL, PHP_INI_SYSTEM, OnUpdateString, debug, zend_mysqlnd_globals, mysqlnd_globals)
  195. STD_PHP_INI_ENTRY("mysqlnd.trace_alloc", NULL, PHP_INI_SYSTEM, OnUpdateString, trace_alloc_settings, zend_mysqlnd_globals, mysqlnd_globals)
  196. STD_PHP_INI_ENTRY("mysqlnd.net_cmd_buffer_size", MYSQLND_NET_CMD_BUFFER_MIN_SIZE_STR, PHP_INI_ALL, OnUpdateNetCmdBufferSize, net_cmd_buffer_size, zend_mysqlnd_globals, mysqlnd_globals)
  197. STD_PHP_INI_ENTRY("mysqlnd.net_read_buffer_size", "32768",PHP_INI_ALL, OnUpdateLong, net_read_buffer_size, zend_mysqlnd_globals, mysqlnd_globals)
  198. STD_PHP_INI_ENTRY("mysqlnd.net_read_timeout", "86400",PHP_INI_ALL, OnUpdateLong, net_read_timeout, zend_mysqlnd_globals, mysqlnd_globals)
  199. STD_PHP_INI_ENTRY("mysqlnd.log_mask", "0", PHP_INI_ALL, OnUpdateLong, log_mask, zend_mysqlnd_globals, mysqlnd_globals)
  200. STD_PHP_INI_ENTRY("mysqlnd.mempool_default_size","16000", PHP_INI_ALL, OnUpdateLong, mempool_default_size, zend_mysqlnd_globals, mysqlnd_globals)
  201. STD_PHP_INI_ENTRY("mysqlnd.sha256_server_public_key",NULL, PHP_INI_PERDIR, OnUpdateString, sha256_server_public_key, zend_mysqlnd_globals, mysqlnd_globals)
  202. STD_PHP_INI_BOOLEAN("mysqlnd.fetch_data_copy", "0", PHP_INI_ALL, OnUpdateBool, fetch_data_copy, zend_mysqlnd_globals, mysqlnd_globals)
  203. #if PHP_DEBUG
  204. STD_PHP_INI_ENTRY("mysqlnd.debug_emalloc_fail_threshold","-1", PHP_INI_SYSTEM, OnUpdateLong, debug_emalloc_fail_threshold, zend_mysqlnd_globals, mysqlnd_globals)
  205. STD_PHP_INI_ENTRY("mysqlnd.debug_ecalloc_fail_threshold","-1", PHP_INI_SYSTEM, OnUpdateLong, debug_ecalloc_fail_threshold, zend_mysqlnd_globals, mysqlnd_globals)
  206. STD_PHP_INI_ENTRY("mysqlnd.debug_erealloc_fail_threshold","-1", PHP_INI_SYSTEM, OnUpdateLong, debug_erealloc_fail_threshold, zend_mysqlnd_globals, mysqlnd_globals)
  207. STD_PHP_INI_ENTRY("mysqlnd.debug_malloc_fail_threshold","-1", PHP_INI_SYSTEM, OnUpdateLong, debug_malloc_fail_threshold, zend_mysqlnd_globals, mysqlnd_globals)
  208. STD_PHP_INI_ENTRY("mysqlnd.debug_calloc_fail_threshold","-1", PHP_INI_SYSTEM, OnUpdateLong, debug_calloc_fail_threshold, zend_mysqlnd_globals, mysqlnd_globals)
  209. STD_PHP_INI_ENTRY("mysqlnd.debug_realloc_fail_threshold","-1", PHP_INI_SYSTEM, OnUpdateLong, debug_realloc_fail_threshold, zend_mysqlnd_globals, mysqlnd_globals)
  210. #endif
  211. PHP_INI_END()
  212. /* }}} */
  213. /* {{{ PHP_MINIT_FUNCTION
  214. */
  215. static PHP_MINIT_FUNCTION(mysqlnd)
  216. {
  217. REGISTER_INI_ENTRIES();
  218. mysqlnd_library_init();
  219. return SUCCESS;
  220. }
  221. /* }}} */
  222. /* {{{ PHP_MSHUTDOWN_FUNCTION
  223. */
  224. static PHP_MSHUTDOWN_FUNCTION(mysqlnd)
  225. {
  226. mysqlnd_library_end();
  227. UNREGISTER_INI_ENTRIES();
  228. return SUCCESS;
  229. }
  230. /* }}} */
  231. #if PHP_DEBUG
  232. /* {{{ PHP_RINIT_FUNCTION
  233. */
  234. static PHP_RINIT_FUNCTION(mysqlnd)
  235. {
  236. if (MYSQLND_G(debug)) {
  237. struct st_mysqlnd_plugin_trace_log * trace_log_plugin = mysqlnd_plugin_find("debug_trace");
  238. MYSQLND_G(dbg) = NULL;
  239. if (trace_log_plugin) {
  240. MYSQLND_DEBUG * dbg = trace_log_plugin->methods.trace_instance_init(mysqlnd_debug_std_no_trace_funcs);
  241. MYSQLND_DEBUG * trace_alloc = trace_log_plugin->methods.trace_instance_init(NULL);
  242. if (!dbg || !trace_alloc) {
  243. return FAILURE;
  244. }
  245. dbg->m->set_mode(dbg, MYSQLND_G(debug));
  246. trace_alloc->m->set_mode(trace_alloc, MYSQLND_G(trace_alloc_settings));
  247. MYSQLND_G(dbg) = dbg;
  248. MYSQLND_G(trace_alloc) = trace_alloc;
  249. }
  250. }
  251. return SUCCESS;
  252. }
  253. /* }}} */
  254. #endif
  255. #if PHP_DEBUG
  256. /* {{{ PHP_RSHUTDOWN_FUNCTION
  257. */
  258. static PHP_RSHUTDOWN_FUNCTION(mysqlnd)
  259. {
  260. MYSQLND_DEBUG * dbg = MYSQLND_G(dbg);
  261. MYSQLND_DEBUG * trace_alloc = MYSQLND_G(trace_alloc);
  262. DBG_ENTER("RSHUTDOWN");
  263. if (dbg) {
  264. dbg->m->close(dbg);
  265. dbg->m->free_handle(dbg);
  266. MYSQLND_G(dbg) = NULL;
  267. }
  268. if (trace_alloc) {
  269. trace_alloc->m->close(trace_alloc);
  270. trace_alloc->m->free_handle(trace_alloc);
  271. MYSQLND_G(trace_alloc) = NULL;
  272. }
  273. return SUCCESS;
  274. }
  275. /* }}} */
  276. #endif
  277. static const zend_module_dep mysqlnd_deps[] = {
  278. ZEND_MOD_REQUIRED("standard")
  279. ZEND_MOD_END
  280. };
  281. /* {{{ mysqlnd_module_entry
  282. */
  283. zend_module_entry mysqlnd_module_entry = {
  284. STANDARD_MODULE_HEADER_EX,
  285. NULL,
  286. mysqlnd_deps,
  287. "mysqlnd",
  288. mysqlnd_functions,
  289. PHP_MINIT(mysqlnd),
  290. PHP_MSHUTDOWN(mysqlnd),
  291. #if PHP_DEBUG
  292. PHP_RINIT(mysqlnd),
  293. #else
  294. NULL,
  295. #endif
  296. #if PHP_DEBUG
  297. PHP_RSHUTDOWN(mysqlnd),
  298. #else
  299. NULL,
  300. #endif
  301. PHP_MINFO(mysqlnd),
  302. PHP_MYSQLND_VERSION,
  303. PHP_MODULE_GLOBALS(mysqlnd),
  304. PHP_GINIT(mysqlnd),
  305. NULL,
  306. NULL,
  307. STANDARD_MODULE_PROPERTIES_EX
  308. };
  309. /* }}} */
  310. /* {{{ COMPILE_DL_MYSQLND */
  311. #ifdef COMPILE_DL_MYSQLND
  312. #ifdef ZTS
  313. ZEND_TSRMLS_CACHE_DEFINE()
  314. #endif
  315. ZEND_GET_MODULE(mysqlnd)
  316. #endif
  317. /* }}} */
  318. /*
  319. * Local variables:
  320. * tab-width: 4
  321. * c-basic-offset: 4
  322. * End:
  323. * vim600: noet sw=4 ts=4 fdm=marker
  324. * vim<600: noet sw=4 ts=4
  325. */