PageRenderTime 26ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/pool_process_reporting.c

https://github.com/kuriyama/pgpool-II
C | 533 lines | 405 code | 94 blank | 34 comment | 22 complexity | c4fce5c79c09dbf2fc3e99a0e88422d6 MD5 | raw file
  1. /* -*-pgsql-c-*- */
  2. /*
  3. * $Header: /cvsroot/pgpool/pgpool-II/pool_process_reporting.c,v 1.4 2010/01/31 02:55:00 t-ishii Exp $
  4. *
  5. * pgpool: a language independent connection pool server for PostgreSQL
  6. * written by Tatsuo Ishii
  7. *
  8. * Copyright (c) 2003-2010 PgPool Global Development Group
  9. *
  10. * Permission to use, copy, modify, and distribute this software and
  11. * its documentation for any purpose and without fee is hereby
  12. * granted, provided that the above copyright notice appear in all
  13. * copies and that both that copyright notice and this permission
  14. * notice appear in supporting documentation, and that the name of the
  15. * author not be used in advertising or publicity pertaining to
  16. * distribution of the software without specific, written prior
  17. * permission. The author makes no representations about the
  18. * suitability of this software for any purpose. It is provided "as
  19. * is" without express or implied warranty.
  20. *
  21. * Process "show pool_status" query.
  22. */
  23. #include "pool.h"
  24. #include "pool_proto_modules.h"
  25. #include <string.h>
  26. #include <netinet/in.h>
  27. void process_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend)
  28. {
  29. static char *cursorname = "blank";
  30. static short num_fields = 3;
  31. static char *field_names[] = {"item", "value", "description"};
  32. static int oid = 0;
  33. static short fsize = -1;
  34. static int mod = 0;
  35. short n;
  36. int i, j;
  37. short s;
  38. int len;
  39. short colnum;
  40. static unsigned char nullmap[2] = {0xff, 0xff};
  41. int nbytes = (num_fields + 7)/8;
  42. #define POOLCONFIG_MAXNAMELEN 32
  43. #define POOLCONFIG_MAXVALLEN 512
  44. #define POOLCONFIG_MAXDESCLEN 64
  45. typedef struct {
  46. char name[POOLCONFIG_MAXNAMELEN+1];
  47. char value[POOLCONFIG_MAXVALLEN+1];
  48. char desc[POOLCONFIG_MAXDESCLEN+1];
  49. } POOL_REPORT_STATUS;
  50. /*
  51. * Report data buffer.
  52. * 128 is the max number of configuration items.
  53. * In addition, we need MAX_NUM_BACKENDS*4
  54. * for backend descriptions.
  55. */
  56. #define MAXITEMS (128 + MAX_NUM_BACKENDS*4)
  57. static POOL_REPORT_STATUS status[MAXITEMS];
  58. short nrows;
  59. int size;
  60. int hsize;
  61. i = 0;
  62. strncpy(status[i].name, "listen_addresses", POOLCONFIG_MAXNAMELEN);
  63. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->listen_addresses);
  64. strncpy(status[i].desc, "host name(s) or IP address(es) to listen to", POOLCONFIG_MAXDESCLEN);
  65. i++;
  66. strncpy(status[i].name, "port", POOLCONFIG_MAXNAMELEN);
  67. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->port);
  68. strncpy(status[i].desc, "pgpool accepting port number", POOLCONFIG_MAXDESCLEN);
  69. i++;
  70. strncpy(status[i].name, "socket_dir", POOLCONFIG_MAXNAMELEN);
  71. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->socket_dir);
  72. strncpy(status[i].desc, "pgpool socket directory", POOLCONFIG_MAXDESCLEN);
  73. i++;
  74. strncpy(status[i].name, "num_init_children", POOLCONFIG_MAXNAMELEN);
  75. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->num_init_children);
  76. strncpy(status[i].desc, "# of children initially pre-forked", POOLCONFIG_MAXDESCLEN);
  77. i++;
  78. strncpy(status[i].name, "child_life_time", POOLCONFIG_MAXNAMELEN);
  79. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->child_life_time);
  80. strncpy(status[i].desc, "if idle for this seconds, child exits", POOLCONFIG_MAXDESCLEN);
  81. i++;
  82. strncpy(status[i].name, "connection_life_time", POOLCONFIG_MAXNAMELEN);
  83. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->connection_life_time);
  84. strncpy(status[i].desc, "if idle for this seconds, connection closes", POOLCONFIG_MAXDESCLEN);
  85. i++;
  86. strncpy(status[i].name, "client_idle_limit", POOLCONFIG_MAXNAMELEN);
  87. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->client_idle_limit);
  88. strncpy(status[i].desc, "if idle for this seconds, child connection closes", POOLCONFIG_MAXDESCLEN);
  89. i++;
  90. strncpy(status[i].name, "child_max_connections", POOLCONFIG_MAXNAMELEN);
  91. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->child_max_connections);
  92. strncpy(status[i].desc, "if max_connections received, chile exits", POOLCONFIG_MAXDESCLEN);
  93. i++;
  94. strncpy(status[i].name, "max_pool", POOLCONFIG_MAXNAMELEN);
  95. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->max_pool);
  96. strncpy(status[i].desc, "max # of connection pool per child", POOLCONFIG_MAXDESCLEN);
  97. i++;
  98. strncpy(status[i].name, "authentication_timeout", POOLCONFIG_MAXNAMELEN);
  99. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->authentication_timeout);
  100. strncpy(status[i].desc, "maximum time in seconds to complete client authentication", POOLCONFIG_MAXNAMELEN);
  101. i++;
  102. strncpy(status[i].name, "logdir", POOLCONFIG_MAXNAMELEN);
  103. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->logdir);
  104. strncpy(status[i].desc, "logging directory", POOLCONFIG_MAXDESCLEN);
  105. i++;
  106. strncpy(status[i].name, "pid_file_name", POOLCONFIG_MAXNAMELEN);
  107. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->pid_file_name);
  108. strncpy(status[i].desc, "path to pid file", POOLCONFIG_MAXDESCLEN);
  109. i++;
  110. strncpy(status[i].name, "backend_socket_dir", POOLCONFIG_MAXNAMELEN);
  111. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->backend_socket_dir);
  112. strncpy(status[i].desc, "Unix domain socket directory for the PostgreSQL server", POOLCONFIG_MAXDESCLEN);
  113. i++;
  114. strncpy(status[i].name, "replication_mode", POOLCONFIG_MAXNAMELEN);
  115. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->replication_mode);
  116. strncpy(status[i].desc, "non 0 if operating in replication mode", POOLCONFIG_MAXDESCLEN);
  117. i++;
  118. strncpy(status[i].name, "load_balance_mode", POOLCONFIG_MAXNAMELEN);
  119. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->load_balance_mode);
  120. strncpy(status[i].desc, "non 0 if operating in load balancing mode", POOLCONFIG_MAXDESCLEN);
  121. i++;
  122. strncpy(status[i].name, "replication_stop_on_mismatch", POOLCONFIG_MAXNAMELEN);
  123. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->replication_stop_on_mismatch);
  124. strncpy(status[i].desc, "stop replication mode on fatal error", POOLCONFIG_MAXDESCLEN);
  125. i++;
  126. strncpy(status[i].name, "replicate_select", POOLCONFIG_MAXNAMELEN);
  127. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->replicate_select);
  128. strncpy(status[i].desc, "non 0 if SELECT statement is replicated", POOLCONFIG_MAXDESCLEN);
  129. i++;
  130. strncpy(status[i].name, "reset_query_list", POOLCONFIG_MAXNAMELEN);
  131. *(status[i].value) = '\0';
  132. for (j=0;j<pool_config->num_reset_queries;j++)
  133. {
  134. int len;
  135. len = POOLCONFIG_MAXVALLEN - strlen(status[i].value);
  136. strncat(status[i].value, pool_config->reset_query_list[j], len);
  137. len = POOLCONFIG_MAXVALLEN - strlen(status[i].value);
  138. strncat(status[i].value, ";", len);
  139. }
  140. strncpy(status[i].desc, "queries issued at the end of session", POOLCONFIG_MAXDESCLEN);
  141. i++;
  142. strncpy(status[i].name, "print_timestamp", POOLCONFIG_MAXNAMELEN);
  143. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->print_timestamp);
  144. strncpy(status[i].desc, "if true print time stamp to each log line", POOLCONFIG_MAXDESCLEN);
  145. i++;
  146. strncpy(status[i].name, "master_slave_mode", POOLCONFIG_MAXNAMELEN);
  147. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->master_slave_mode);
  148. strncpy(status[i].desc, "if true, operate in master/slave mode", POOLCONFIG_MAXDESCLEN);
  149. i++;
  150. strncpy(status[i].name, "connection_cache", POOLCONFIG_MAXNAMELEN);
  151. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->connection_cache);
  152. strncpy(status[i].desc, "if true, cache connection pool", POOLCONFIG_MAXDESCLEN);
  153. i++;
  154. strncpy(status[i].name, "health_check_timeout", POOLCONFIG_MAXNAMELEN);
  155. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->health_check_timeout);
  156. strncpy(status[i].desc, "health check timeout", POOLCONFIG_MAXDESCLEN);
  157. i++;
  158. strncpy(status[i].name, "health_check_period", POOLCONFIG_MAXNAMELEN);
  159. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->health_check_period);
  160. strncpy(status[i].desc, "health check period", POOLCONFIG_MAXDESCLEN);
  161. i++;
  162. strncpy(status[i].name, "health_check_user", POOLCONFIG_MAXNAMELEN);
  163. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->health_check_user);
  164. strncpy(status[i].desc, "health check user", POOLCONFIG_MAXDESCLEN);
  165. i++;
  166. strncpy(status[i].name, "failover_command", POOLCONFIG_MAXNAMELEN);
  167. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->failover_command);
  168. strncpy(status[i].desc, "failover command", POOLCONFIG_MAXDESCLEN);
  169. i++;
  170. strncpy(status[i].name, "failback_command", POOLCONFIG_MAXNAMELEN);
  171. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->failover_command);
  172. strncpy(status[i].desc, "failback command", POOLCONFIG_MAXDESCLEN);
  173. i++;
  174. strncpy(status[i].name, "fail_over_on_backend_error", POOLCONFIG_MAXNAMELEN);
  175. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->insert_lock);
  176. strncpy(status[i].desc, "fail_over_on_backend_error", POOLCONFIG_MAXDESCLEN);
  177. i++;
  178. strncpy(status[i].name, "insert_lock", POOLCONFIG_MAXNAMELEN);
  179. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->insert_lock);
  180. strncpy(status[i].desc, "insert lock", POOLCONFIG_MAXDESCLEN);
  181. i++;
  182. strncpy(status[i].name, "ignore_leading_white_space", POOLCONFIG_MAXNAMELEN);
  183. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->ignore_leading_white_space);
  184. strncpy(status[i].desc, "ignore leading white spaces", POOLCONFIG_MAXDESCLEN);
  185. i++;
  186. strncpy(status[i].name, "replication_enabled", POOLCONFIG_MAXNAMELEN);
  187. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->replication_enabled);
  188. strncpy(status[i].desc, "non 0 if actually operating in replication mode", POOLCONFIG_MAXDESCLEN);
  189. i++;
  190. strncpy(status[i].name, "master_slave_enabled", POOLCONFIG_MAXNAMELEN);
  191. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->master_slave_enabled);
  192. strncpy(status[i].desc, "non 0 if actually operating in master/slave", POOLCONFIG_MAXDESCLEN);
  193. i++;
  194. strncpy(status[i].name, "num_reset_queries", POOLCONFIG_MAXNAMELEN);
  195. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->num_reset_queries);
  196. strncpy(status[i].desc, "number of queries in reset_query_list", POOLCONFIG_MAXDESCLEN);
  197. i++;
  198. strncpy(status[i].name, "pcp_port", POOLCONFIG_MAXNAMELEN);
  199. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->pcp_port);
  200. strncpy(status[i].desc, "PCP port # to bind", POOLCONFIG_MAXDESCLEN);
  201. i++;
  202. strncpy(status[i].name, "pcp_socket_dir", POOLCONFIG_MAXNAMELEN);
  203. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->pcp_socket_dir);
  204. strncpy(status[i].desc, "PCP socket directory", POOLCONFIG_MAXDESCLEN);
  205. i++;
  206. strncpy(status[i].name, "pcp_timeout", POOLCONFIG_MAXNAMELEN);
  207. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->pcp_timeout);
  208. strncpy(status[i].desc, "PCP timeout for an idle client", POOLCONFIG_MAXDESCLEN);
  209. i++;
  210. strncpy(status[i].name, "log_statement", POOLCONFIG_MAXNAMELEN);
  211. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->log_statement);
  212. strncpy(status[i].desc, "if non 0, logs all SQL statements", POOLCONFIG_MAXDESCLEN);
  213. i++;
  214. strncpy(status[i].name, "log_per_node_statement", POOLCONFIG_MAXNAMELEN);
  215. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->log_per_node_statement);
  216. strncpy(status[i].desc, "if non 0, logs all SQL statements on each node", POOLCONFIG_MAXDESCLEN);
  217. i++;
  218. strncpy(status[i].name, "log_connections", POOLCONFIG_MAXNAMELEN);
  219. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->log_connections);
  220. strncpy(status[i].desc, "if true, print incoming connections to the log", POOLCONFIG_MAXDESCLEN);
  221. i++;
  222. strncpy(status[i].name, "log_hostname", POOLCONFIG_MAXNAMELEN);
  223. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->log_hostname);
  224. strncpy(status[i].desc, "if true, resolve hostname for ps and log print", POOLCONFIG_MAXDESCLEN);
  225. i++;
  226. strncpy(status[i].name, "enable_pool_hba", POOLCONFIG_MAXNAMELEN);
  227. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->enable_pool_hba);
  228. strncpy(status[i].desc, "if true, use pool_hba.conf for client authentication", POOLCONFIG_MAXDESCLEN);
  229. i++;
  230. strncpy(status[i].name, "recovery_user", POOLCONFIG_MAXNAMELEN);
  231. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->recovery_user);
  232. strncpy(status[i].desc, "online recovery user", POOLCONFIG_MAXDESCLEN);
  233. i++;
  234. strncpy(status[i].name, "recovery_password", POOLCONFIG_MAXNAMELEN);
  235. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->recovery_password);
  236. strncpy(status[i].desc, "online recovery password", POOLCONFIG_MAXDESCLEN);
  237. i++;
  238. strncpy(status[i].name, "recovery_1st_stage_command", POOLCONFIG_MAXNAMELEN);
  239. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->recovery_1st_stage_command);
  240. strncpy(status[i].desc, "execute a command in first stage.", POOLCONFIG_MAXDESCLEN);
  241. i++;
  242. strncpy(status[i].name, "recovery_2nd_stage_command", POOLCONFIG_MAXNAMELEN);
  243. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->recovery_2nd_stage_command);
  244. strncpy(status[i].desc, "execute a command in second stage.", POOLCONFIG_MAXDESCLEN);
  245. i++;
  246. strncpy(status[i].name, "recovery_timeout", POOLCONFIG_MAXNAMELEN);
  247. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->recovery_timeout);
  248. strncpy(status[i].desc, "max time in seconds to wait for the recovering node's postmaster", POOLCONFIG_MAXDESCLEN);
  249. i++;
  250. strncpy(status[i].name, "client_idle_limit_in_recovery", POOLCONFIG_MAXNAMELEN);
  251. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->client_idle_limit_in_recovery);
  252. strncpy(status[i].desc, "if idle for this seconds, child connection closes in recovery 2nd statge", POOLCONFIG_MAXDESCLEN);
  253. i++;
  254. strncpy(status[i].name, "lobj_lock_table", POOLCONFIG_MAXNAMELEN);
  255. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->lobj_lock_table);
  256. strncpy(status[i].desc, "table name used for large object replication control", POOLCONFIG_MAXDESCLEN);
  257. i++;
  258. strncpy(status[i].name, "ssl", POOLCONFIG_MAXNAMELEN);
  259. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->ssl);
  260. strncpy(status[i].desc, "SSL support", POOLCONFIG_MAXDESCLEN);
  261. i++;
  262. strncpy(status[i].name, "ssl_key", POOLCONFIG_MAXNAMELEN);
  263. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->ssl_key);
  264. strncpy(status[i].desc, "path to the SSL private key file", POOLCONFIG_MAXDESCLEN);
  265. i++;
  266. strncpy(status[i].name, "ssl_cert", POOLCONFIG_MAXNAMELEN);
  267. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->ssl_cert);
  268. strncpy(status[i].desc, "path to the SSL public certificate file", POOLCONFIG_MAXDESCLEN);
  269. i++;
  270. strncpy(status[i].name, "parallel_mode", POOLCONFIG_MAXNAMELEN);
  271. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->parallel_mode);
  272. strncpy(status[i].desc, "if non 0, run in parallel query mode", POOLCONFIG_MAXDESCLEN);
  273. i++;
  274. strncpy(status[i].name, "enable_query_cache", POOLCONFIG_MAXNAMELEN);
  275. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->enable_query_cache);
  276. strncpy(status[i].desc, "if non 0, use query cache", POOLCONFIG_MAXDESCLEN);
  277. i++;
  278. strncpy(status[i].name, "pgpool2_hostname", POOLCONFIG_MAXNAMELEN);
  279. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->pgpool2_hostname);
  280. strncpy(status[i].desc, "pgpool2 hostname", POOLCONFIG_MAXDESCLEN);
  281. i++;
  282. strncpy(status[i].name, "system_db_hostname", POOLCONFIG_MAXNAMELEN);
  283. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->system_db_hostname);
  284. strncpy(status[i].desc, "system DB hostname", POOLCONFIG_MAXDESCLEN);
  285. i++;
  286. strncpy(status[i].name, "system_db_port", POOLCONFIG_MAXNAMELEN);
  287. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->system_db_port);
  288. strncpy(status[i].desc, "system DB port number", POOLCONFIG_MAXDESCLEN);
  289. i++;
  290. strncpy(status[i].name, "system_db_dbname", POOLCONFIG_MAXNAMELEN);
  291. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->system_db_dbname);
  292. strncpy(status[i].desc, "system DB name", POOLCONFIG_MAXDESCLEN);
  293. i++;
  294. strncpy(status[i].name, "system_db_schema", POOLCONFIG_MAXNAMELEN);
  295. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->system_db_schema);
  296. strncpy(status[i].desc, "system DB schema name", POOLCONFIG_MAXDESCLEN);
  297. i++;
  298. strncpy(status[i].name, "system_db_user", POOLCONFIG_MAXNAMELEN);
  299. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->system_db_user);
  300. strncpy(status[i].desc, "user name to access system DB", POOLCONFIG_MAXDESCLEN);
  301. i++;
  302. strncpy(status[i].name, "system_db_password", POOLCONFIG_MAXNAMELEN);
  303. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->system_db_password);
  304. strncpy(status[i].desc, "password to access system DB", POOLCONFIG_MAXDESCLEN);
  305. i++;
  306. for (j = 0; j < NUM_BACKENDS; j++)
  307. {
  308. if (BACKEND_INFO(j).backend_port == 0)
  309. continue;
  310. snprintf(status[i].name, POOLCONFIG_MAXNAMELEN, "backend_hostname%d", j);
  311. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", BACKEND_INFO(j).backend_hostname);
  312. snprintf(status[i].desc, POOLCONFIG_MAXDESCLEN, "backend #%d hostname", j);
  313. i++;
  314. snprintf(status[i].name, POOLCONFIG_MAXNAMELEN, "backend_port%d", j);
  315. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", BACKEND_INFO(j).backend_port);
  316. snprintf(status[i].desc, POOLCONFIG_MAXDESCLEN, "backend #%d port number", j);
  317. i++;
  318. snprintf(status[i].name, POOLCONFIG_MAXNAMELEN, "backend_weight%d", j);
  319. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%f", BACKEND_INFO(j).backend_weight);
  320. snprintf(status[i].desc, POOLCONFIG_MAXDESCLEN, "weight of backend #%d", j);
  321. i++;
  322. snprintf(status[i].name, POOLCONFIG_MAXNAMELEN, "backend status%d", j);
  323. snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", BACKEND_INFO(j).backend_status);
  324. snprintf(status[i].desc, POOLCONFIG_MAXDESCLEN, "status of backend #%d", j);
  325. i++;
  326. }
  327. nrows = i;
  328. if (MAJOR(backend) == PROTO_MAJOR_V2)
  329. {
  330. /* cursor response */
  331. pool_write(frontend, "P", 1);
  332. pool_write(frontend, cursorname, strlen(cursorname)+1);
  333. }
  334. /* row description */
  335. pool_write(frontend, "T", 1);
  336. if (MAJOR(backend) == PROTO_MAJOR_V3)
  337. {
  338. len = sizeof(num_fields) + sizeof(len);
  339. for (i=0;i<num_fields;i++)
  340. {
  341. char *f = field_names[i];
  342. len += strlen(f)+1;
  343. len += sizeof(oid);
  344. len += sizeof(colnum);
  345. len += sizeof(oid);
  346. len += sizeof(s);
  347. len += sizeof(mod);
  348. len += sizeof(s);
  349. }
  350. len = htonl(len);
  351. pool_write(frontend, &len, sizeof(len));
  352. }
  353. n = htons(num_fields);
  354. pool_write(frontend, &n, sizeof(short));
  355. for (i=0;i<num_fields;i++)
  356. {
  357. char *f = field_names[i];
  358. pool_write(frontend, f, strlen(f)+1); /* field name */
  359. if (MAJOR(backend) == PROTO_MAJOR_V3)
  360. {
  361. pool_write(frontend, &oid, sizeof(oid)); /* table oid */
  362. colnum = htons(i);
  363. pool_write(frontend, &colnum, sizeof(colnum)); /* column number */
  364. }
  365. pool_write(frontend, &oid, sizeof(oid)); /* data type oid */
  366. s = htons(fsize);
  367. pool_write(frontend, &s, sizeof(fsize)); /* field size */
  368. pool_write(frontend, &mod, sizeof(mod)); /* modifier */
  369. if (MAJOR(backend) == PROTO_MAJOR_V3)
  370. {
  371. s = htons(0);
  372. pool_write(frontend, &s, sizeof(fsize)); /* field format (text) */
  373. }
  374. }
  375. pool_flush(frontend);
  376. if (MAJOR(backend) == PROTO_MAJOR_V2)
  377. {
  378. /* ascii row */
  379. for (i=0;i<nrows;i++)
  380. {
  381. pool_write(frontend, "D", 1);
  382. pool_write_and_flush(frontend, nullmap, nbytes);
  383. size = strlen(status[i].name);
  384. hsize = htonl(size+4);
  385. pool_write(frontend, &hsize, sizeof(hsize));
  386. pool_write(frontend, status[i].name, size);
  387. size = strlen(status[i].value);
  388. hsize = htonl(size+4);
  389. pool_write(frontend, &hsize, sizeof(hsize));
  390. pool_write(frontend, status[i].value, size);
  391. size = strlen(status[i].desc);
  392. hsize = htonl(size+4);
  393. pool_write(frontend, &hsize, sizeof(hsize));
  394. pool_write(frontend, status[i].desc, size);
  395. }
  396. }
  397. else
  398. {
  399. /* data row */
  400. for (i=0;i<nrows;i++)
  401. {
  402. pool_write(frontend, "D", 1);
  403. len = sizeof(len) + sizeof(nrows);
  404. len += sizeof(int) + strlen(status[i].name);
  405. len += sizeof(int) + strlen(status[i].value);
  406. len += sizeof(int) + strlen(status[i].desc);
  407. len = htonl(len);
  408. pool_write(frontend, &len, sizeof(len));
  409. s = htons(3);
  410. pool_write(frontend, &s, sizeof(s));
  411. len = htonl(strlen(status[i].name));
  412. pool_write(frontend, &len, sizeof(len));
  413. pool_write(frontend, status[i].name, strlen(status[i].name));
  414. len = htonl(strlen(status[i].value));
  415. pool_write(frontend, &len, sizeof(len));
  416. pool_write(frontend, status[i].value, strlen(status[i].value));
  417. len = htonl(strlen(status[i].desc));
  418. pool_write(frontend, &len, sizeof(len));
  419. pool_write(frontend, status[i].desc, strlen(status[i].desc));
  420. }
  421. }
  422. /* complete command response */
  423. pool_write(frontend, "C", 1);
  424. if (MAJOR(backend) == PROTO_MAJOR_V3)
  425. {
  426. len = htonl(sizeof(len) + strlen("SELECT")+1);
  427. pool_write(frontend, &len, sizeof(len));
  428. }
  429. pool_write(frontend, "SELECT", strlen("SELECT")+1);
  430. /* ready for query */
  431. pool_write(frontend, "Z", 1);
  432. if (MAJOR(backend) == PROTO_MAJOR_V3)
  433. {
  434. len = htonl(sizeof(len) + 1);
  435. pool_write(frontend, &len, sizeof(len));
  436. pool_write(frontend, "I", 1);
  437. }
  438. pool_flush(frontend);
  439. }