prestogres 0.1.0

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.
Files changed (393) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +2 -0
  3. data/Gemfile.lock +20 -0
  4. data/LICENSE +202 -0
  5. data/NOTICE +22 -0
  6. data/README.md +217 -0
  7. data/Rakefile +13 -0
  8. data/VERSION +1 -0
  9. data/bin/prestogres +254 -0
  10. data/config/pcp.conf.sample +28 -0
  11. data/config/pgpool.conf +678 -0
  12. data/config/pool_hba.conf +84 -0
  13. data/config/pool_passwd +0 -0
  14. data/config/postgresql.conf +2 -0
  15. data/ext/.gitignore +6 -0
  16. data/ext/depend +26 -0
  17. data/ext/extconf.rb +4 -0
  18. data/ext/prestogres_config.c +12 -0
  19. data/pgpool2/.gitignore +36 -0
  20. data/pgpool2/AUTHORS +4 -0
  21. data/pgpool2/COPYING +12 -0
  22. data/pgpool2/ChangeLog +1 -0
  23. data/pgpool2/INSTALL +1 -0
  24. data/pgpool2/Makefile.am +159 -0
  25. data/pgpool2/Makefile.in +1187 -0
  26. data/pgpool2/NEWS +4960 -0
  27. data/pgpool2/README +1 -0
  28. data/pgpool2/README.euc_jp +1 -0
  29. data/pgpool2/README.online-recovery +62 -0
  30. data/pgpool2/TODO +103 -0
  31. data/pgpool2/ac_func_accept_argtypes.m4 +85 -0
  32. data/pgpool2/aclocal.m4 +1088 -0
  33. data/pgpool2/c-compiler.m4 +134 -0
  34. data/pgpool2/c-library.m4 +325 -0
  35. data/pgpool2/child.c +2097 -0
  36. data/pgpool2/config.guess +1532 -0
  37. data/pgpool2/config.h.in +332 -0
  38. data/pgpool2/config.sub +1640 -0
  39. data/pgpool2/configure +15752 -0
  40. data/pgpool2/configure.in +392 -0
  41. data/pgpool2/depcomp +522 -0
  42. data/pgpool2/doc/basebackup.sh +17 -0
  43. data/pgpool2/doc/pgpool-de.html +4220 -0
  44. data/pgpool2/doc/pgpool-en.html +5738 -0
  45. data/pgpool2/doc/pgpool-fr.html +4118 -0
  46. data/pgpool2/doc/pgpool-ja.css +198 -0
  47. data/pgpool2/doc/pgpool-ja.html +11279 -0
  48. data/pgpool2/doc/pgpool-zh_cn.html +4445 -0
  49. data/pgpool2/doc/pgpool.css +280 -0
  50. data/pgpool2/doc/pgpool_remote_start +13 -0
  51. data/pgpool2/doc/recovery.conf.sample +117 -0
  52. data/pgpool2/doc/tutorial-en.html +707 -0
  53. data/pgpool2/doc/tutorial-ja.html +422 -0
  54. data/pgpool2/doc/tutorial-memqcache-en.html +325 -0
  55. data/pgpool2/doc/tutorial-memqcache-ja.html +370 -0
  56. data/pgpool2/doc/tutorial-memqcache-zh_cn.html +322 -0
  57. data/pgpool2/doc/tutorial-watchdog-en.html +306 -0
  58. data/pgpool2/doc/tutorial-watchdog-ja.html +343 -0
  59. data/pgpool2/doc/tutorial-watchdog-zh_cn.html +301 -0
  60. data/pgpool2/doc/tutorial-zh_cn.html +537 -0
  61. data/pgpool2/doc/watchdog.png +0 -0
  62. data/pgpool2/doc/wd-en.html +236 -0
  63. data/pgpool2/doc/wd-en.jpg +0 -0
  64. data/pgpool2/doc/wd-ja.html +219 -0
  65. data/pgpool2/doc/wd-ja.jpg +0 -0
  66. data/pgpool2/doc/wd-zh_cn.html +201 -0
  67. data/pgpool2/doc/where_to_send_queries.odg +0 -0
  68. data/pgpool2/doc/where_to_send_queries.pdf +0 -0
  69. data/pgpool2/general.m4 +166 -0
  70. data/pgpool2/getopt_long.c +200 -0
  71. data/pgpool2/getopt_long.h +44 -0
  72. data/pgpool2/install-sh +251 -0
  73. data/pgpool2/ltmain.sh +8406 -0
  74. data/pgpool2/m4/libtool.m4 +7360 -0
  75. data/pgpool2/m4/ltoptions.m4 +368 -0
  76. data/pgpool2/m4/ltsugar.m4 +123 -0
  77. data/pgpool2/m4/ltversion.m4 +23 -0
  78. data/pgpool2/m4/lt~obsolete.m4 +92 -0
  79. data/pgpool2/main.c +2971 -0
  80. data/pgpool2/md5.c +444 -0
  81. data/pgpool2/md5.h +28 -0
  82. data/pgpool2/missing +360 -0
  83. data/pgpool2/mkinstalldirs +40 -0
  84. data/pgpool2/parser/Makefile.am +50 -0
  85. data/pgpool2/parser/Makefile.in +559 -0
  86. data/pgpool2/parser/copyfuncs.c +3310 -0
  87. data/pgpool2/parser/gram.c +39100 -0
  88. data/pgpool2/parser/gram.h +940 -0
  89. data/pgpool2/parser/gram.y +13408 -0
  90. data/pgpool2/parser/gramparse.h +74 -0
  91. data/pgpool2/parser/keywords.c +32 -0
  92. data/pgpool2/parser/keywords.h +39 -0
  93. data/pgpool2/parser/kwlist.h +425 -0
  94. data/pgpool2/parser/kwlookup.c +88 -0
  95. data/pgpool2/parser/list.c +1156 -0
  96. data/pgpool2/parser/makefuncs.c +518 -0
  97. data/pgpool2/parser/makefuncs.h +83 -0
  98. data/pgpool2/parser/memnodes.h +79 -0
  99. data/pgpool2/parser/nodes.c +29 -0
  100. data/pgpool2/parser/nodes.h +609 -0
  101. data/pgpool2/parser/outfuncs.c +5790 -0
  102. data/pgpool2/parser/parsenodes.h +2615 -0
  103. data/pgpool2/parser/parser.c +262 -0
  104. data/pgpool2/parser/parser.h +46 -0
  105. data/pgpool2/parser/pg_class.h +158 -0
  106. data/pgpool2/parser/pg_config_manual.h +273 -0
  107. data/pgpool2/parser/pg_list.h +352 -0
  108. data/pgpool2/parser/pg_trigger.h +147 -0
  109. data/pgpool2/parser/pg_wchar.h +492 -0
  110. data/pgpool2/parser/pool_memory.c +342 -0
  111. data/pgpool2/parser/pool_memory.h +77 -0
  112. data/pgpool2/parser/pool_parser.h +222 -0
  113. data/pgpool2/parser/pool_string.c +121 -0
  114. data/pgpool2/parser/pool_string.h +37 -0
  115. data/pgpool2/parser/primnodes.h +1280 -0
  116. data/pgpool2/parser/scan.c +4094 -0
  117. data/pgpool2/parser/scan.l +1451 -0
  118. data/pgpool2/parser/scanner.h +120 -0
  119. data/pgpool2/parser/scansup.c +221 -0
  120. data/pgpool2/parser/scansup.h +28 -0
  121. data/pgpool2/parser/snprintf.c +1102 -0
  122. data/pgpool2/parser/stringinfo.c +294 -0
  123. data/pgpool2/parser/stringinfo.h +178 -0
  124. data/pgpool2/parser/value.c +78 -0
  125. data/pgpool2/parser/value.h +62 -0
  126. data/pgpool2/parser/wchar.c +2048 -0
  127. data/pgpool2/pcp.conf.sample +28 -0
  128. data/pgpool2/pcp/Makefile.am +40 -0
  129. data/pgpool2/pcp/Makefile.in +771 -0
  130. data/pgpool2/pcp/libpcp_ext.h +250 -0
  131. data/pgpool2/pcp/md5.c +444 -0
  132. data/pgpool2/pcp/md5.h +28 -0
  133. data/pgpool2/pcp/pcp.c +1652 -0
  134. data/pgpool2/pcp/pcp.h +61 -0
  135. data/pgpool2/pcp/pcp_attach_node.c +172 -0
  136. data/pgpool2/pcp/pcp_detach_node.c +185 -0
  137. data/pgpool2/pcp/pcp_error.c +87 -0
  138. data/pgpool2/pcp/pcp_node_count.c +160 -0
  139. data/pgpool2/pcp/pcp_node_info.c +198 -0
  140. data/pgpool2/pcp/pcp_pool_status.c +166 -0
  141. data/pgpool2/pcp/pcp_proc_count.c +166 -0
  142. data/pgpool2/pcp/pcp_proc_info.c +261 -0
  143. data/pgpool2/pcp/pcp_promote_node.c +185 -0
  144. data/pgpool2/pcp/pcp_recovery_node.c +172 -0
  145. data/pgpool2/pcp/pcp_stop_pgpool.c +179 -0
  146. data/pgpool2/pcp/pcp_stream.c +385 -0
  147. data/pgpool2/pcp/pcp_stream.h +52 -0
  148. data/pgpool2/pcp/pcp_systemdb_info.c +194 -0
  149. data/pgpool2/pcp/pcp_watchdog_info.c +211 -0
  150. data/pgpool2/pcp_child.c +1493 -0
  151. data/pgpool2/pg_md5.c +305 -0
  152. data/pgpool2/pgpool.8.in +121 -0
  153. data/pgpool2/pgpool.conf +553 -0
  154. data/pgpool2/pgpool.conf.sample +666 -0
  155. data/pgpool2/pgpool.conf.sample-master-slave +665 -0
  156. data/pgpool2/pgpool.conf.sample-replication +664 -0
  157. data/pgpool2/pgpool.conf.sample-stream +664 -0
  158. data/pgpool2/pgpool.spec +264 -0
  159. data/pgpool2/pgpool_adm/TODO +7 -0
  160. data/pgpool2/pgpool_adm/pgpool_adm--1.0.sql +85 -0
  161. data/pgpool2/pgpool_adm/pgpool_adm.c +558 -0
  162. data/pgpool2/pgpool_adm/pgpool_adm.control +5 -0
  163. data/pgpool2/pgpool_adm/pgpool_adm.h +46 -0
  164. data/pgpool2/pgpool_adm/pgpool_adm.sql.in +85 -0
  165. data/pgpool2/pool.h +655 -0
  166. data/pgpool2/pool_auth.c +1390 -0
  167. data/pgpool2/pool_config.c +5007 -0
  168. data/pgpool2/pool_config.h +284 -0
  169. data/pgpool2/pool_config.l +3281 -0
  170. data/pgpool2/pool_config_md5.c +29 -0
  171. data/pgpool2/pool_connection_pool.c +812 -0
  172. data/pgpool2/pool_error.c +242 -0
  173. data/pgpool2/pool_globals.c +27 -0
  174. data/pgpool2/pool_hba.c +1723 -0
  175. data/pgpool2/pool_hba.conf.sample +67 -0
  176. data/pgpool2/pool_ip.c +567 -0
  177. data/pgpool2/pool_ip.h +65 -0
  178. data/pgpool2/pool_ipc.h +38 -0
  179. data/pgpool2/pool_lobj.c +242 -0
  180. data/pgpool2/pool_lobj.h +32 -0
  181. data/pgpool2/pool_memqcache.c +3818 -0
  182. data/pgpool2/pool_memqcache.h +268 -0
  183. data/pgpool2/pool_params.c +163 -0
  184. data/pgpool2/pool_passwd.c +249 -0
  185. data/pgpool2/pool_passwd.h +41 -0
  186. data/pgpool2/pool_path.c +193 -0
  187. data/pgpool2/pool_path.h +81 -0
  188. data/pgpool2/pool_process_context.c +247 -0
  189. data/pgpool2/pool_process_context.h +62 -0
  190. data/pgpool2/pool_process_query.c +5001 -0
  191. data/pgpool2/pool_process_reporting.c +1671 -0
  192. data/pgpool2/pool_process_reporting.h +44 -0
  193. data/pgpool2/pool_proto2.c +671 -0
  194. data/pgpool2/pool_proto_modules.c +3524 -0
  195. data/pgpool2/pool_proto_modules.h +185 -0
  196. data/pgpool2/pool_query_cache.c +1020 -0
  197. data/pgpool2/pool_query_context.c +1871 -0
  198. data/pgpool2/pool_query_context.h +105 -0
  199. data/pgpool2/pool_relcache.c +284 -0
  200. data/pgpool2/pool_relcache.h +78 -0
  201. data/pgpool2/pool_rewrite_outfuncs.c +9060 -0
  202. data/pgpool2/pool_rewrite_query.c +715 -0
  203. data/pgpool2/pool_rewrite_query.h +192 -0
  204. data/pgpool2/pool_select_walker.c +1150 -0
  205. data/pgpool2/pool_select_walker.h +68 -0
  206. data/pgpool2/pool_sema.c +161 -0
  207. data/pgpool2/pool_session_context.c +952 -0
  208. data/pgpool2/pool_session_context.h +203 -0
  209. data/pgpool2/pool_shmem.c +185 -0
  210. data/pgpool2/pool_signal.c +158 -0
  211. data/pgpool2/pool_signal.h +61 -0
  212. data/pgpool2/pool_ssl.c +339 -0
  213. data/pgpool2/pool_stream.c +962 -0
  214. data/pgpool2/pool_stream.h +61 -0
  215. data/pgpool2/pool_system.c +659 -0
  216. data/pgpool2/pool_timestamp.c +1215 -0
  217. data/pgpool2/pool_timestamp.h +38 -0
  218. data/pgpool2/pool_type.h +171 -0
  219. data/pgpool2/pool_worker_child.c +384 -0
  220. data/pgpool2/ps_status.c +404 -0
  221. data/pgpool2/recovery.c +435 -0
  222. data/pgpool2/redhat/pgpool.conf.sample.patch +52 -0
  223. data/pgpool2/redhat/pgpool.init +201 -0
  224. data/pgpool2/redhat/pgpool.sysconfig +7 -0
  225. data/pgpool2/redhat/rpm_installer/basebackup-replication.sh +53 -0
  226. data/pgpool2/redhat/rpm_installer/basebackup-stream.sh +55 -0
  227. data/pgpool2/redhat/rpm_installer/config_for_script +17 -0
  228. data/pgpool2/redhat/rpm_installer/failover.sh +64 -0
  229. data/pgpool2/redhat/rpm_installer/getsources.sh +141 -0
  230. data/pgpool2/redhat/rpm_installer/install.sh +1363 -0
  231. data/pgpool2/redhat/rpm_installer/pgpool_recovery_pitr +47 -0
  232. data/pgpool2/redhat/rpm_installer/pgpool_remote_start +15 -0
  233. data/pgpool2/redhat/rpm_installer/recovery.conf +4 -0
  234. data/pgpool2/redhat/rpm_installer/uninstall.sh +57 -0
  235. data/pgpool2/sample/dist_def_pgbench.sql +73 -0
  236. data/pgpool2/sample/pgpool.pam +3 -0
  237. data/pgpool2/sample/pgpool_recovery +20 -0
  238. data/pgpool2/sample/pgpool_recovery_pitr +19 -0
  239. data/pgpool2/sample/pgpool_remote_start +13 -0
  240. data/pgpool2/sample/replicate_def_pgbench.sql +18 -0
  241. data/pgpool2/sql/insert_lock.sql +15 -0
  242. data/pgpool2/sql/pgpool-recovery/pgpool-recovery.c +280 -0
  243. data/pgpool2/sql/pgpool-recovery/pgpool-recovery.sql.in +19 -0
  244. data/pgpool2/sql/pgpool-recovery/pgpool_recovery--1.0.sql +24 -0
  245. data/pgpool2/sql/pgpool-recovery/pgpool_recovery.control +5 -0
  246. data/pgpool2/sql/pgpool-recovery/uninstall_pgpool-recovery.sql +3 -0
  247. data/pgpool2/sql/pgpool-regclass/pgpool-regclass.c +206 -0
  248. data/pgpool2/sql/pgpool-regclass/pgpool-regclass.sql.in +4 -0
  249. data/pgpool2/sql/pgpool-regclass/pgpool_regclass--1.0.sql +7 -0
  250. data/pgpool2/sql/pgpool-regclass/pgpool_regclass.control +5 -0
  251. data/pgpool2/sql/pgpool-regclass/uninstall_pgpool-regclass.sql +1 -0
  252. data/pgpool2/sql/system_db.sql +38 -0
  253. data/pgpool2/strlcpy.c +85 -0
  254. data/pgpool2/test/C/test_extended.c +98 -0
  255. data/pgpool2/test/jdbc/.cvsignore +2 -0
  256. data/pgpool2/test/jdbc/AutoCommitTest.java +45 -0
  257. data/pgpool2/test/jdbc/BatchTest.java +55 -0
  258. data/pgpool2/test/jdbc/ColumnTest.java +60 -0
  259. data/pgpool2/test/jdbc/CreateTempTableTest.java +48 -0
  260. data/pgpool2/test/jdbc/InsertTest.java +34 -0
  261. data/pgpool2/test/jdbc/LockTest.java +36 -0
  262. data/pgpool2/test/jdbc/PgpoolTest.java +75 -0
  263. data/pgpool2/test/jdbc/README.euc_jp +73 -0
  264. data/pgpool2/test/jdbc/RunTest.java +83 -0
  265. data/pgpool2/test/jdbc/SelectTest.java +37 -0
  266. data/pgpool2/test/jdbc/UpdateTest.java +32 -0
  267. data/pgpool2/test/jdbc/expected/CreateTempTable +1 -0
  268. data/pgpool2/test/jdbc/expected/autocommit +10 -0
  269. data/pgpool2/test/jdbc/expected/batch +1 -0
  270. data/pgpool2/test/jdbc/expected/column +100 -0
  271. data/pgpool2/test/jdbc/expected/insert +1 -0
  272. data/pgpool2/test/jdbc/expected/lock +100 -0
  273. data/pgpool2/test/jdbc/expected/select +2 -0
  274. data/pgpool2/test/jdbc/expected/update +1 -0
  275. data/pgpool2/test/jdbc/pgpool.properties +7 -0
  276. data/pgpool2/test/jdbc/prepare.sql +54 -0
  277. data/pgpool2/test/jdbc/run.sh +6 -0
  278. data/pgpool2/test/parser/.cvsignore +6 -0
  279. data/pgpool2/test/parser/README +32 -0
  280. data/pgpool2/test/parser/expected/copy.out +17 -0
  281. data/pgpool2/test/parser/expected/create.out +64 -0
  282. data/pgpool2/test/parser/expected/cursor.out +37 -0
  283. data/pgpool2/test/parser/expected/delete.out +10 -0
  284. data/pgpool2/test/parser/expected/drop.out +12 -0
  285. data/pgpool2/test/parser/expected/insert.out +13 -0
  286. data/pgpool2/test/parser/expected/misc.out +28 -0
  287. data/pgpool2/test/parser/expected/prepare.out +4 -0
  288. data/pgpool2/test/parser/expected/privileges.out +31 -0
  289. data/pgpool2/test/parser/expected/scanner.out +30 -0
  290. data/pgpool2/test/parser/expected/select.out +89 -0
  291. data/pgpool2/test/parser/expected/transaction.out +38 -0
  292. data/pgpool2/test/parser/expected/update.out +11 -0
  293. data/pgpool2/test/parser/expected/v84.out +37 -0
  294. data/pgpool2/test/parser/expected/v90.out +25 -0
  295. data/pgpool2/test/parser/expected/var.out +22 -0
  296. data/pgpool2/test/parser/input/alter.sql +2 -0
  297. data/pgpool2/test/parser/input/copy.sql +17 -0
  298. data/pgpool2/test/parser/input/create.sql +64 -0
  299. data/pgpool2/test/parser/input/cursor.sql +37 -0
  300. data/pgpool2/test/parser/input/delete.sql +10 -0
  301. data/pgpool2/test/parser/input/drop.sql +12 -0
  302. data/pgpool2/test/parser/input/insert.sql +13 -0
  303. data/pgpool2/test/parser/input/misc.sql +28 -0
  304. data/pgpool2/test/parser/input/prepare.sql +4 -0
  305. data/pgpool2/test/parser/input/privileges.sql +31 -0
  306. data/pgpool2/test/parser/input/scanner.sql +34 -0
  307. data/pgpool2/test/parser/input/select.sql +89 -0
  308. data/pgpool2/test/parser/input/transaction.sql +38 -0
  309. data/pgpool2/test/parser/input/update.sql +11 -0
  310. data/pgpool2/test/parser/input/v84.sql +37 -0
  311. data/pgpool2/test/parser/input/v90.sql +38 -0
  312. data/pgpool2/test/parser/input/var.sql +22 -0
  313. data/pgpool2/test/parser/main.c +96 -0
  314. data/pgpool2/test/parser/parse_schedule +16 -0
  315. data/pgpool2/test/parser/pool.h +13 -0
  316. data/pgpool2/test/parser/run-test +62 -0
  317. data/pgpool2/test/pdo-test/README.euc_jp +58 -0
  318. data/pgpool2/test/pdo-test/SQLlist/test1.sql +3 -0
  319. data/pgpool2/test/pdo-test/SQLlist/test2.sql +3 -0
  320. data/pgpool2/test/pdo-test/collections.inc +11 -0
  321. data/pgpool2/test/pdo-test/def.inc +7 -0
  322. data/pgpool2/test/pdo-test/log.txt +0 -0
  323. data/pgpool2/test/pdo-test/mod/database.inc +36 -0
  324. data/pgpool2/test/pdo-test/mod/def.inc +0 -0
  325. data/pgpool2/test/pdo-test/mod/errorhandler.inc +27 -0
  326. data/pgpool2/test/pdo-test/pdotest.php +11 -0
  327. data/pgpool2/test/pdo-test/regsql.inc +56 -0
  328. data/pgpool2/test/pgpool_setup +898 -0
  329. data/pgpool2/test/regression/README +39 -0
  330. data/pgpool2/test/regression/clean.sh +21 -0
  331. data/pgpool2/test/regression/libs.sh +16 -0
  332. data/pgpool2/test/regression/regress.sh +166 -0
  333. data/pgpool2/test/regression/tests/001.load_balance/test.sh +128 -0
  334. data/pgpool2/test/regression/tests/002.native_replication/PgTester.java +47 -0
  335. data/pgpool2/test/regression/tests/002.native_replication/create.sql +6 -0
  336. data/pgpool2/test/regression/tests/002.native_replication/test.sh +71 -0
  337. data/pgpool2/test/regression/tests/003.failover/expected.r +6 -0
  338. data/pgpool2/test/regression/tests/003.failover/expected.s +6 -0
  339. data/pgpool2/test/regression/tests/003.failover/test.sh +45 -0
  340. data/pgpool2/test/regression/tests/004.watchdog/master.conf +12 -0
  341. data/pgpool2/test/regression/tests/004.watchdog/standby.conf +19 -0
  342. data/pgpool2/test/regression/tests/004.watchdog/test.sh +52 -0
  343. data/pgpool2/test/regression/tests/050.bug58/test.sh +50 -0
  344. data/pgpool2/test/regression/tests/051.bug60/bug.sql +12 -0
  345. data/pgpool2/test/regression/tests/051.bug60/database-clean.sql +6 -0
  346. data/pgpool2/test/regression/tests/051.bug60/database-setup.sql +28 -0
  347. data/pgpool2/test/regression/tests/051.bug60/test.sh +79 -0
  348. data/pgpool2/test/regression/tests/052.do_query/test.sh +44 -0
  349. data/pgpool2/test/regression/tests/053.insert_lock_hangs/test.sh +81 -0
  350. data/pgpool2/test/regression/tests/054.postgres_fdw/test.sh +67 -0
  351. data/pgpool2/test/regression/tests/055.backend_all_down/test.sh +52 -0
  352. data/pgpool2/test/regression/tests/056.bug63/jdbctest2.java +66 -0
  353. data/pgpool2/test/regression/tests/056.bug63/test.sh +47 -0
  354. data/pgpool2/test/regression/tests/057.bug61/test.sh +40 -0
  355. data/pgpool2/test/regression/tests/058.bug68/jdbctest3.java +45 -0
  356. data/pgpool2/test/regression/tests/058.bug68/test.sh +47 -0
  357. data/pgpool2/test/timestamp/expected/insert.out +16 -0
  358. data/pgpool2/test/timestamp/expected/misc.out +3 -0
  359. data/pgpool2/test/timestamp/expected/update.out +6 -0
  360. data/pgpool2/test/timestamp/input/insert.sql +16 -0
  361. data/pgpool2/test/timestamp/input/misc.sql +3 -0
  362. data/pgpool2/test/timestamp/input/update.sql +6 -0
  363. data/pgpool2/test/timestamp/main.c +129 -0
  364. data/pgpool2/test/timestamp/parse_schedule +3 -0
  365. data/pgpool2/test/timestamp/run-test +69 -0
  366. data/pgpool2/version.h +1 -0
  367. data/pgpool2/watchdog/Makefile.am +17 -0
  368. data/pgpool2/watchdog/Makefile.in +505 -0
  369. data/pgpool2/watchdog/test/stab.c +266 -0
  370. data/pgpool2/watchdog/test/test.c +85 -0
  371. data/pgpool2/watchdog/test/wd_child_t.c +87 -0
  372. data/pgpool2/watchdog/test/wd_lifecheck_t.c +87 -0
  373. data/pgpool2/watchdog/test/wd_packet_t.c +87 -0
  374. data/pgpool2/watchdog/test/wd_ping_t.c +20 -0
  375. data/pgpool2/watchdog/watchdog.c +408 -0
  376. data/pgpool2/watchdog/watchdog.h +209 -0
  377. data/pgpool2/watchdog/wd_child.c +444 -0
  378. data/pgpool2/watchdog/wd_ext.h +123 -0
  379. data/pgpool2/watchdog/wd_heartbeat.c +577 -0
  380. data/pgpool2/watchdog/wd_if.c +216 -0
  381. data/pgpool2/watchdog/wd_init.c +126 -0
  382. data/pgpool2/watchdog/wd_interlock.c +347 -0
  383. data/pgpool2/watchdog/wd_lifecheck.c +512 -0
  384. data/pgpool2/watchdog/wd_list.c +429 -0
  385. data/pgpool2/watchdog/wd_packet.c +1159 -0
  386. data/pgpool2/watchdog/wd_ping.c +330 -0
  387. data/pgpool2/ylwrap +223 -0
  388. data/pgsql/presto_client.py +346 -0
  389. data/pgsql/prestogres.py +156 -0
  390. data/pgsql/setup_functions.sql +21 -0
  391. data/pgsql/setup_language.sql +3 -0
  392. data/prestogres.gemspec +23 -0
  393. metadata +496 -0
@@ -0,0 +1,429 @@
1
+ /*
2
+ * $Header$
3
+ *
4
+ * Handles watchdog connection, and protocol communication with pgpool-II
5
+ *
6
+ * pgpool: a language independent connection pool server for PostgreSQL
7
+ * written by Tatsuo Ishii
8
+ *
9
+ * Copyright (c) 2003-2012 PgPool Global Development Group
10
+ *
11
+ * Permission to use, copy, modify, and distribute this software and
12
+ * its documentation for any purpose and without fee is hereby
13
+ * granted, provided that the above copyright notice appear in all
14
+ * copies and that both that copyright notice and this permission
15
+ * notice appear in supporting documentation, and that the name of the
16
+ * author not be used in advertising or publicity pertaining to
17
+ * distribution of the software without specific, written prior
18
+ * permission. The author makes no representations about the
19
+ * suitability of this software for any purpose. It is provided "as
20
+ * is" without express or implied warranty.
21
+ *
22
+ */
23
+
24
+ #include <stdio.h>
25
+ #include <string.h>
26
+ #include <stdlib.h>
27
+ #include <sys/time.h>
28
+
29
+ #include "pool.h"
30
+ #include "pool_config.h"
31
+ #include "watchdog.h"
32
+ #include "wd_ext.h"
33
+
34
+ int wd_add_wd_list(WdDesc * other_wd);
35
+ int wd_set_wd_info(WdInfo * info);
36
+ WdInfo * wd_is_exist_master(void);
37
+ WdInfo * wd_get_lock_holder(void);
38
+ WdInfo * wd_get_interlocking(void);
39
+ bool wd_are_interlocking_all(void);
40
+ void wd_set_lock_holder(WdInfo *info, bool value);
41
+ void wd_set_interlocking(WdInfo *info, bool value);
42
+ void wd_clear_interlocking_info(void);
43
+ int wd_am_I_oldest(void);
44
+ int wd_set_myself(struct timeval * tv, int status);
45
+ WdInfo * wd_is_alive_master(void);
46
+ bool wd_is_contactable_master(void);
47
+ bool wd_are_contactable_all(void);
48
+
49
+ /* add or modify watchdog information list */
50
+ int
51
+ wd_set_wd_list(char * hostname, int pgpool_port, int wd_port, char * delegate_ip, struct timeval * tv, int status)
52
+ {
53
+ int i = 0;
54
+ WdInfo * p = NULL;
55
+
56
+ if ((WD_List == NULL) || (hostname == NULL))
57
+ {
58
+ pool_error("wd_set_wd_list: memory allocate error");
59
+ return -1;
60
+ }
61
+
62
+ if (strcmp(pool_config->delegate_IP, delegate_ip))
63
+ {
64
+ pool_error("wd_set_wd_list: delegate IP mismatch error");
65
+ return -1;
66
+ }
67
+
68
+ for ( i = 0 ; i < MAX_WATCHDOG_NUM ; i ++)
69
+ {
70
+ p = (WD_List+i);
71
+
72
+ if( p->status != WD_END)
73
+ {
74
+ /* found; modify the pgpool. */
75
+ if ((!strncmp(p->hostname, hostname, sizeof(p->hostname))) &&
76
+ (p->pgpool_port == pgpool_port) &&
77
+ (p->wd_port == wd_port))
78
+ {
79
+ p->status = status;
80
+
81
+ if (tv != NULL)
82
+ {
83
+ memcpy(&(p->tv), tv, sizeof(struct timeval));
84
+ }
85
+
86
+ return i;
87
+ }
88
+ }
89
+
90
+ /* not found; add as a new pgpool */
91
+ else
92
+ {
93
+ p->status = status;
94
+ p->pgpool_port = pgpool_port;
95
+ p->wd_port = wd_port;
96
+ p->in_interlocking = false;
97
+ p->is_lock_holder = false;
98
+
99
+ strlcpy(p->hostname, hostname, sizeof(p->hostname));
100
+ strlcpy(p->delegate_ip, delegate_ip, sizeof(p->delegate_ip));
101
+
102
+ if (tv != NULL)
103
+ {
104
+ memcpy(&(p->tv), tv, sizeof(struct timeval));
105
+ }
106
+
107
+ return i;
108
+ }
109
+ }
110
+
111
+ pool_error("wd_set_wd_list: Can not add new watchdog information cause the WD_List is full.");
112
+ return -1;
113
+ }
114
+
115
+ /* add watchdog information to list using config description */
116
+ int
117
+ wd_add_wd_list(WdDesc * other_wd)
118
+ {
119
+ WdInfo * p = NULL;
120
+ int i = 0;
121
+
122
+ if (other_wd == NULL)
123
+ {
124
+ pool_error("wd_add_wd_list: memory allocate error");
125
+ return -1;
126
+ }
127
+
128
+ for ( i = 0 ; i < other_wd->num_wd ; i ++)
129
+ {
130
+ p = &(other_wd->wd_info[i]);
131
+ strlcpy(p->delegate_ip, pool_config->delegate_IP, sizeof(p->delegate_ip));
132
+ wd_set_wd_info(p);
133
+ }
134
+
135
+ return i;
136
+ }
137
+
138
+ /* set watchdog information to list */
139
+ int
140
+ wd_set_wd_info(WdInfo * info)
141
+ {
142
+ int rtn;
143
+ rtn = wd_set_wd_list(info->hostname, info->pgpool_port, info->wd_port,
144
+ info->delegate_ip, &(info->tv), info->status);
145
+ return rtn;
146
+ }
147
+
148
+ /* return master if exist, NULL if not found */
149
+ WdInfo *
150
+ wd_is_exist_master(void)
151
+ {
152
+ WdInfo * p = WD_List;
153
+
154
+ while (p->status != WD_END)
155
+ {
156
+ /* find master pgpool in the other servers */
157
+ if (p->status == WD_MASTER)
158
+ {
159
+ /* master found */
160
+ return p;
161
+ }
162
+ p++;
163
+ }
164
+ /* not found */
165
+ return NULL;
166
+ }
167
+
168
+ /* set or unset in_interlocking flag */
169
+ void
170
+ wd_set_interlocking(WdInfo *info, bool value)
171
+ {
172
+ WdInfo * p = WD_List;
173
+
174
+ while (p->status != WD_END)
175
+ {
176
+ if ((!strncmp(p->hostname, info->hostname, sizeof(p->hostname))) &&
177
+ (p->pgpool_port == info->pgpool_port) &&
178
+ (p->wd_port == info->wd_port))
179
+ {
180
+ p->in_interlocking = value;
181
+
182
+ return;
183
+ }
184
+ p++;
185
+ }
186
+ }
187
+
188
+ /* set or unset lock holder flag */
189
+ void
190
+ wd_set_lock_holder(WdInfo *info, bool value)
191
+ {
192
+ WdInfo * p = WD_List;
193
+
194
+ while (p->status != WD_END)
195
+ {
196
+ if ((!strncmp(p->hostname, info->hostname, sizeof(p->hostname))) &&
197
+ (p->pgpool_port == info->pgpool_port) &&
198
+ (p->wd_port == info->wd_port))
199
+ {
200
+ p->is_lock_holder = value;
201
+
202
+ return;
203
+ }
204
+ p++;
205
+ }
206
+ }
207
+
208
+ /* return the lock holder if exist, NULL if not found */
209
+ WdInfo *
210
+ wd_get_lock_holder(void)
211
+ {
212
+ WdInfo * p = WD_List;
213
+
214
+ while (p->status != WD_END)
215
+ {
216
+ /* find failover lock holder */
217
+ if ((p->status == WD_NORMAL || p->status == WD_MASTER) &&
218
+ p->is_lock_holder)
219
+ {
220
+ /* found */
221
+ return p;
222
+ }
223
+ p++;
224
+ }
225
+
226
+ /* not found */
227
+ return NULL;
228
+ }
229
+
230
+ /* return the pgpool in interlocking found in first, NULL if not found */
231
+ WdInfo *
232
+ wd_get_interlocking(void)
233
+ {
234
+ WdInfo * p = WD_List;
235
+
236
+ /* for updating contactable flag */
237
+ wd_update_info();
238
+
239
+ while (p->status != WD_END)
240
+ {
241
+ /* skip if not contactable */
242
+ if (!p->is_contactable)
243
+ {
244
+ p++;
245
+ continue;
246
+ }
247
+
248
+ /* find pgpool in interlocking */
249
+ if ((p->status == WD_NORMAL || p->status == WD_MASTER) &&
250
+ p->in_interlocking)
251
+ {
252
+ /* found */
253
+ return p;
254
+ }
255
+ p++;
256
+ }
257
+
258
+ /* not found */
259
+ return NULL;
260
+ }
261
+
262
+ /* if all pgpool are in interlocking return true, otherwise false */
263
+ bool
264
+ wd_are_interlocking_all(void)
265
+ {
266
+ WdInfo * p = WD_List;
267
+ bool rtn = true;
268
+
269
+ /* for updating contactable flag */
270
+ wd_update_info();
271
+
272
+ while (p->status != WD_END)
273
+ {
274
+ /* skip if not contactable */
275
+ if (!p->is_contactable)
276
+ {
277
+ p++;
278
+ continue;
279
+ }
280
+
281
+ /* find pgpool not in interlocking */
282
+ if ((p->status == WD_NORMAL || p->status == WD_MASTER) &&
283
+ !p->in_interlocking)
284
+ {
285
+ rtn = false;
286
+ }
287
+ p++;
288
+ }
289
+
290
+ return rtn;
291
+ }
292
+
293
+ /* clear flags for interlocking */
294
+ void
295
+ wd_clear_interlocking_info(void)
296
+ {
297
+ WdInfo * p = WD_List;
298
+
299
+ while (p->status != WD_END)
300
+ {
301
+ wd_set_lock_holder(p, false);
302
+ wd_set_interlocking(p, false);
303
+ p++;
304
+ }
305
+ }
306
+
307
+ int
308
+ wd_am_I_oldest(void)
309
+ {
310
+ WdInfo * p = WD_List;
311
+
312
+ p++;
313
+ while (p->status != WD_END)
314
+ {
315
+ if ((p->status == WD_NORMAL) ||
316
+ (p->status == WD_MASTER))
317
+ {
318
+ if (WD_TIME_BEFORE(p->tv, WD_MYSELF->tv))
319
+ {
320
+ return WD_NG;
321
+ }
322
+ }
323
+ p++;
324
+ }
325
+ return WD_OK;
326
+ }
327
+
328
+ int
329
+ wd_set_myself(struct timeval * tv, int status)
330
+ {
331
+ if (WD_MYSELF == NULL)
332
+ {
333
+ return WD_NG;
334
+ }
335
+
336
+ if (tv != NULL)
337
+ {
338
+ memcpy(&(WD_MYSELF->tv),tv,sizeof(struct timeval));
339
+ }
340
+
341
+ WD_MYSELF->status = status;
342
+
343
+ return WD_OK;
344
+ }
345
+
346
+ /*
347
+ * if master exists and it is alive actually return the master,
348
+ * otherwise return NULL
349
+ */
350
+ WdInfo *
351
+ wd_is_alive_master(void)
352
+ {
353
+ WdInfo * master = NULL;
354
+
355
+ if (WD_MYSELF->status == WD_MASTER)
356
+ return WD_MYSELF;
357
+
358
+ master = wd_is_exist_master();
359
+ if (master != NULL)
360
+ {
361
+ if ((!strcmp(pool_config->wd_lifecheck_method, MODE_HEARTBEAT)) ||
362
+ (!strcmp(pool_config->wd_lifecheck_method, MODE_QUERY)
363
+ && wd_ping_pgpool(master) == WD_OK))
364
+ {
365
+ return master;
366
+ }
367
+ }
368
+
369
+ pool_debug("wd_is_alive_master: alive master not found");
370
+
371
+ return NULL;
372
+ }
373
+
374
+ /*
375
+ * if master exists and it is contactable return true,
376
+ * otherwise return false
377
+ */
378
+ bool
379
+ wd_is_contactable_master(void)
380
+ {
381
+ WdInfo * master = NULL;
382
+
383
+ if (WD_MYSELF->status == WD_MASTER)
384
+ return true;
385
+
386
+ /* for updating contactable flag */
387
+ wd_update_info();
388
+
389
+ master = wd_is_exist_master();
390
+ if (master != NULL)
391
+ {
392
+ return master->is_contactable;
393
+ }
394
+
395
+ return false;
396
+ }
397
+
398
+ bool
399
+ wd_are_contactable_all(void)
400
+ {
401
+ WdInfo * p = WD_List;
402
+
403
+ /* for updating contactable flag */
404
+ wd_update_info();
405
+
406
+ while (p->status != WD_END)
407
+ {
408
+ if ((p->status == WD_NORMAL || p->status == WD_MASTER) &&
409
+ !p->is_contactable)
410
+ {
411
+ return false;
412
+ }
413
+ p++;
414
+ }
415
+
416
+ return true;
417
+ }
418
+
419
+ /*
420
+ * get watchdog information of specified index
421
+ */
422
+ WdInfo *
423
+ wd_get_watchdog_info(int wd_index)
424
+ {
425
+ if (wd_index < 0 || wd_index > pool_config->other_wd->num_wd)
426
+ return NULL;
427
+
428
+ return &WD_List[wd_index];
429
+ }
@@ -0,0 +1,1159 @@
1
+ /*
2
+ * $Header$
3
+ *
4
+ * Handles watchdog connection, and protocol communication with pgpool-II
5
+ *
6
+ * pgpool: a language independent connection pool server for PostgreSQL
7
+ * written by Tatsuo Ishii
8
+ *
9
+ * Copyright (c) 2003-2013 PgPool Global Development Group
10
+ *
11
+ * Permission to use, copy, modify, and distribute this software and
12
+ * its documentation for any purpose and without fee is hereby
13
+ * granted, provided that the above copyright notice appear in all
14
+ * copies and that both that copyright notice and this permission
15
+ * notice appear in supporting documentation, and that the name of the
16
+ * author not be used in advertising or publicity pertaining to
17
+ * distribution of the software without specific, written prior
18
+ * permission. The author makes no representations about the
19
+ * suitability of this software for any purpose. It is provided "as
20
+ * is" without express or implied warranty.
21
+ *
22
+ */
23
+
24
+ #include <pthread.h>
25
+ #include <stdio.h>
26
+ #include <errno.h>
27
+ #include <ctype.h>
28
+ #include <time.h>
29
+ #include <string.h>
30
+ #include <stdlib.h>
31
+ #include <signal.h>
32
+ #include <sys/stat.h>
33
+ #include <sys/un.h>
34
+ #include <sys/types.h>
35
+ #include <sys/socket.h>
36
+ #include <netinet/in.h>
37
+ #include <netinet/tcp.h>
38
+ #include <netdb.h>
39
+ #include <arpa/inet.h>
40
+ #include <unistd.h>
41
+ #include <fcntl.h>
42
+
43
+ #include "pool.h"
44
+ #include "pool_config.h"
45
+ #include "watchdog.h"
46
+ #include "wd_ext.h"
47
+ #include "pool_memqcache.h"
48
+
49
+ typedef enum {
50
+ WD_SEND_TO_MASTER = 0,
51
+ WD_SEND_WITHOUT_MASTER,
52
+ WD_SEND_ALL_NODES
53
+ } WD_SEND_TYPE;
54
+
55
+ int wd_startup(void);
56
+ int wd_declare(void);
57
+ int wd_stand_for_master(void);
58
+ int wd_notice_server_down(void);
59
+ int wd_update_info(void);
60
+ int wd_authentication_failed(int sock);
61
+ int wd_create_send_socket(char * hostname, int port);
62
+ int wd_create_recv_socket(int port);
63
+ int wd_accept(int sock);
64
+ int wd_send_packet(int sock, WdPacket * snd_pack);
65
+ int wd_recv_packet(int sock, WdPacket * buf);
66
+ int wd_escalation(void);
67
+ int wd_start_recovery(void);
68
+ int wd_end_recovery(void);
69
+ int wd_send_failback_request(int node_id);
70
+ int wd_degenerate_backend_set(int *node_id_set, int count);
71
+ int wd_promote_backend(int node_id);
72
+ int wd_set_node_mask (WD_PACKET_NO packet_no, int *node_id_set, int count);
73
+ int wd_send_packet_no(WD_PACKET_NO packet_no );
74
+ int wd_send_lock_packet(WD_PACKET_NO packet_no, WD_LOCK_ID lock_id);
75
+
76
+ static int wd_send_node_packet(WD_PACKET_NO packet_no, int *node_id_set, int count);
77
+ static int wd_chk_node_mask (WD_PACKET_NO packet_no, int *node_id_set, int count);
78
+
79
+ void wd_calc_hash(const char *str, int len, char *buf);
80
+ int wd_packet_to_string(WdPacket *pkt, char *str, int maxlen);
81
+
82
+ static void * wd_thread_negotiation(void * arg);
83
+ static int send_packet_for_all(WdPacket *packet);
84
+ static int send_packet_4_nodes(WdPacket *packet, WD_SEND_TYPE type);
85
+ static int hton_wd_packet(WdPacket * to, WdPacket * from);
86
+ static int ntoh_wd_packet(WdPacket * to, WdPacket * from);
87
+ static int hton_wd_node_packet(WdPacket * to, WdPacket * from);
88
+ static int ntoh_wd_node_packet(WdPacket * to, WdPacket * from);
89
+ static int hton_wd_lock_packet(WdPacket * to, WdPacket * from);
90
+ static int ntoh_wd_lock_packet(WdPacket * to, WdPacket * from);
91
+
92
+ int
93
+ wd_startup(void)
94
+ {
95
+ int rtn;
96
+
97
+ /* send add request packet */
98
+ rtn = wd_send_packet_no(WD_ADD_REQ);
99
+ return rtn;
100
+ }
101
+
102
+ int
103
+ wd_declare(void)
104
+ {
105
+ int rtn;
106
+
107
+ /* send declare new master packet */
108
+ pool_debug("wd_declare: send the packet to declare the new master");
109
+
110
+ rtn = wd_send_packet_no(WD_DECLARE_NEW_MASTER);
111
+ return rtn;
112
+ }
113
+
114
+ int
115
+ wd_stand_for_master(void)
116
+ {
117
+ int rtn;
118
+
119
+ /* send stand for master packet */
120
+ pool_debug("wd_stand_for_master: send the packet to be the new master");
121
+ rtn = wd_send_packet_no(WD_STAND_FOR_MASTER);
122
+ return rtn;
123
+ }
124
+
125
+ int
126
+ wd_notice_server_down(void)
127
+ {
128
+ int rtn;
129
+
130
+ wd_IP_down();
131
+ /* send notice server down packet */
132
+ rtn = wd_send_packet_no(WD_SERVER_DOWN);
133
+ return rtn;
134
+ }
135
+
136
+ int
137
+ wd_update_info(void)
138
+ {
139
+ int rtn;
140
+
141
+ /* send info request packet */
142
+ rtn = wd_send_packet_no(WD_INFO_REQ);
143
+ return rtn;
144
+ }
145
+
146
+ /* send authentication failed packet */
147
+ int
148
+ wd_authentication_failed(int sock)
149
+ {
150
+ int rtn;
151
+ WdPacket send_packet;
152
+
153
+ memset(&send_packet, 0, sizeof(WdPacket));
154
+
155
+ send_packet.packet_no = WD_AUTH_FAILED;
156
+ memcpy(&(send_packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo));
157
+
158
+ rtn = wd_send_packet(sock, &send_packet);
159
+
160
+ return rtn;
161
+ }
162
+
163
+ int
164
+ wd_send_packet_no(WD_PACKET_NO packet_no )
165
+ {
166
+ int rtn = WD_OK;
167
+ WdPacket packet;
168
+
169
+ memset(&packet, 0, sizeof(WdPacket));
170
+
171
+ /* set packet no and self information */
172
+ packet.packet_no = packet_no;
173
+ memcpy(&(packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo));
174
+
175
+ /* send packet for all watchdogs */
176
+ rtn = send_packet_for_all(&packet);
177
+
178
+ return rtn;
179
+ }
180
+
181
+ int
182
+ wd_create_send_socket(char * hostname, int port)
183
+ {
184
+ int sock;
185
+ int one = 1;
186
+ size_t len = 0;
187
+ struct sockaddr_in addr;
188
+ struct hostent * hp;
189
+
190
+ /* create socket */
191
+ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
192
+ {
193
+ /* socket create failed */
194
+ pool_error("wd_create_send_socket: Failed to create socket. reason: %s", strerror(errno));
195
+ return -1;
196
+ }
197
+
198
+ /* set socket option */
199
+ if ( setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *) &one, sizeof(one)) == -1 )
200
+ {
201
+ pool_error("wd_create_send_socket: setsockopt(TCP_NODELAY) failed. reason: %s", strerror(errno));
202
+ close(sock);
203
+ return -1;
204
+ }
205
+ if ( setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one)) == -1 )
206
+ {
207
+ pool_error("wd_create_send_socket: setsockopt(SO_KEEPALIVE) failed. reason: %s", strerror(errno));
208
+ close(sock);
209
+ return -1;
210
+ }
211
+
212
+ /* set sockaddr_in */
213
+ memset(&addr,0,sizeof(addr));
214
+ addr.sin_family = AF_INET;
215
+ hp = gethostbyname(hostname);
216
+ if ((hp == NULL) || (hp->h_addrtype != AF_INET))
217
+ {
218
+ hp = gethostbyaddr(hostname,strlen(hostname),AF_INET);
219
+ if ((hp == NULL) || (hp->h_addrtype != AF_INET))
220
+ {
221
+ pool_error("gethostbyname() failed: %s host: %s", hstrerror(h_errno), hostname);
222
+ close(sock);
223
+ return -1;
224
+ }
225
+ }
226
+ memmove((char *)&(addr.sin_addr), (char *)hp->h_addr, hp->h_length);
227
+ addr.sin_port = htons(port);
228
+ len = sizeof(struct sockaddr_in);
229
+
230
+ /* try to connect */
231
+ for (;;)
232
+ {
233
+ if (connect(sock,(struct sockaddr*)&addr, len) < 0)
234
+ {
235
+ if (errno == EINTR)
236
+ continue;
237
+ else if (errno == EISCONN)
238
+ {
239
+ return sock;
240
+ }
241
+ pool_log("wd_create_send_socket: connect() reports failure (%s). You can safely ignore this while starting up.",
242
+ strerror(errno));
243
+ break;
244
+ }
245
+ return sock;
246
+ }
247
+ close(sock);
248
+ return -1;
249
+ }
250
+
251
+ int
252
+ wd_create_recv_socket(int port)
253
+ {
254
+ size_t len = 0;
255
+ struct sockaddr_in addr;
256
+ int one = 1;
257
+ int sock = -1;
258
+
259
+ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
260
+ {
261
+ /* socket create failed */
262
+ pool_error("wd_create_recv_socket: Failed to create socket. reason: %s", strerror(errno));
263
+ return -1;
264
+ }
265
+ if ( fcntl(sock, F_SETFL, O_NONBLOCK) == -1)
266
+ {
267
+ /* failed to set nonblock */
268
+ pool_error("wd_create_recv_socket: Failed to set nonblock. reason: %s", strerror(errno));
269
+ close(sock);
270
+ return -1;
271
+ }
272
+ if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one)) == -1 )
273
+ {
274
+ /* setsockopt(SO_REUSEADDR) failed */
275
+ pool_error("wd_create_recv_socket: setspockopt(SO_REUSEADDR) failed. reason: %s", strerror(errno));
276
+ close(sock);
277
+ return -1;
278
+ }
279
+ if ( setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *) &one, sizeof(one)) == -1 )
280
+ {
281
+ /* setsockopt(TCP_NODELAY) failed */
282
+ pool_error("wd_create_recv_socket: setsockopt(TCP_NODELAY) failed. reason: %s", strerror(errno));
283
+ close(sock);
284
+ return -1;
285
+ }
286
+ if ( setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one)) == -1 )
287
+ {
288
+ /* setsockopt(SO_KEEPALIVE) failed */
289
+ pool_error("wd_create_recv_socket: setsockopt(SO_KEEPALIVE) failed. reason: %s", strerror(errno));
290
+ close(sock);
291
+ return -1;
292
+ }
293
+
294
+ addr.sin_family = AF_INET;
295
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
296
+ addr.sin_port = htons(port);
297
+ len = sizeof(struct sockaddr_in);
298
+
299
+ if ( bind(sock, (struct sockaddr *) & addr, len) < 0 )
300
+ {
301
+ /* bind failed */
302
+ char *host = "", *serv = "";
303
+ char hostname[NI_MAXHOST], servname[NI_MAXSERV];
304
+ if (getnameinfo((struct sockaddr *) &addr, len, hostname, sizeof(hostname), servname, sizeof(servname), 0) == 0) {
305
+ host = hostname;
306
+ serv = servname;
307
+ }
308
+ pool_error("wd_create_recv_socket: bind(%s:%s) failed. reason: %s", host, serv, strerror(errno));
309
+ close(sock);
310
+ return -1;
311
+ }
312
+
313
+ if ( listen(sock, MAX_WATCHDOG_NUM * 2) < 0 )
314
+ {
315
+ /* listen failed */
316
+ pool_error("wd_create_recv_socket: listen() failed. reason: %s", strerror(errno));
317
+ close(sock);
318
+ return -1;
319
+ }
320
+
321
+ return sock;
322
+ }
323
+
324
+ int
325
+ wd_accept(int sock)
326
+ {
327
+ int fd = -1;
328
+ fd_set rmask;
329
+ fd_set emask;
330
+ int rtn;
331
+ struct sockaddr addr;
332
+ socklen_t addrlen = sizeof(struct sockaddr);
333
+
334
+ for (;;)
335
+ {
336
+ FD_ZERO(&rmask);
337
+ FD_ZERO(&emask);
338
+ FD_SET(sock,&rmask);
339
+ FD_SET(sock,&emask);
340
+
341
+ rtn = select(sock+1, &rmask, NULL, &emask, NULL );
342
+ if ( rtn < 0 )
343
+ {
344
+ if ( errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK )
345
+ {
346
+ continue;
347
+ }
348
+ /* connection failed */
349
+ break;
350
+ }
351
+ else if ( rtn == 0 )
352
+ {
353
+ /* connection failed */
354
+ break;
355
+ }
356
+ else if ( FD_ISSET(sock, &emask) )
357
+ {
358
+ /* socket exception occurred */
359
+ break;
360
+ }
361
+ else if ( FD_ISSET(sock, &rmask) )
362
+ {
363
+ fd = accept(sock, &addr, &addrlen);
364
+ if (fd < 0)
365
+ {
366
+ if ( errno == EINTR || errno == 0 || errno == EAGAIN || errno == EWOULDBLOCK )
367
+ {
368
+ /* nothing to accept now */
369
+ continue;
370
+ }
371
+ /* accept failed */
372
+ return -1;
373
+ }
374
+ return fd;
375
+ }
376
+ }
377
+ return -1;
378
+ }
379
+
380
+ int
381
+ wd_send_packet(int sock, WdPacket * snd_pack)
382
+ {
383
+ fd_set wmask;
384
+ struct timeval timeout;
385
+ char * send_ptr = NULL;
386
+ int send_size= 0;
387
+ int buf_size = 0;
388
+ int s = 0;
389
+ int flag = 0;
390
+ int rtn;
391
+ WdPacket buf;
392
+
393
+ memset(&buf,0,sizeof(WdPacket));
394
+ if ((snd_pack->packet_no >= WD_INVALID) &&
395
+ (snd_pack->packet_no <= WD_READY ))
396
+ {
397
+ hton_wd_packet((WdPacket *)&buf,snd_pack);
398
+ }
399
+ else if ((snd_pack->packet_no >= WD_START_RECOVERY) &&
400
+ (snd_pack->packet_no <= WD_NODE_FAILED))
401
+ {
402
+ hton_wd_node_packet((WdPacket *)&buf,snd_pack);
403
+ }
404
+ else
405
+ {
406
+ hton_wd_lock_packet((WdPacket *)&buf,snd_pack);
407
+ }
408
+
409
+ send_ptr = (char*)&buf;
410
+ buf_size = sizeof(WdPacket);
411
+
412
+ for (;;)
413
+ {
414
+ timeout.tv_sec = WD_SEND_TIMEOUT;
415
+ timeout.tv_usec = 0;
416
+
417
+ FD_ZERO(&wmask);
418
+ FD_SET(sock,&wmask);
419
+ rtn = select(sock+1, (fd_set *)NULL, &wmask, (fd_set *)NULL, &timeout);
420
+
421
+ if (rtn < 0 )
422
+ {
423
+ if (errno == EAGAIN || errno == EINTR)
424
+ {
425
+ continue;
426
+ }
427
+ return WD_NG;
428
+ }
429
+ else if (rtn & FD_ISSET(sock, &wmask))
430
+ {
431
+ s = send(sock,send_ptr + send_size,buf_size - send_size ,flag);
432
+ if (s < 0)
433
+ {
434
+ if (errno == EINTR || errno == EAGAIN)
435
+ continue;
436
+ else
437
+ {
438
+ /* send failed */
439
+ return WD_NG;
440
+ }
441
+ }
442
+ else if (s == 0)
443
+ {
444
+ /* send failed */
445
+ return WD_NG;
446
+ }
447
+ else /* s > 0 */
448
+ {
449
+ send_size += s;
450
+ if (send_size == buf_size)
451
+ {
452
+ return WD_OK;
453
+ }
454
+ }
455
+ }
456
+ }
457
+ return WD_NG;
458
+ }
459
+
460
+ int
461
+ wd_recv_packet(int sock, WdPacket * recv_pack)
462
+ {
463
+ int r = 0;
464
+ WdPacket buf;
465
+ char * read_ptr = (char *)&buf;
466
+ int read_size = 0;
467
+ int len = sizeof(WdPacket);
468
+
469
+ memset(&buf,0,sizeof(WdPacket));
470
+ for (;;)
471
+ {
472
+ r = recv(sock,read_ptr + read_size ,len - read_size, 0);
473
+ if (r < 0)
474
+ {
475
+ if (errno == EINTR || errno == EAGAIN)
476
+ continue;
477
+ else
478
+ {
479
+ pool_error("wd_recv_packet: recv failed");
480
+ return WD_NG;
481
+ }
482
+ }
483
+ else if (r > 0)
484
+ {
485
+ read_size += r;
486
+ if (read_size == len)
487
+ {
488
+
489
+ if (ntohl(buf.packet_no) <= WD_READY)
490
+ {
491
+ ntoh_wd_packet(recv_pack,&buf);
492
+ }
493
+ else if (ntohl((buf.packet_no) >= WD_START_RECOVERY) &&
494
+ (ntohl(buf.packet_no) <= WD_NODE_FAILED))
495
+ {
496
+ ntoh_wd_node_packet(recv_pack,&buf);
497
+ }
498
+ else
499
+ {
500
+ ntoh_wd_lock_packet(recv_pack,&buf);
501
+ }
502
+
503
+ return WD_OK;
504
+ }
505
+ }
506
+ else /* r == 0 */
507
+ {
508
+ return WD_NG;
509
+ }
510
+ }
511
+ return WD_NG;
512
+ }
513
+
514
+ static void *
515
+ wd_thread_negotiation(void * arg)
516
+ {
517
+ WdPacketThreadArg * thread_arg;
518
+ int sock;
519
+ uintptr_t rtn;
520
+ WdPacket recv_packet;
521
+ WdInfo * p;
522
+ char pack_str[WD_MAX_PACKET_STRING];
523
+ int pack_str_len;
524
+
525
+ thread_arg = (WdPacketThreadArg *)arg;
526
+ sock = thread_arg->sock;
527
+
528
+ gettimeofday(&(thread_arg->packet->send_time), NULL);
529
+
530
+ if (strlen(pool_config->wd_authkey))
531
+ {
532
+ /* calculate hash from packet */
533
+ pack_str_len = wd_packet_to_string(thread_arg->packet, pack_str, sizeof(pack_str));
534
+ wd_calc_hash(pack_str, pack_str_len, thread_arg->packet->hash);
535
+ }
536
+
537
+ /* packet send to target watchdog */
538
+ rtn = (uintptr_t)wd_send_packet(sock, thread_arg->packet);
539
+ if (rtn != WD_OK)
540
+ {
541
+ close(sock);
542
+ pthread_exit((void *)rtn);
543
+ }
544
+
545
+ /* receive response packet */
546
+ memset(&recv_packet,0,sizeof(WdPacket));
547
+ rtn = (uintptr_t)wd_recv_packet(sock, &recv_packet);
548
+ if (rtn != WD_OK)
549
+ {
550
+ close(sock);
551
+ pthread_exit((void *)rtn);
552
+ }
553
+ rtn = WD_OK;
554
+
555
+ switch (thread_arg->packet->packet_no)
556
+ {
557
+ case WD_ADD_REQ:
558
+ if (recv_packet.packet_no == WD_ADD_ACCEPT)
559
+ {
560
+ memcpy(thread_arg->target, &(recv_packet.wd_body.wd_info),sizeof(WdInfo));
561
+ }
562
+ else
563
+ {
564
+ rtn = WD_NG;
565
+ }
566
+ break;
567
+ case WD_STAND_FOR_MASTER:
568
+ if (recv_packet.packet_no == WD_MASTER_EXIST)
569
+ {
570
+ p = &(recv_packet.wd_body.wd_info);
571
+ wd_set_wd_info(p);
572
+ rtn = WD_NG;
573
+ }
574
+ break;
575
+ case WD_STAND_FOR_LOCK_HOLDER:
576
+ case WD_DECLARE_LOCK_HOLDER:
577
+ if (recv_packet.packet_no == WD_LOCK_HOLDER_EXIST)
578
+ {
579
+ rtn = WD_NG;
580
+ }
581
+ break;
582
+ case WD_DECLARE_NEW_MASTER:
583
+ case WD_RESIGN_LOCK_HOLDER:
584
+
585
+ if (recv_packet.packet_no != WD_READY)
586
+ {
587
+ rtn = WD_NG;
588
+ }
589
+ break;
590
+ case WD_START_RECOVERY:
591
+ case WD_FAILBACK_REQUEST:
592
+ case WD_DEGENERATE_BACKEND:
593
+ case WD_PROMOTE_BACKEND:
594
+ rtn = (recv_packet.packet_no == WD_NODE_FAILED) ? WD_NG : WD_OK;
595
+ break;
596
+ case WD_UNLOCK_REQUEST:
597
+ rtn = (recv_packet.packet_no == WD_LOCK_FAILED) ? WD_NG : WD_OK;
598
+ break;
599
+ case WD_AUTH_FAILED:
600
+ pool_log("wd_thread_negotiation: watchdog authentication failed");
601
+ rtn = WD_NG;
602
+ break;
603
+ default:
604
+ break;
605
+ }
606
+ close(sock);
607
+ pthread_exit((void *)rtn);
608
+ }
609
+
610
+ static int
611
+ send_packet_for_all(WdPacket *packet)
612
+ {
613
+ int rtn = WD_OK;
614
+
615
+ /* send packet to master watchdog */
616
+ if (WD_MYSELF->status != WD_MASTER)
617
+ rtn = send_packet_4_nodes(packet, WD_SEND_TO_MASTER );
618
+
619
+ /* send packet to other watchdogs */
620
+ if (rtn == WD_OK)
621
+ {
622
+ rtn = send_packet_4_nodes(packet, WD_SEND_WITHOUT_MASTER);
623
+ }
624
+
625
+ return rtn;
626
+ }
627
+
628
+ static int
629
+ send_packet_4_nodes(WdPacket *packet, WD_SEND_TYPE type)
630
+ {
631
+ int rtn;
632
+ WdInfo * p = WD_List;
633
+ int i,cnt;
634
+ int sock;
635
+ int rc;
636
+ pthread_attr_t attr;
637
+ pthread_t thread[MAX_WATCHDOG_NUM];
638
+ WdPacketThreadArg thread_arg[MAX_WATCHDOG_NUM];
639
+
640
+ if (packet == NULL)
641
+ {
642
+ return WD_NG;
643
+ }
644
+
645
+ /* thread init */
646
+ pthread_attr_init(&attr);
647
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
648
+
649
+ /* skip myself */
650
+ p++;
651
+ WD_MYSELF->is_contactable = true;
652
+
653
+ /* send packet to other watchdogs */
654
+ cnt = 0;
655
+ while (p->status != WD_END)
656
+ {
657
+ /* don't send packet to pgpool in down */
658
+ if (p->status == WD_DOWN ||
659
+ (packet->packet_no != WD_ADD_REQ && p->status == WD_INIT))
660
+ {
661
+ p->is_contactable = false;
662
+ p++;
663
+ continue;
664
+ }
665
+
666
+ if (type == WD_SEND_TO_MASTER )
667
+ {
668
+ if (p->status != WD_MASTER)
669
+ {
670
+ p++;
671
+ continue;
672
+ }
673
+ }
674
+ else if (type == WD_SEND_WITHOUT_MASTER )
675
+ {
676
+ if (p->status == WD_MASTER)
677
+ {
678
+ p++;
679
+ continue;
680
+ }
681
+ }
682
+
683
+ sock = wd_create_send_socket(p->hostname, p->wd_port);
684
+ if (sock == -1)
685
+ {
686
+ pool_log("send_packet_4_nodes: packet for %s:%d is canceled", p->hostname, p->wd_port);
687
+ p->is_contactable = false;
688
+ p++;
689
+ continue;
690
+ }
691
+ else
692
+ {
693
+ p->is_contactable = true;
694
+ }
695
+
696
+ thread_arg[cnt].sock = sock;
697
+ thread_arg[cnt].target = p;
698
+ thread_arg[cnt].packet = packet;
699
+ rc = pthread_create(&thread[cnt], &attr, wd_thread_negotiation, (void*)&thread_arg[cnt]);
700
+
701
+ cnt ++;
702
+ p++;
703
+ }
704
+
705
+ pthread_attr_destroy(&attr);
706
+
707
+ /* no packet is sent */
708
+ if (cnt == 0)
709
+ {
710
+ return WD_OK;
711
+ }
712
+
713
+ /* default return value */
714
+ if ((packet->packet_no == WD_STAND_FOR_MASTER) ||
715
+ (packet->packet_no == WD_STAND_FOR_LOCK_HOLDER) ||
716
+ (packet->packet_no == WD_DECLARE_LOCK_HOLDER) ||
717
+ (packet->packet_no == WD_START_RECOVERY))
718
+ {
719
+ rtn = WD_OK;
720
+ }
721
+ else
722
+ {
723
+ rtn = WD_NG;
724
+ }
725
+
726
+ /* receive the results */
727
+ for (i=0; i<cnt; )
728
+ {
729
+ int result;
730
+ rc = pthread_join(thread[i], (void **)&result);
731
+ if ((rc != 0) && (errno == EINTR))
732
+ {
733
+ usleep(100);
734
+ continue;
735
+ }
736
+
737
+ /* aggregate results according to the packet type */
738
+ if ((packet->packet_no == WD_STAND_FOR_MASTER) ||
739
+ (packet->packet_no == WD_STAND_FOR_LOCK_HOLDER) ||
740
+ (packet->packet_no == WD_DECLARE_LOCK_HOLDER) ||
741
+ (packet->packet_no == WD_START_RECOVERY))
742
+ {
743
+ /* if any result is NG then return NG */
744
+ if (result == WD_NG)
745
+ {
746
+ rtn = WD_NG;
747
+ }
748
+ }
749
+
750
+ else
751
+ {
752
+ /* if any result is OK then return OK */
753
+ if (result == WD_OK)
754
+ {
755
+ rtn = WD_OK;
756
+ }
757
+ }
758
+ i++;
759
+ }
760
+
761
+ return rtn;
762
+ }
763
+
764
+ static int
765
+ hton_wd_packet(WdPacket * to, WdPacket * from)
766
+ {
767
+ WdInfo * to_info = NULL;
768
+ WdInfo * from_info = NULL;
769
+
770
+ if ((to == NULL) || (from == NULL))
771
+ {
772
+ return WD_NG;
773
+ }
774
+
775
+ to_info = &(to->wd_body.wd_info);
776
+ from_info = &(from->wd_body.wd_info);
777
+
778
+ to->packet_no = htonl(from->packet_no);
779
+ to->send_time.tv_sec = htonl(from->send_time.tv_sec);
780
+ to->send_time.tv_usec = htonl(from->send_time.tv_usec);
781
+
782
+ memcpy(to->hash, from->hash, sizeof(to->hash));
783
+
784
+ to_info->status = htonl(from_info->status);
785
+ to_info->tv.tv_sec = htonl(from_info->tv.tv_sec);
786
+ to_info->tv.tv_usec = htonl(from_info->tv.tv_usec);
787
+ to_info->pgpool_port = htonl(from_info->pgpool_port);
788
+ to_info->wd_port = htonl(from_info->wd_port);
789
+
790
+ memcpy(to_info->hostname, from_info->hostname, sizeof(to_info->hostname));
791
+ memcpy(to_info->delegate_ip, from_info->delegate_ip, sizeof(to_info->delegate_ip));
792
+
793
+ return WD_OK;
794
+ }
795
+
796
+ static int
797
+ ntoh_wd_packet(WdPacket * to, WdPacket * from)
798
+ {
799
+ WdInfo * to_info = NULL;
800
+ WdInfo * from_info = NULL;
801
+
802
+ if ((to == NULL) || (from == NULL))
803
+ {
804
+ return WD_NG;
805
+ }
806
+
807
+ to_info = &(to->wd_body.wd_info);
808
+ from_info = &(from->wd_body.wd_info);
809
+
810
+ to->packet_no = ntohl(from->packet_no);
811
+ to->send_time.tv_sec = ntohl(from->send_time.tv_sec);
812
+ to->send_time.tv_usec = ntohl(from->send_time.tv_usec);
813
+
814
+ memcpy(to->hash, from->hash, sizeof(to->hash));
815
+
816
+ to_info->status = ntohl(from_info->status);
817
+ to_info->tv.tv_sec = ntohl(from_info->tv.tv_sec);
818
+ to_info->tv.tv_usec = ntohl(from_info->tv.tv_usec);
819
+ to_info->pgpool_port = ntohl(from_info->pgpool_port);
820
+ to_info->wd_port = ntohl(from_info->wd_port);
821
+
822
+ memcpy(to_info->hostname, from_info->hostname, sizeof(to_info->hostname));
823
+ memcpy(to_info->delegate_ip, from_info->delegate_ip, sizeof(to_info->delegate_ip));
824
+
825
+ return WD_OK;
826
+ }
827
+
828
+ static int
829
+ hton_wd_node_packet(WdPacket * to, WdPacket * from)
830
+ {
831
+ WdNodeInfo * to_info = NULL;
832
+ WdNodeInfo * from_info = NULL;
833
+ int i;
834
+
835
+ if ((to == NULL) || (from == NULL))
836
+ {
837
+ return WD_NG;
838
+ }
839
+
840
+ to_info = &(to->wd_body.wd_node_info);
841
+ from_info = &(from->wd_body.wd_node_info);
842
+
843
+ to->packet_no = htonl(from->packet_no);
844
+ to->send_time.tv_sec = htonl(from->send_time.tv_sec);
845
+ to->send_time.tv_usec = htonl(from->send_time.tv_usec);
846
+
847
+ memcpy(to->hash, from->hash, sizeof(to->hash));
848
+
849
+ to_info->node_num = htonl(from_info->node_num);
850
+
851
+ for (i = 0 ; i < from_info->node_num ; i ++)
852
+ {
853
+ to_info->node_id_set[i] = htonl(from_info->node_id_set[i]);
854
+ }
855
+
856
+ return WD_OK;
857
+ }
858
+
859
+ static int
860
+ ntoh_wd_node_packet(WdPacket * to, WdPacket * from)
861
+ {
862
+ WdNodeInfo * to_info = NULL;
863
+ WdNodeInfo * from_info = NULL;
864
+ int i;
865
+
866
+ if ((to == NULL) || (from == NULL))
867
+ {
868
+ return WD_NG;
869
+ }
870
+
871
+ to_info = &(to->wd_body.wd_node_info);
872
+ from_info = &(from->wd_body.wd_node_info);
873
+
874
+ to->packet_no = ntohl(from->packet_no);
875
+ to->send_time.tv_sec = ntohl(from->send_time.tv_sec);
876
+ to->send_time.tv_usec = ntohl(from->send_time.tv_usec);
877
+
878
+ memcpy(to->hash, from->hash, sizeof(to->hash));
879
+
880
+ to_info->node_num = ntohl(from_info->node_num);
881
+
882
+ for (i = 0 ; i < to_info->node_num ; i ++)
883
+ {
884
+ to_info->node_id_set[i] = ntohl(from_info->node_id_set[i]);
885
+ }
886
+
887
+ return WD_OK;
888
+ }
889
+
890
+ static int
891
+ hton_wd_lock_packet(WdPacket * to, WdPacket * from)
892
+ {
893
+ WdLockInfo * to_info = NULL;
894
+ WdLockInfo * from_info = NULL;
895
+
896
+ if ((to == NULL) || (from == NULL))
897
+ {
898
+ return WD_NG;
899
+ }
900
+
901
+ to_info = &(to->wd_body.wd_lock_info);
902
+ from_info = &(from->wd_body.wd_lock_info);
903
+
904
+ to->packet_no = htonl(from->packet_no);
905
+ to->send_time.tv_sec = htonl(from->send_time.tv_sec);
906
+ to->send_time.tv_usec = htonl(from->send_time.tv_usec);
907
+
908
+ memcpy(to->hash, from->hash, sizeof(to->hash));
909
+
910
+ to_info->lock_id = htonl(from_info->lock_id);
911
+
912
+ return WD_OK;
913
+ }
914
+
915
+ static int
916
+ ntoh_wd_lock_packet(WdPacket * to, WdPacket * from)
917
+ {
918
+ WdLockInfo * to_info = NULL;
919
+ WdLockInfo * from_info = NULL;
920
+
921
+ if ((to == NULL) || (from == NULL))
922
+ {
923
+ return WD_NG;
924
+ }
925
+
926
+ to_info = &(to->wd_body.wd_lock_info);
927
+ from_info = &(from->wd_body.wd_lock_info);
928
+
929
+ to->packet_no = ntohl(from->packet_no);
930
+ to->send_time.tv_sec = ntohl(from->send_time.tv_sec);
931
+ to->send_time.tv_usec = ntohl(from->send_time.tv_usec);
932
+
933
+ memcpy(to->hash, from->hash, sizeof(to->hash));
934
+
935
+ to_info->lock_id = ntohl(from_info->lock_id);
936
+
937
+ return WD_OK;
938
+ }
939
+
940
+ int
941
+ wd_escalation(void)
942
+ {
943
+ int rtn;
944
+
945
+ pool_log("wd_escalation: escalating to master pgpool");
946
+
947
+ /* clear shared memory cache */
948
+ if (pool_config->memory_cache_enabled && pool_is_shmem_cache() &&
949
+ pool_config->clear_memqcache_on_escalation)
950
+ {
951
+ pool_log("wd_escalation: clear all the query cache on shared memory");
952
+ pool_clear_memory_cache();
953
+ }
954
+
955
+ /* execute escalation command */
956
+ if (strlen(pool_config->wd_escalation_command))
957
+ {
958
+ system(pool_config->wd_escalation_command);
959
+ }
960
+
961
+ /* interface up as delegate IP */
962
+ if (strlen(pool_config->delegate_IP) != 0)
963
+ wd_IP_up();
964
+
965
+ /* set master status to the wd list */
966
+ wd_set_wd_list(pool_config->wd_hostname, pool_config->port,
967
+ pool_config->wd_port, pool_config->delegate_IP,
968
+ NULL, WD_MASTER);
969
+
970
+ /* send declare packet */
971
+ rtn = wd_declare();
972
+ if (rtn == WD_OK)
973
+ {
974
+ pool_log("wd_escalation: escalated to master pgpool successfully");
975
+ }
976
+
977
+ return rtn;
978
+ }
979
+
980
+ int
981
+ wd_start_recovery(void)
982
+ {
983
+ int rtn;
984
+
985
+ /* send start recovery packet */
986
+ rtn = wd_send_packet_no(WD_START_RECOVERY);
987
+ return rtn;
988
+ }
989
+
990
+ int
991
+ wd_end_recovery(void)
992
+ {
993
+ int rtn;
994
+
995
+ /* send end recovery packet */
996
+ rtn = wd_send_packet_no(WD_END_RECOVERY);
997
+ return rtn;
998
+ }
999
+
1000
+ int
1001
+ wd_send_failback_request(int node_id)
1002
+ {
1003
+ int rtn = 0;
1004
+ int n = node_id;
1005
+
1006
+ /* if failback packet is received already, do nothing */
1007
+ if (wd_chk_node_mask(WD_FAILBACK_REQUEST,&n,1))
1008
+ {
1009
+ return WD_OK;
1010
+ }
1011
+
1012
+ /* send failback packet */
1013
+ rtn = wd_send_node_packet(WD_FAILBACK_REQUEST, &n, 1);
1014
+ return rtn;
1015
+ }
1016
+
1017
+ int
1018
+ wd_degenerate_backend_set(int *node_id_set, int count)
1019
+ {
1020
+ int rtn = 0;
1021
+
1022
+ /* if degenerate packet is received already, do nothing */
1023
+ if (wd_chk_node_mask(WD_DEGENERATE_BACKEND,node_id_set,count))
1024
+ {
1025
+ return WD_OK;
1026
+ }
1027
+
1028
+ /* send degenerate packet */
1029
+ rtn = wd_send_node_packet(WD_DEGENERATE_BACKEND, node_id_set, count);
1030
+ return rtn;
1031
+ }
1032
+
1033
+ int
1034
+ wd_promote_backend(int node_id)
1035
+ {
1036
+ int rtn = 0;
1037
+ int n = node_id;
1038
+
1039
+ /* if promote packet is received already, do nothing */
1040
+ if (wd_chk_node_mask(WD_PROMOTE_BACKEND,&n,1))
1041
+ {
1042
+ return WD_OK;
1043
+ }
1044
+
1045
+ /* send promote packet */
1046
+ rtn = wd_send_node_packet(WD_PROMOTE_BACKEND, &n, 1);
1047
+ return rtn;
1048
+ }
1049
+
1050
+ static int
1051
+ wd_send_node_packet(WD_PACKET_NO packet_no, int *node_id_set, int count)
1052
+ {
1053
+ int rtn = 0;
1054
+ WdPacket packet;
1055
+
1056
+ memset(&packet, 0, sizeof(WdPacket));
1057
+ /* set add request packet */
1058
+ packet.packet_no = packet_no;
1059
+ memcpy(packet.wd_body.wd_node_info.node_id_set,node_id_set,sizeof(int)*count);
1060
+ packet.wd_body.wd_node_info.node_num = count;
1061
+
1062
+ /* send packet to all watchdogs */
1063
+ rtn = send_packet_for_all(&packet);
1064
+
1065
+ return rtn;
1066
+ }
1067
+
1068
+ int
1069
+ wd_send_lock_packet(WD_PACKET_NO packet_no, WD_LOCK_ID lock_id)
1070
+ {
1071
+ int rtn = 0;
1072
+ WdPacket packet;
1073
+
1074
+ memset(&packet, 0, sizeof(WdPacket));
1075
+
1076
+ /* set add request packet */
1077
+ packet.packet_no = packet_no;
1078
+ packet.wd_body.wd_lock_info.lock_id= lock_id;
1079
+
1080
+ /* send packet to all watchdogs */
1081
+ rtn = send_packet_for_all(&packet);
1082
+
1083
+ return rtn;
1084
+ }
1085
+
1086
+ /* check mask, and if maskted return 1 and clear it, otherwise return 0 */
1087
+ static int
1088
+ wd_chk_node_mask (WD_PACKET_NO packet_no, int *node_id_set, int count)
1089
+ {
1090
+ int rtn = 0;
1091
+ unsigned char mask = 0;
1092
+ int i;
1093
+ int offset = 0;
1094
+ mask = 1 << (packet_no - WD_START_RECOVERY);
1095
+ for ( i = 0 ; i < count ; i ++)
1096
+ {
1097
+ offset = *(node_id_set+i);
1098
+ if ((*(WD_Node_List + offset) & mask) != 0)
1099
+ {
1100
+ *(WD_Node_List + offset) ^= mask;
1101
+ rtn = 1;
1102
+ }
1103
+ }
1104
+ return rtn;
1105
+ }
1106
+
1107
+ /* set mask */
1108
+ int
1109
+ wd_set_node_mask (WD_PACKET_NO packet_no, int *node_id_set, int count)
1110
+ {
1111
+ int rtn = 0;
1112
+ unsigned char mask = 0;
1113
+ int i;
1114
+ int offset = 0;
1115
+ mask = 1 << (packet_no - WD_START_RECOVERY);
1116
+ for ( i = 0 ; i < count ; i ++)
1117
+ {
1118
+ offset = *(node_id_set+i);
1119
+ *(WD_Node_List + offset) |= mask;
1120
+ }
1121
+ return rtn;
1122
+ }
1123
+
1124
+ /* calculate hash for authentication using packet contents */
1125
+ void
1126
+ wd_calc_hash(const char *str, int len, char *buf)
1127
+ {
1128
+ char pass[(MAX_PASSWORD_SIZE + 1) / 2];
1129
+ char username[(MAX_PASSWORD_SIZE + 1) / 2];
1130
+ size_t pass_len;
1131
+ size_t username_len;
1132
+ size_t authkey_len;
1133
+
1134
+ /* use first half of authkey as username, last half as password */
1135
+ authkey_len = strlen(pool_config->wd_authkey);
1136
+
1137
+ username_len = authkey_len / 2;
1138
+ pass_len = authkey_len - username_len;
1139
+ snprintf(username, username_len + 1, "%s", pool_config->wd_authkey);
1140
+ snprintf(pass, pass_len + 1, "%s", pool_config->wd_authkey + username_len);
1141
+
1142
+ /* calculate hash using md5 encrypt */
1143
+ pool_md5_encrypt(pass, username, strlen(username), buf + MD5_PASSWD_LEN + 1);
1144
+ buf[(MD5_PASSWD_LEN+1)*2-1] = '\0';
1145
+
1146
+ pool_md5_encrypt(buf+MD5_PASSWD_LEN+1, str, len, buf);
1147
+ buf[MD5_PASSWD_LEN] = '\0';
1148
+ }
1149
+
1150
+ int
1151
+ wd_packet_to_string(WdPacket *pkt, char *str, int maxlen)
1152
+ {
1153
+ int len;
1154
+
1155
+ len = snprintf(str, maxlen, "no=%d tv_sec=%ld tv_usec=%ld",
1156
+ pkt->packet_no, pkt->send_time.tv_sec, pkt->send_time.tv_usec);
1157
+
1158
+ return len;
1159
+ }