prestogres 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }