1 /* -*-pgsql-c-*- */
2 /*
3  *
4  * $Header$
5  *
6  * pgpool: a language independent connection pool server for PostgreSQL
7  * written by Tatsuo Ishii
8  *
9  * Copyright (c) 2003-2019	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  * watchdog.h.: watchdog definition header file
23  *
24  */
25 
26 #ifndef WATCHDOG_H
27 #define WATCHDOG_H
28 
29 #include <sys/time.h>
30 #include "pool_config.h"
31 
32 #define WD_TIME_INIT(tv)      ((tv).tv_sec = (tv).tv_usec = 0)
33 #define WD_TIME_ISSET(tv)     ((tv).tv_sec || (tv).tv_usec)
34 #define WD_TIME_BEFORE(a,b)   (((a).tv_sec == (b).tv_sec) ? \
35                                ((a).tv_usec < (b).tv_usec) : \
36                                ((a).tv_sec < (b).tv_sec))
37 #define WD_TIME_DIFF_SEC(a,b) (int)(((a).tv_sec - (b).tv_sec) + \
38                                     ((a).tv_usec - (b).tv_usec) / 1000000.0)
39 
40 /*
41 * Data version number of watchdog messages
42 * The version number is in major.minor format
43 * The major versions are always kept compatible.
44 *
45 * Increment the minor version whenever a minor change is
46 * made to message data, where the older versions can still
47 * work even when that change is not present in it.
48 *
49 * while incrementing the major version would mean that
50 * the watchdog node with older major version will not be
51 * allowed to join the cluster
52 *
53 * Since the message data version was not present from the
54 * beginning, so the default version is considered to be 1.0
55 * meaning if the data version number is not present in the
56 * watchdog node info then it will be considered as version 1.0
57 */
58 
59 #define WD_MESSAGE_DATA_VERSION_MAJOR	"1"
60 #define WD_MESSAGE_DATA_VERSION_MINOR	"1"
61 #define WD_MESSAGE_DATA_VERSION	WD_MESSAGE_DATA_VERSION_MAJOR "." WD_MESSAGE_DATA_VERSION_MINOR
62 #define MAX_VERSION_STR_LEN		10
63 
64 /*
65  * watchdog state
66  */
67 typedef enum {
68 	WD_DEAD = 0,
69 	WD_LOADING,
70 	WD_JOINING,
71 	WD_INITIALIZING,
72 	WD_COORDINATOR,
73 	WD_PARTICIPATE_IN_ELECTION,
74 	WD_STAND_FOR_COORDINATOR,
75 	WD_STANDBY,
76 	WD_LOST,
77 	/* the following states are only valid on local node */
78 	WD_IN_NW_TROUBLE,
79 	/* the following states are only valid on remote nodes */
80 	WD_SHUTDOWN,
81 	WD_ADD_MESSAGE_SENT,
82 	WD_NETWORK_ISOLATION
83 } WD_STATES;
84 
85 typedef enum {
86 	WD_SOCK_UNINITIALIZED = 0,
87 	WD_SOCK_CREATED,
88 	WD_SOCK_WAITING_FOR_CONNECT,
89 	WD_SOCK_CONNECTED,
90 	WD_SOCK_ERROR,
91 	WD_SOCK_CLOSED
92 } WD_SOCK_STATE;
93 
94 typedef enum {
95 	WD_EVENT_WD_STATE_CHANGED = 0,
96 	WD_EVENT_TIMEOUT,
97 	WD_EVENT_PACKET_RCV,
98 	WD_EVENT_COMMAND_FINISHED,
99 	WD_EVENT_NEW_OUTBOUND_CONNECTION,
100 
101 	WD_EVENT_NW_IP_IS_REMOVED,
102 	WD_EVENT_NW_IP_IS_ASSIGNED,
103 
104 	WD_EVENT_NW_LINK_IS_INACTIVE,
105 	WD_EVENT_NW_LINK_IS_ACTIVE,
106 
107 	WD_EVENT_LOCAL_NODE_LOST,
108 	WD_EVENT_REMOTE_NODE_LOST,
109 	WD_EVENT_REMOTE_NODE_FOUND,
110 	WD_EVENT_LOCAL_NODE_FOUND,
111 
112 	WD_EVENT_NODE_CON_LOST,
113 	WD_EVENT_NODE_CON_FOUND,
114 	WD_EVENT_CLUSTER_QUORUM_CHANGED,
115 	WD_EVENT_WD_STATE_REQUIRE_RELOAD,
116 	WD_EVENT_I_AM_APPEARING_LOST,
117 	WD_EVENT_I_AM_APPEARING_FOUND
118 }			WD_EVENTS;
119 
120 typedef enum {
121 	NODE_LOST_UNKNOWN_REASON,
122 	NODE_LOST_BY_LIFECHECK,
123 	NODE_LOST_BY_SEND_FAILURE,
124 	NODE_LOST_BY_MISSING_BEACON,
125 	NODE_LOST_BY_RECEIVE_TIMEOUT,
126 	NODE_LOST_BY_NOT_REACHABLE,
127 	NODE_LOST_SHUTDOWN
128 } WD_NODE_LOST_REASONS;
129 
130 typedef struct SocketConnection
131 {
132 	int				sock;			/* socket descriptor */
133 	struct			timeval tv;		/* connect time of socket */
134 	char			addr[48];		/* ip address of socket connection*/
135 	WD_SOCK_STATE	sock_state;		/* current state of socket */
136 }SocketConnection;
137 
138 typedef struct WatchdogNode
139 {
140 	WD_STATES state;
141 	struct timeval current_state_time;		/* time value when the node state last changed*/
142 	struct timeval startup_time;			/* startup time value of node */
143 	struct timeval last_rcv_time;			/* timestamp when last packet
144 											 * was received from the node
145 											 */
146 	struct timeval last_sent_time;			/* timestamp when last packet
147 											 * was sent on the node
148 											 */
149 	bool   has_lost_us;             		/*
150 											 * True when this remote node thinks
151 											 * we are lost
152 											 */
153 	int    sending_failures_count;  		/* number of times we have failed
154 											 * to send message to the node.
155 											 * Gets reset after successfull sent
156 											 */
157 	int    missed_beacon_count;     		/* number of times the node has
158 											 * failed to reply for beacon.
159 											 * message
160 											 */
161 	WD_NODE_LOST_REASONS node_lost_reason;
162 
163 	char		pgp_version[MAX_VERSION_STR_LEN];		/* Pgpool-II version */
164 	int			wd_data_major_version;	/* watchdog messaging version major*/
165 	int			wd_data_minor_version;  /* watchdog messaging version minor*/
166 
167 	char nodeName[WD_MAX_HOST_NAMELEN];		/* name of this node */
168 	char hostname[WD_MAX_HOST_NAMELEN];		/* host name */
169 	int wd_port;							/* watchdog port */
170 	int pgpool_port;						/* pgpool port */
171 	int wd_priority;						/* watchdog priority */
172 	char delegate_ip[WD_MAX_HOST_NAMELEN];	/* delegate IP */
173 	int	private_id;							/* ID assigned to this node
174 											 * This id is consumed locally
175 											 */
176 	int standby_nodes_count;				/* number of standby nodes joined the cluster
177 											 * only applicable when this WatchdogNode is
178 											 * the master/coordinator node*/
179 	int quorum_status;						/* quorum status on the node */
180 	bool escalated;							/* true if the Watchdog node has
181 											 * performed escalation */
182 	SocketConnection server_socket;			/* socket connections for this node initiated by remote */
183 	SocketConnection client_socket;			/* socket connections for this node initiated by local*/
184 }WatchdogNode;
185 
186 extern pid_t initialize_watchdog(void);
187 
188 #endif /* WATCHDOG_H */
189 
190 
191