2 * $Header: /cvsroot/pgpool/pgpool-II/pcp/pcp.c,v 1.8 2008/12/31 10:25:40 t-ishii Exp $
4 * Handles PCP connection, and protocol communication with pgpool-II
5 * These are client APIs. Server program should use APIs in pcp_stream.c
8 * pgpool: a language independent connection pool server for PostgreSQL
9 * written by Tatsuo Ishii
11 * Copyright (c) 2003-2008 PgPool Global Development Group
13 * Permission to use, copy, modify, and distribute this software and
14 * its documentation for any purpose and without fee is hereby
15 * granted, provided that the above copyright notice appear in all
16 * copies and that both that copyright notice and this permission
17 * notice appear in supporting documentation, and that the name of the
18 * author not be used in advertising or publicity pertaining to
19 * distribution of the software without specific, written prior
20 * permission. The author makes no representations about the
21 * suitability of this software for any purpose. It is provided "as
22 * is" without express or implied warranty.
29 #include <sys/types.h>
30 #include <sys/socket.h>
33 #include <netinet/in.h>
34 #include <netinet/tcp.h>
39 #include "pcp_stream.h"
42 struct timeval pcp_timeout;
44 static PCP_CONNECTION *pc;
50 static int pcp_authorize(char *username, char *password);
52 /* --------------------------------
53 * pcp_connect - open connection to pgpool using given arguments
55 * return 0 on success, -1 otherwise
56 * --------------------------------
59 pcp_connect(char *hostname, int port, char *username, char *password)
61 struct sockaddr_in addr;
62 struct sockaddr_un unix_addr;
70 if (debug) fprintf(stderr, "DEBUG: connection to backend \"%s\" already exists\n", hostname);
74 if (hostname == NULL || *hostname == '\0' || *hostname == '/')
78 fd = socket(AF_UNIX, SOCK_STREAM, 0);
82 if (debug) fprintf(stderr, "DEBUG: could not create socket\n");
87 memset(&unix_addr, 0, sizeof(unix_addr));
88 unix_addr.sun_family = AF_UNIX;
90 if (hostname == NULL || *hostname == '\0')
92 path = UNIX_DOMAIN_PATH;
99 snprintf(unix_addr.sun_path, sizeof(unix_addr.sun_path), "%s/.s.PGSQL.%d",
102 if (connect(fd, (struct sockaddr *) &unix_addr, sizeof(unix_addr)) < 0)
104 if (debug) fprintf(stderr, "DEBUG: could not connect to \"%s\"\n", unix_addr.sun_path);
112 fd = socket(AF_INET, SOCK_STREAM, 0);
115 if (debug) fprintf(stderr, "DEBUG: could not create socket\n");
120 if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
121 (char *) &on, sizeof(on)) < 0)
123 if (debug) fprintf(stderr, "DEBUG: could not set socket option\n");
129 memset((char *) &addr, 0, sizeof(addr));
130 ((struct sockaddr *) &addr)->sa_family = AF_INET;
131 hp = gethostbyname(hostname);
132 if ((hp == NULL) || (hp->h_addrtype != AF_INET))
134 if (debug) fprintf(stderr, "DEBUG: could not retrieve hostname\n");
139 memmove((char *) &(addr.sin_addr),
142 addr.sin_port = htons(port);
144 len = sizeof(struct sockaddr_in);
145 if (connect(fd, (struct sockaddr *) &addr, len) < 0)
147 if (debug) fprintf(stderr, "DEBUG: could not connect to \"%s\"\n", hostname);
157 if (debug) fprintf(stderr, "DEBUG: could not allocate buffer space\n");
162 if (pcp_authorize(username, password) < 0)
171 /* --------------------------------
172 * pcp_authorize - authenticate with pgpool using username and password
174 * return 0 on success, -1 otherwise
175 * --------------------------------
178 pcp_authorize(char *username, char *password)
185 char encrypt_buf[(MD5_PASSWD_LEN+1)*2];
186 char md5[MD5_PASSWD_LEN+1];
189 pcp_write(pc, "M", 1);
190 wsize = htonl(sizeof(int));
191 pcp_write(pc, &wsize, sizeof(int));
192 if (pcp_flush(pc) < 0)
194 if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n");
198 if (pcp_read(pc, &tos, 1))
200 if (pcp_read(pc, &rsize, sizeof(int)))
202 rsize = ntohl(rsize);
203 buf = (char *)malloc(rsize);
206 errorcode = NOMEMERR;
209 if (pcp_read(pc, buf, rsize - sizeof(int)))
211 memcpy(salt, buf, 4);
214 /* encrypt password */
215 pool_md5_hash(password, strlen(password), md5);
216 md5[MD5_PASSWD_LEN] = '\0';
218 pool_md5_encrypt(md5, username, strlen(username),
219 encrypt_buf + MD5_PASSWD_LEN + 1);
220 encrypt_buf[(MD5_PASSWD_LEN+1)*2-1] = '\0';
222 pool_md5_encrypt(encrypt_buf+MD5_PASSWD_LEN+1, salt, 4,
224 encrypt_buf[MD5_PASSWD_LEN] = '\0';
226 pcp_write(pc, "R", 1);
227 wsize = htonl((strlen(username)+1 + strlen(encrypt_buf)+1) + sizeof(int));
228 pcp_write(pc, &wsize, sizeof(int));
229 pcp_write(pc, username, strlen(username)+1);
230 pcp_write(pc, encrypt_buf, strlen(encrypt_buf)+1);
231 if (pcp_flush(pc) < 0)
233 if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n");
236 if (debug) fprintf(stderr, "DEBUG: send: tos=\"R\", len=%d\n", ntohl(wsize));
238 if (pcp_read(pc, &tos, 1))
240 if (pcp_read(pc, &rsize, sizeof(int)))
242 rsize = ntohl(rsize);
243 buf = (char *)malloc(rsize);
246 errorcode = NOMEMERR;
249 if (pcp_read(pc, buf, rsize - sizeof(int)))
251 if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf);
255 if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf);
256 errorcode = BACKENDERR;
260 if (strcmp(buf, "AuthenticationOK") == 0)
266 if (debug) fprintf(stderr, "DEBUG: authentication failed. reason=%s\n", buf);
274 /* --------------------------------
275 * pcp_disconnect - close connection to pgpool
276 * --------------------------------
285 if (debug) fprintf(stderr, "DEBUG: connection does not exist\n");
289 pcp_write(pc, "X", 1);
290 wsize = htonl(sizeof(int));
291 pcp_write(pc, &wsize, sizeof(int));
292 if (pcp_flush(pc) < 0)
294 /* backend had closed connection already */
296 if (debug) fprintf(stderr, "DEBUG: send: tos=\"X\", len=%d\n", sizeof(int));
302 /* --------------------------------
303 * pcp_terminate_pgpool - send terminate packet
305 * return 0 on success, -1 otherwise
306 * --------------------------------
309 pcp_terminate_pgpool(char mode)
315 if (debug) fprintf(stderr, "DEBUG: connection does not exist\n");
316 errorcode = NOCONNERR;
320 pcp_write(pc, "T", 1);
321 wsize = htonl(sizeof(int) + sizeof(char));
322 pcp_write(pc, &wsize, sizeof(int));
323 pcp_write(pc, &mode, sizeof(char));
324 if (pcp_flush(pc) < 0)
326 if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n");
329 if (debug) fprintf(stderr, "DEBUG: send: tos=\"T\", len=%d\n", ntohl(wsize));
334 /* --------------------------------
335 * pcp_node_count - get number of nodes currently connected to pgpool
337 * return array of node IDs on success, -1 otherwise
338 * --------------------------------
351 if (debug) fprintf(stderr, "DEBUG: connection does not exist\n");
352 errorcode = NOCONNERR;
356 pcp_write(pc, "L", 1);
357 wsize = htonl(sizeof(int));
358 pcp_write(pc, &wsize, sizeof(int));
359 if (pcp_flush(pc) < 0)
361 if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n");
364 if (debug) fprintf(stderr, "DEBUG: send: tos=\"L\", len=%d\n", ntohl(wsize));
366 if (pcp_read(pc, &tos, 1))
368 if (pcp_read(pc, &rsize, sizeof(int)))
370 rsize = ntohl(rsize);
371 buf = (char *)malloc(rsize);
374 errorcode = NOMEMERR;
377 if (pcp_read(pc, buf, rsize - sizeof(int)))
383 if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf);
387 if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf);
388 errorcode = BACKENDERR;
392 if (strcmp(buf, "CommandComplete") == 0)
394 index = (char *) memchr(buf, '\0', rsize) + 1;
397 int ret = atoi(index);
409 /* --------------------------------
410 * pcp_node_info - get information of node pointed by given argument
412 * return structure of node information on success, -1 otherwise
413 * --------------------------------
416 pcp_node_info(int nid)
426 if (debug) fprintf(stderr, "DEBUG: connection does not exist\n");
427 errorcode = NOCONNERR;
431 snprintf(node_id, sizeof(node_id), "%d", nid);
433 pcp_write(pc, "I", 1);
434 wsize = htonl(strlen(node_id)+1 + sizeof(int));
435 pcp_write(pc, &wsize, sizeof(int));
436 pcp_write(pc, node_id, strlen(node_id)+1);
437 if (pcp_flush(pc) < 0)
439 if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n");
442 if (debug) fprintf(stderr, "DEBUG: send: tos=\"I\", len=%d\n", ntohl(wsize));
444 if (pcp_read(pc, &tos, 1))
446 if (pcp_read(pc, &rsize, sizeof(int)))
448 rsize = ntohl(rsize);
449 buf = (char *)malloc(rsize);
452 errorcode = NOMEMERR;
455 if (pcp_read(pc, buf, rsize - sizeof(int)))
461 if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf);
465 if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf);
466 errorcode = BACKENDERR;
472 if (strcmp(buf, "CommandComplete") == 0)
475 BackendInfo* backend_info = NULL;
477 backend_info = (BackendInfo *)malloc(sizeof(BackendInfo));
478 if (backend_info == NULL)
480 errorcode = NOMEMERR;
485 // rsize -= strlen("CommandComplete") + 1;
487 index = (char *) memchr(buf, '\0', rsize) + 1;
489 strcpy(backend_info->backend_hostname, index);
491 index = (char *) memchr(index, '\0', rsize) + 1;
493 backend_info->backend_port = atoi(index);
495 index = (char *) memchr(index, '\0', rsize) + 1;
497 backend_info->backend_status = atoi(index);
499 index = (char *) memchr(index, '\0', rsize) + 1;
501 backend_info->backend_weight = atof(index);
512 /* --------------------------------
513 * pcp_node_count - get number of nodes currently connected to pgpool
515 * return array of pids on success, NULL otherwise
516 * --------------------------------
519 pcp_process_count(int *pnum)
528 if (debug) fprintf(stderr, "DEBUG: connection does not exist\n");
529 errorcode = NOCONNERR;
533 pcp_write(pc, "N", 1);
534 wsize = htonl(sizeof(int));
535 pcp_write(pc, &wsize, sizeof(int));
536 if (pcp_flush(pc) < 0)
538 if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n");
541 if (debug) fprintf(stderr, "DEBUG: send: tos=\"N\", len=%d\n", ntohl(wsize));
543 if (pcp_read(pc, &tos, 1))
545 if (pcp_read(pc, &rsize, sizeof(int)))
547 rsize = ntohl(rsize);
548 buf = (char *)malloc(rsize);
551 errorcode = NOMEMERR;
554 if (pcp_read(pc, buf, rsize - sizeof(int)))
559 if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf);
563 if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf);
565 errorcode = BACKENDERR;
570 if (strcmp(buf, "CommandComplete") == 0)
573 int *process_list = NULL;
577 index = (char *) memchr(buf, '\0', rsize) + 1;
578 process_count = atoi(index);
580 process_list = (int *)malloc(sizeof(int) * process_count);
581 if (process_list == NULL)
584 errorcode = NOMEMERR;
588 for (i = 0; i < process_count; i++)
590 index = (char *) memchr(index, '\0', rsize) + 1;
591 process_list[i] = atoi(index);
594 *pnum = process_count;
604 /* --------------------------------
605 * pcp_process_info - get information of node pointed by given argument
607 * return structure of process information on success, -1 otherwise
608 * --------------------------------
611 pcp_process_info(int pid, int *array_size)
619 ProcessInfo *process_info = NULL;
625 if (debug) fprintf(stderr, "DEBUG: connection does not exist\n");
626 errorcode = NOCONNERR;
630 snprintf(process_id, sizeof(process_id), "%d", pid);
632 pcp_write(pc, "P", 1);
633 wsize = htonl(strlen(process_id)+1 + sizeof(int));
634 pcp_write(pc, &wsize, sizeof(int));
635 pcp_write(pc, process_id, strlen(process_id)+1);
636 if (pcp_flush(pc) < 0)
638 if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n");
641 if (debug) fprintf(stderr, "DEBUG: send: tos=\"P\", len=%d\n", ntohl(wsize));
645 if (pcp_read(pc, &tos, 1))
647 if (pcp_read(pc, &rsize, sizeof(int)))
649 rsize = ntohl(rsize);
650 buf = (char *)malloc(rsize);
653 errorcode = NOMEMERR;
656 if (pcp_read(pc, buf, rsize - sizeof(int)))
661 if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf);
665 if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf);
667 errorcode = BACKENDERR;
674 if (strcmp(buf, "ArraySize") == 0)
676 index = (char *) memchr(buf, '\0', rsize) + 1;
678 ci_size = atoi(index);
680 *array_size = ci_size;
682 process_info = (ProcessInfo *)malloc(sizeof(ProcessInfo));
683 if (process_info == NULL)
686 errorcode = NOMEMERR;
689 process_info->connection_info = NULL;
690 process_info->connection_info = (ConnectionInfo *)malloc(sizeof(ConnectionInfo)*ci_size);
691 if (process_info->connection_info == NULL)
694 errorcode = NOMEMERR;
700 else if (strcmp(buf, "ProcessInfo") == 0)
702 index = (char *) memchr(buf, '\0', rsize) + 1;
704 strcpy(process_info->connection_info[offset].database, index);
706 index = (char *) memchr(index, '\0', rsize) + 1;
708 strcpy(process_info->connection_info[offset].user, index);
710 index = (char *) memchr(index, '\0', rsize) + 1;
712 process_info->start_time = atol(index);
714 index = (char *) memchr(index, '\0', rsize) + 1;
716 process_info->connection_info[offset].create_time = atol(index);
718 index = (char *) memchr(index, '\0', rsize) + 1;
720 process_info->connection_info[offset].major = atoi(index);
722 index = (char *) memchr(index, '\0', rsize) + 1;
724 process_info->connection_info[offset].minor = atoi(index);
726 index = (char *) memchr(index, '\0', rsize) + 1;
728 process_info->connection_info[offset].counter = atoi(index);
732 else if (strcmp(buf, "CommandComplete") == 0)
748 /* --------------------------------
749 * pcp_systemdb_info - get information of system DB
751 * return structure of system DB information on success, -1 otherwise
752 * --------------------------------
755 pcp_systemdb_info(void)
761 SystemDBInfo *systemdb_info = NULL;
766 if (debug) fprintf(stderr, "DEBUG: connection does not exist\n");
767 errorcode = NOCONNERR;
771 pcp_write(pc, "S", 1);
772 wsize = htonl(sizeof(int));
773 pcp_write(pc, &wsize, sizeof(int));
774 if (pcp_flush(pc) < 0)
776 if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n");
779 if (debug) fprintf(stderr, "DEBUG: send: tos=\"S\", len=%d\n", ntohl(wsize));
782 if (pcp_read(pc, &tos, 1))
784 if (pcp_read(pc, &rsize, sizeof(int)))
786 rsize = ntohl(rsize);
787 buf = (char *)malloc(rsize);
790 errorcode = NOMEMERR;
793 if (pcp_read(pc, buf, rsize - sizeof(int)))
798 if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf);
802 if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf);
804 errorcode = BACKENDERR;
811 if (strcmp(buf, "SystemDBInfo") == 0)
813 systemdb_info = (SystemDBInfo *)malloc(sizeof(SystemDBInfo));
814 if (systemdb_info == NULL)
817 errorcode = NOMEMERR;
821 index = (char *) memchr(buf, '\0', rsize) + 1;
823 systemdb_info->hostname = strdup(index);
824 if (systemdb_info->hostname == NULL)
827 free_systemdb_info(systemdb_info);
828 errorcode = NOMEMERR;
832 index = (char *) memchr(index, '\0', rsize) + 1;
834 systemdb_info->port = atoi(index);
836 index = (char *) memchr(index, '\0', rsize) + 1;
838 systemdb_info->user = strdup(index);
839 if (systemdb_info->user == NULL)
842 free_systemdb_info(systemdb_info);
843 errorcode = NOMEMERR;
847 index = (char *) memchr(index, '\0', rsize) + 1;
849 systemdb_info->password = strdup(index);
850 if (systemdb_info->password == NULL)
853 free_systemdb_info(systemdb_info);
854 errorcode = NOMEMERR;
858 index = (char *) memchr(index, '\0', rsize) + 1;
860 systemdb_info->schema_name = strdup(index);
861 if (systemdb_info->schema_name == NULL)
864 free_systemdb_info(systemdb_info);
865 errorcode = NOMEMERR;
869 index = (char *) memchr(index, '\0', rsize) + 1;
871 systemdb_info->database_name = strdup(index);
872 if (systemdb_info->database_name == NULL)
875 free_systemdb_info(systemdb_info);
876 errorcode = NOMEMERR;
880 index = (char *) memchr(index, '\0', rsize) + 1;
882 systemdb_info->dist_def_num = atoi(index);
884 index = (char *) memchr(index, '\0', rsize) + 1;
886 systemdb_info->system_db_status = atoi(index);
888 if (systemdb_info->dist_def_num > 0)
890 systemdb_info->dist_def_slot = NULL;
891 systemdb_info->dist_def_slot = (DistDefInfo *)malloc(sizeof(DistDefInfo) * systemdb_info->dist_def_num);
892 if (systemdb_info->dist_def_slot == NULL)
895 free_systemdb_info(systemdb_info);
896 errorcode = NOMEMERR;
901 else if (strcmp(buf, "DistDefInfo") == 0)
903 DistDefInfo *dist_def_info = NULL;
906 dist_def_info = (DistDefInfo *)malloc(sizeof(DistDefInfo));
907 if (dist_def_info == NULL)
910 free_systemdb_info(systemdb_info);
911 errorcode = NOMEMERR;
915 index = (char *) memchr(buf, '\0', rsize) + 1;
917 dist_def_info->dbname = strdup(index);
918 if (dist_def_info->dbname == NULL)
921 free_systemdb_info(systemdb_info);
922 errorcode = NOMEMERR;
926 index = (char *) memchr(index, '\0', rsize) + 1;
928 dist_def_info->schema_name = strdup(index);
929 if (dist_def_info->schema_name == NULL)
932 free_systemdb_info(systemdb_info);
933 errorcode = NOMEMERR;
937 index = (char *) memchr(index, '\0', rsize) + 1;
939 dist_def_info->table_name = strdup(index);
940 if (dist_def_info->table_name == NULL)
943 free_systemdb_info(systemdb_info);
944 errorcode = NOMEMERR;
948 index = (char *) memchr(index, '\0', rsize) + 1;
950 dist_def_info->dist_key_col_name = strdup(index);
951 if (dist_def_info->dist_key_col_name == NULL)
954 free_systemdb_info(systemdb_info);
955 errorcode = NOMEMERR;
959 index = (char *) memchr(index, '\0', rsize) + 1;
961 dist_def_info->col_num = atoi(index);
963 dist_def_info->col_list = NULL;
964 dist_def_info->col_list = (char **)malloc(sizeof(char *) * dist_def_info->col_num);
965 if (dist_def_info->col_list == NULL)
968 free_systemdb_info(systemdb_info);
969 errorcode = NOMEMERR;
972 for (i = 0; i < dist_def_info->col_num; i++)
974 index = (char *) memchr(index, '\0', rsize) + 1;
976 dist_def_info->col_list[i] = strdup(index);
977 if (dist_def_info->col_list[i] == NULL)
980 free_systemdb_info(systemdb_info);
981 errorcode = NOMEMERR;
986 dist_def_info->type_list = NULL;
987 dist_def_info->type_list = (char **)malloc(sizeof(char *) * dist_def_info->col_num);
988 if (dist_def_info->type_list == NULL)
991 free_systemdb_info(systemdb_info);
992 errorcode = NOMEMERR;
995 for (i = 0; i < dist_def_info->col_num; i++)
997 index = (char *) memchr(index, '\0', rsize) + 1;
999 dist_def_info->type_list[i] = strdup(index);
1000 if (dist_def_info->type_list[i] == NULL)
1003 free_systemdb_info(systemdb_info);
1004 errorcode = NOMEMERR;
1009 index = (char *) memchr(index, '\0', rsize) + 1;
1011 dist_def_info->dist_def_func = strdup(index);
1012 if (dist_def_info->dist_def_func == NULL)
1015 free_systemdb_info(systemdb_info);
1016 errorcode = NOMEMERR;
1020 memcpy(&systemdb_info->dist_def_slot[offset++], dist_def_info, sizeof(DistDefInfo));
1022 else if (strcmp(buf, "CommandComplete") == 0)
1025 return systemdb_info;
1039 free_systemdb_info(SystemDBInfo * si)
1046 free(si->schema_name);
1047 free(si->database_name);
1049 if (si->dist_def_slot != NULL)
1051 for (i = 0; i < si->dist_def_num; i++)
1053 DistDefInfo *di = &si->dist_def_slot[i];
1055 free(di->schema_name);
1056 free(di->table_name);
1057 free(di->dist_def_func);
1058 for (j = 0; j < di->col_num; j++)
1060 free(di->col_list[j]);
1061 free(di->type_list[j]);
1069 /* --------------------------------
1070 * pcp_detach_node - dettach a node given by the argument from pgpool's control
1072 * return 0 on success, -1 otherwise
1073 * --------------------------------
1076 pcp_detach_node(int nid)
1086 if (debug) fprintf(stderr, "DEBUG: connection does not exist\n");
1087 errorcode = NOCONNERR;
1091 snprintf(node_id, sizeof(node_id), "%d", nid);
1093 pcp_write(pc, "D", 1);
1094 wsize = htonl(strlen(node_id)+1 + sizeof(int));
1095 pcp_write(pc, &wsize, sizeof(int));
1096 pcp_write(pc, node_id, strlen(node_id)+1);
1097 if (pcp_flush(pc) < 0)
1099 if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n");
1102 if (debug) fprintf(stderr, "DEBUG: send: tos=\"D\", len=%d\n", ntohl(wsize));
1104 if (pcp_read(pc, &tos, 1))
1106 if (pcp_read(pc, &rsize, sizeof(int)))
1108 rsize = ntohl(rsize);
1109 buf = (char *)malloc(rsize);
1112 errorcode = NOMEMERR;
1115 if (pcp_read(pc, buf, rsize - sizeof(int)))
1120 if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf);
1124 if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf);
1125 errorcode = BACKENDERR;
1127 else if (tos == 'd')
1129 /* strcmp() for success message, or fail */
1130 if(strcmp(buf, "CommandComplete") == 0)
1142 /* --------------------------------
1143 * pcp_attach_node - attach a node given by the argument from pgpool's control
1145 * return 0 on success, -1 otherwise
1146 * --------------------------------
1149 pcp_attach_node(int nid)
1159 if (debug) fprintf(stderr, "DEBUG: connection does not exist\n");
1160 errorcode = NOCONNERR;
1164 snprintf(node_id, sizeof(node_id), "%d", nid);
1166 pcp_write(pc, "C", 1);
1167 wsize = htonl(strlen(node_id)+1 + sizeof(int));
1168 pcp_write(pc, &wsize, sizeof(int));
1169 pcp_write(pc, node_id, strlen(node_id)+1);
1170 if (pcp_flush(pc) < 0)
1172 if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n");
1175 if (debug) fprintf(stderr, "DEBUG: send: tos=\"D\", len=%d\n", ntohl(wsize));
1177 if (pcp_read(pc, &tos, 1))
1179 if (pcp_read(pc, &rsize, sizeof(int)))
1181 rsize = ntohl(rsize);
1182 buf = (char *)malloc(rsize);
1185 errorcode = NOMEMERR;
1188 if (pcp_read(pc, buf, rsize - sizeof(int)))
1193 if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf);
1197 if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf);
1198 errorcode = BACKENDERR;
1200 else if (tos == 'c')
1202 /* strcmp() for success message, or fail */
1203 if(strcmp(buf, "CommandComplete") == 0)
1215 pcp_set_timeout(long sec)
1217 /* disable timeout (wait forever!) (2008/02/08 yamaguti) */
1219 pcp_timeout.tv_sec = sec;
1224 pcp_recovery_node(int nid)
1234 if (debug) fprintf(stderr, "DEBUG: connection does not exist\n");
1235 errorcode = NOCONNERR;
1239 snprintf(node_id, sizeof(node_id), "%d", nid);
1241 pcp_write(pc, "O", 1);
1242 wsize = htonl(strlen(node_id)+1 + sizeof(int));
1243 pcp_write(pc, &wsize, sizeof(int));
1244 pcp_write(pc, node_id, strlen(node_id)+1);
1245 if (pcp_flush(pc) < 0)
1247 if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n");
1250 if (debug) fprintf(stderr, "DEBUG: send: tos=\"D\", len=%d\n", ntohl(wsize));
1252 if (pcp_read(pc, &tos, 1))
1254 if (pcp_read(pc, &rsize, sizeof(int)))
1256 rsize = ntohl(rsize);
1257 buf = (char *)malloc(rsize);
1260 errorcode = NOMEMERR;
1263 if (pcp_read(pc, buf, rsize - sizeof(int)))
1268 if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf);
1272 if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf);
1273 errorcode = BACKENDERR;
1275 else if (tos == 'c')
1277 /* strcmp() for success message, or fail */
1278 if(strcmp(buf, "CommandComplete") == 0)
1290 pcp_enable_debug(void)
1296 pcp_disable_debug(void)