1 /*- 2 * Copyright (c) 2009-2010 The FreeBSD Foundation 3 * Copyright (c) 2010 Mikolaj Golub <to.my.trociny@gmail.com> 4 * All rights reserved. 5 * 6 * This software wss developed by Mikolaj Golub. The source is derived 7 * from HAST developed by Pawel Jakub Dawidek under sponsorship from 8 * the FreeBSD Foundation. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 */ 32 33 #ifndef _HAST_H_ 34 #define _HAST_H_ 35 36 #include <sys/cdefs.h> 37 #include <sys/types.h> 38 39 #ifdef HAVE_DEFINE_TAILQ_FOREACH_SAFE_SYS_QUEUE_H 40 #include <sys/queue.h> 41 #else 42 #include "queue.h" 43 #endif 44 #include <sys/socket.h> 45 46 #include <netinet/in.h> 47 #include <arpa/inet.h> 48 49 #include <limits.h> 50 #include <pthread.h> 51 #include <stdbool.h> 52 #include <stdint.h> 53 54 #include "auth.h" 55 #include "proto.h" 56 57 #define HAST_PROTO_VERSION 0 58 59 #define EHAST_OK 0 60 #define EHAST_NOENTRY 1 61 #define EHAST_INVALID 2 62 #define EHAST_NOMEMORY 3 63 #define EHAST_UNIMPLEMENTED 4 64 #define EHAST_AUTHFAILED 5 65 66 #define HASTREQ_TYPE_UNKNOWN 0 67 #define HASTREQ_TYPE_CONTROL 1 68 #define HASTREQ_TYPE_COMPLAINT 2 69 70 #define HASTCTL_CMD_UNKNOWN 0 71 #define HASTCTL_CMD_SETROLE 1 72 #define HASTCTL_CMD_STATUS 2 73 74 #define HAST_ROLE_UNDEF 0 75 #define HAST_ROLE_INIT 1 76 #define HAST_ROLE_PRIMARY 2 77 #define HAST_ROLE_SECONDARY 3 78 #define HAST_ROLE_WATCHDOG 4 79 80 #define HAST_STATE_UNKNOWN 0 81 #define HAST_STATE_READYTORUN 1 82 #define HAST_STATE_STARTING 2 83 #define HAST_STATE_RUN 3 84 #define HAST_STATE_STOPPING 4 85 #define HAST_STATE_STOPPED 5 86 #define HAST_STATE_FAILED 6 87 88 #define HIO_UNDEF 0 89 #define HIO_STATE 1 90 91 #define HAST_TIMEOUT 5 92 #define HAST_CONFIG "/usr/local/etc/hastmon.conf" 93 #define HAST_CONTROL "/var/run/hastmonctl" 94 #define HAST_PORT 8458 95 #define HAST_LISTEN "tcp4://0.0.0.0:8458" 96 #define HAST_PIDFILE "/var/run/hastmon.pid" 97 #define HAST_ATTEMPTS 5 98 #define HAST_HBEAT_INT 10 99 #define HAST_CMPLNT_CNT 3 100 #define HAST_CMPLNT_INT 60 101 102 #define HAST_ADDRSIZE 1024 103 #define HAST_TOKEN_SIZE 16 104 #define HAST_KEYMAX 1024 105 106 struct hastmon_config { 107 /* Address to communicate with hastctl(8). */ 108 char hc_controladdr[HAST_ADDRSIZE]; 109 /* Protocol-specific data. */ 110 struct proto_conn *hc_controlconn; 111 /* Incoming control connection. */ 112 struct proto_conn *hc_controlin; 113 /* Address to listen on. */ 114 char hc_listenaddr[HAST_ADDRSIZE]; 115 /* Protocol-specific data. */ 116 struct proto_conn *hc_listenconn; 117 /* Global list of addresses that can connect to us. */ 118 TAILQ_HEAD(, hast_address) hc_friends; 119 /* List of resources. */ 120 TAILQ_HEAD(, hast_resource) hc_resources; 121 }; 122 123 /* 124 * Structure that describes single resource. 125 */ 126 struct hast_resource { 127 /* Resource name. */ 128 char hr_name[NAME_MAX]; 129 130 /* Path to a program to execute on various events. */ 131 char hr_exec[PATH_MAX]; 132 133 /* Resource unique identifier. */ 134 uint64_t hr_resuid; 135 136 /* This node priority being primary for the resourse. */ 137 int hr_priority; 138 139 /* Resource role: HAST_ROLE_{INIT,PRIMARY,SECONDARY,WATCHDOG}. */ 140 int hr_role; 141 /* Previous resource role: HAST_ROLE_{INIT,PRIMARY,SECONDARY,WATCHDOG}. */ 142 int hr_previous_role; 143 /* Resource role on start: HAST_ROLE_{INIT,PRIMARY,SECONDARY,WATCHDOG}. */ 144 int hr_role_on_start; 145 /* PID of child worker process. 0 - no child. */ 146 pid_t hr_workerpid; 147 /* Control connection between parent and child. */ 148 struct proto_conn *hr_ctrl; 149 /* Events from child to parent. */ 150 struct proto_conn *hr_event; 151 /* Connection timeout. */ 152 int hr_timeout; 153 /* Resource state: HAST_STATE_{UNKNOWN,STARTING,RUN,STOPPING,STOPPED,FAILED}. */ 154 int hr_local_state; 155 /* Number of attemps to start resource. */ 156 int hr_local_attempts; 157 /* Number of attemps after which the resourse is considered failed. */ 158 int hr_local_attempts_max; 159 160 /* Time of the last received STATUS request from a remote (watchdog). */ 161 time_t hr_remote_lastcheck; 162 163 /* Per resource list of addresses that can connect to us. */ 164 TAILQ_HEAD(, hast_address) hr_friends; 165 166 /* Key used for authentication. */ 167 struct hast_auth hr_key; 168 169 /* Number of remote components. */ 170 int hr_remote_cnt; 171 172 /* List of remote components. */ 173 TAILQ_HEAD(, hast_remote) hr_remote; 174 175 /* Number of complaints we want to receive before failovering. */ 176 int hr_complaint_critical_cnt; 177 /* Period of time (in sec) complaints are counted. */ 178 int hr_complaint_interval; 179 180 /* Period of time (in sec) between heartbeats. */ 181 int hr_heartbeat_interval; 182 183 /* Complaints. */ 184 TAILQ_HEAD(, hast_complaint) hr_complaints; 185 186 /* Locked used to synchronize access to resourse. */ 187 pthread_mutex_t hr_lock; 188 189 /* Next resource. */ 190 TAILQ_ENTRY(hast_resource) hr_next; 191 }; 192 193 struct hast_remote { 194 /* Address of the remote component. */ 195 char r_addr[HAST_ADDRSIZE]; 196 /* Connection for incoming data. */ 197 struct proto_conn *r_in; 198 /* Connection for outgoing data. */ 199 struct proto_conn *r_out; 200 /* Token to verify both in and out connection are coming from 201 the same node (not necessarily from the same address). */ 202 unsigned char r_token[HAST_TOKEN_SIZE]; 203 /* Remote role: HAST_ROLE_{INIT,PRIMARY,SECONDARY,WATCHDOG}. */ 204 int r_role; 205 /* Remote state: HAST_STATE_{UNKNOWN,STARTING,RUN,STOPPING,STOPPED}. */ 206 int r_state; 207 /* Pointer to resurce */ 208 struct hast_resource *r_res; 209 /* This component number */ 210 int r_ncomp; 211 /* Next remote. */ 212 TAILQ_ENTRY(hast_remote) r_next; 213 }; 214 215 struct hast_address { 216 char a_addr[HAST_ADDRSIZE]; 217 TAILQ_ENTRY(hast_address) a_next; 218 }; 219 220 struct hast_complaint { 221 time_t c_time; 222 TAILQ_ENTRY(hast_complaint) c_next; 223 }; 224 225 struct hastmon_config *yy_config_parse(const char *config, bool exitonerror); 226 void yy_resource_free(struct hast_resource *res); 227 void yy_config_free(struct hastmon_config *config); 228 229 void yyerror(const char *); 230 int yylex(void); 231 int yyparse(void); 232 233 #endif /* !_HAST_H_ */ 234