CUBRID Engine  latest
master.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * master.c - master main
21  */
22 
23 #ident "$Id$"
24 
25 #include "config.h"
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <errno.h>
31 #include <time.h>
32 
33 #if defined(_AIX)
34 #include <sys/select.h>
35 #endif
36 
37 #if defined(WINDOWS)
38 #include <winsock2.h>
39 #include <time.h>
40 #include <fcntl.h>
41 #include <signal.h>
42 #include <io.h>
43 #else /* ! WINDOWS */
44 #include <sys/types.h>
45 #include <sys/wait.h>
46 #include <sys/time.h>
47 #include <netdb.h>
48 #include <sys/param.h>
49 #include <sys/resource.h>
50 #include <netinet/in.h>
51 #include <unistd.h>
52 #include <fcntl.h>
53 #include <syslog.h>
54 #include <pthread.h>
55 #endif /* ! WINDOWS */
56 
57 #include "utility.h"
58 #include "porting.h"
59 #include "error_manager.h"
60 #include "connection_globals.h"
61 #include "connection_cl.h"
62 #if defined(WINDOWS)
63 #include "wintcp.h"
64 #else /* ! WINDOWS */
65 #include "tcp.h"
66 #endif /* ! WINDOWS */
67 #include "master_util.h"
68 #include "master_request.h"
69 #if !defined(WINDOWS)
70 #include "master_heartbeat.h"
71 #endif
72 #include "environment_variable.h"
73 #include "message_catalog.h"
74 #include "dbi.h"
75 #include "util_func.h"
76 
77 static void css_master_error (const char *error_string);
78 static int css_master_timeout (void);
79 static int css_master_init (int cport, SOCKET * clientfd);
80 static void css_reject_client_request (CSS_CONN_ENTRY * conn, unsigned short rid, int reason);
81 static void css_reject_server_request (CSS_CONN_ENTRY * conn, int reason);
82 static void css_accept_server_request (CSS_CONN_ENTRY * conn, int reason);
83 static void css_accept_new_request (CSS_CONN_ENTRY * conn, unsigned short rid, char *server_name,
84  int server_name_length);
85 static void css_accept_old_request (CSS_CONN_ENTRY * conn, unsigned short rid, SOCKET_QUEUE_ENTRY * entry,
86  char *server_name, int server_name_length);
87 static void css_register_new_server (CSS_CONN_ENTRY * conn, unsigned short rid);
88 static void css_register_new_server2 (CSS_CONN_ENTRY * conn, unsigned short rid);
89 static bool css_send_new_request_to_server (SOCKET server_fd, SOCKET client_fd, unsigned short rid,
90  CSS_SERVER_REQUEST request);
91 static void css_send_to_existing_server (CSS_CONN_ENTRY * conn, unsigned short rid, CSS_SERVER_REQUEST request);
92 static void css_process_new_connection (SOCKET fd);
93 static int css_enroll_read_sockets (SOCKET_QUEUE_ENTRY * anchor_p, fd_set * fd_var);
94 static int css_enroll_write_sockets (SOCKET_QUEUE_ENTRY * anchor_p, fd_set * fd_var);
95 static int css_enroll_exception_sockets (SOCKET_QUEUE_ENTRY * anchor_p, fd_set * fd_var);
96 
97 static int css_enroll_master_read_sockets (fd_set * fd_var);
98 static int css_enroll_master_write_sockets (fd_set * fd_var);
99 static int css_enroll_master_exception_sockets (fd_set * fd_var);
100 static void css_master_select_error (void);
101 static void css_check_master_socket_input (int *count, fd_set * fd_var);
102 static void css_check_master_socket_output (void);
103 static int css_check_master_socket_exception (fd_set * fd_var);
104 static void css_master_loop (void);
105 static void css_free_entry (SOCKET_QUEUE_ENTRY * entry_p);
106 
107 #if !defined(WINDOWS)
108 static void css_daemon_start (void);
109 #endif
110 
111 struct timeval *css_Master_timeout = NULL;
114 #if defined(DEBUG)
115 static int css_Active_server_count = 0;
116 #endif
117 
120 
121 /* socket for incoming client requests */
123 
124 /* This is the queue anchor of sockets used by the Master server. */
126 #if !defined(WINDOWS)
128 #endif
129 pthread_mutex_t css_Master_er_log_lock = PTHREAD_MUTEX_INITIALIZER;
130 pthread_mutex_t css_Master_er_log_enable_lock = PTHREAD_MUTEX_INITIALIZER;
132 
133 /*
134  * css_master_error() - print error message to syslog or console
135  * return: none
136  * error_string(in)
137  *
138  * Note: Errors encountered by the master will always be printed.
139  */
140 static void
141 css_master_error (const char *error_string)
142 {
143 #if defined(WINDOWS)
144  /* send it to the invoking console */
145  fprintf (stderr, "Master process: %s\n", error_string);
146  perror ("css_master_error");
147 #else /* ! WINDOWS */
148  syslog (LOG_ALERT, "Master process: %s %s\n", error_string, errno > 0 ? strerror (errno) : "");
149 #endif /* ! WINDOWS */
150 }
151 
152 /*
153  * css_master_timeout()
154  * return: 0 if css_Master_timeout time is expired,
155  * otherwise 1
156  *
157  * Note:
158  * This is to handle the case when nothing is happening. We will check the
159  * process status to see if the server is still running. If not, then we
160  * remove our entry.
161  */
162 static int
164 {
165 #if !defined(WINDOWS)
166  int rv;
167  SOCKET_QUEUE_ENTRY *temp;
168 #endif
169  struct timeval timeout;
170 
171  /* check for timeout */
172  if (css_Master_timeout && time ((time_t *) (&timeout.tv_sec)) != (time_t) (-1)
173  && css_Master_timeout->tv_sec < timeout.tv_sec)
174  {
175  return (0);
176  }
177 
178 #if !defined(WINDOWS)
179  /* On the WINDOWS, it is not clear if we will ever have spawned child processes, at least initially. There don't
180  * appear to be any similarly named "wait" functions in the MSVC runtime library. */
182  for (temp = css_Master_socket_anchor; temp; temp = temp->next)
183  {
184  if (kill (temp->pid, 0) && errno == ESRCH)
185  {
186 #if defined(DEBUG)
187  if (css_Active_server_count > 0)
188  {
189  css_Active_server_count--;
190  }
191 #endif
192 #if !defined(WINDOWS)
193  if (temp->ha_mode)
194  {
196  }
197  else
198 #endif
199  {
200  css_remove_entry_by_conn (temp->conn_ptr, &css_Master_socket_anchor);
201  }
202  break;
203  }
204  }
206 #endif
207  return (1);
208 }
209 
210 /*
211  * css_master_cleanup() - cleanup the socket on the port-id
212  * return: none
213  * sig(in)
214  *
215  * Note: It will not be called if we are killed by an outside process
216  */
217 void
219 {
222 #if !defined(WINDOWS)
223  unlink (css_get_master_domain_path ());
224 
225  if (!HA_DISABLED ())
226  {
228  }
229 #endif
230  exit (1);
231 }
232 
233 /*
234  * css_master_init() - setup the signal handling routines and attempt to
235  * bind the socket address
236  * return: 1 if success, otherwise 0
237  * cservice(in)
238  * clientfd(out)
239  */
240 static int
241 css_master_init (int cport, SOCKET * clientfd)
242 {
243 #if defined(WINDOWS)
244  if (os_set_signal_handler (SIGABRT, css_master_cleanup) == SIG_ERR
245  || os_set_signal_handler (SIGINT, css_master_cleanup) == SIG_ERR
246  || os_set_signal_handler (SIGTERM, css_master_cleanup) == SIG_ERR)
247  {
249  return (0);
250  }
251 #else /* ! WINDOWS */
252  (void) os_set_signal_handler (SIGSTOP, css_master_cleanup);
253  if (os_set_signal_handler (SIGTERM, css_master_cleanup) == SIG_ERR
254  || os_set_signal_handler (SIGINT, css_master_cleanup) == SIG_ERR
255  || os_set_signal_handler (SIGPIPE, SIG_IGN) == SIG_ERR || os_set_signal_handler (SIGCHLD, SIG_IGN) == SIG_ERR)
256  {
258  return (0);
259  }
260 #endif /* ! WINDOWS */
261 
262 #if !defined(WINDOWS)
264 #endif
265 
266  return (css_tcp_master_open (cport, clientfd));
267 }
268 
269 /*
270  * css_reject_client_request() - Sends the reject reason to the client
271  * if the server cannot immediatly accept a connection.
272  * return: none
273  * conn(in)
274  * rid(in)
275  * reason(in)
276  */
277 static void
278 css_reject_client_request (CSS_CONN_ENTRY * conn, unsigned short rid, int reason)
279 {
280  int reject_reason;
281 
282  reject_reason = htonl (reason);
283  css_send_data (conn, rid, (char *) &reject_reason, sizeof (int));
284 }
285 
286 /*
287  * css_reject_server_request() - Sends a reject message to a server request
288  * return: none
289  * conn(in)
290  * reason(in)
291  */
292 static void
294 {
295  int reject_reason;
296 
297  reject_reason = htonl (reason);
298  send (conn->fd, (char *) &reject_reason, sizeof (int), 0);
299 }
300 
301 /*
302  * css_accept_server_request() - Sends an accept reply to the server to
303  * indicate that it is now connected to the master server
304  * return: none
305  * conn(in)
306  * reason(in)
307  */
308 static void
310 {
311  int accept_reason;
312 
313  accept_reason = htonl (reason);
314  send (conn->fd, (char *) &accept_reason, sizeof (int), 0);
315 }
316 
317 /*
318  * css_accept_new_request() - Accepts a connect request from a new server
319  * return: none
320  * conn(in)
321  * rid(in)
322  * server_name(in)
323  * server_name_length(in)
324  */
325 static void
326 css_accept_new_request (CSS_CONN_ENTRY * conn, unsigned short rid, char *server_name, int server_name_length)
327 {
328  char *datagram;
329  int datagram_length;
330  SOCKET server_fd = INVALID_SOCKET;
331  int length;
332  CSS_CONN_ENTRY *datagram_conn;
333  SOCKET_QUEUE_ENTRY *entry;
334 
335  datagram = NULL;
336  datagram_length = 0;
338  if (css_receive_data (conn, rid, &datagram, &datagram_length, -1) == NO_ERRORS)
339  {
340  if (datagram != NULL && css_tcp_master_datagram (datagram, &server_fd))
341  {
342  datagram_conn = css_make_conn (server_fd);
343 #if defined(DEBUG)
344  css_Active_server_count++;
345 #endif
346  css_add_request_to_socket_queue (datagram_conn, false, server_name, server_fd, READ_WRITE, 0,
347  &css_Master_socket_anchor);
348  length = (int) strlen (server_name) + 1;
349  if (length < server_name_length)
350  {
351  entry = css_return_entry_of_server (server_name, css_Master_socket_anchor);
352  if (entry != NULL)
353  {
354  server_name += length;
355  entry->version_string = (char *) malloc (strlen (server_name) + 1);
356  if (entry->version_string != NULL)
357  {
358  strcpy (entry->version_string, server_name);
359  server_name += strlen (entry->version_string) + 1;
360 
361  entry->env_var = (char *) malloc (strlen (server_name) + 1);
362  if (entry->env_var != NULL)
363  {
364  strcpy (entry->env_var, server_name);
365  }
366 
367  server_name += strlen (server_name) + 1;
368 
369  entry->pid = atoi (server_name);
370  }
371  else
372  {
373  entry->env_var = NULL;
374  }
375  }
376  }
377  }
378  }
379  if (datagram)
380  {
381  free_and_init (datagram);
382  }
383 }
384 
385 /*
386  * css_accept_old_request() - Accepts a connect request from a server
387  * return: none
388  * conn(in)
389  * rid(in)
390  * entry(out)
391  * server_name(in)
392  * server_name_length(in)
393  */
394 static void
395 css_accept_old_request (CSS_CONN_ENTRY * conn, unsigned short rid, SOCKET_QUEUE_ENTRY * entry, char *server_name,
396  int server_name_length)
397 {
398  char *datagram;
399  int datagram_length;
400  SOCKET server_fd = INVALID_SOCKET;
401  int length;
402  CSS_CONN_ENTRY *datagram_conn;
403 
404  datagram = NULL;
405  datagram_length = 0;
407  if (css_receive_data (conn, rid, &datagram, &datagram_length, -1) == NO_ERRORS)
408  {
409  if (datagram != NULL && css_tcp_master_datagram (datagram, &server_fd))
410  {
411  datagram_conn = css_make_conn (server_fd);
412  entry->fd = server_fd;
413  css_free_conn (entry->conn_ptr);
414  entry->conn_ptr = datagram_conn;
415  length = (int) strlen (server_name) + 1;
416  if (length < server_name_length)
417  {
418  server_name += length;
419  if ((entry->version_string = (char *) malloc (strlen (server_name) + 1)) != NULL)
420  {
421  strcpy (entry->version_string, server_name);
422  }
423  }
424  }
425  }
426  if (datagram)
427  {
428  free_and_init (datagram);
429  }
430 }
431 
432 /*
433  * css_register_new_server() - register a new server by reading the server name
434  * return: none
435  * conn(in)
436  * rid(in)
437  *
438  * Note: This will allow us to pass fds for future requests to the server.
439  */
440 static void
441 css_register_new_server (CSS_CONN_ENTRY * conn, unsigned short rid)
442 {
443  int name_length;
444  char *server_name = NULL;
445  SOCKET_QUEUE_ENTRY *entry;
446 
447  /* read server name */
448  if (css_receive_data (conn, rid, &server_name, &name_length, -1) == NO_ERRORS)
449  {
450  entry = css_return_entry_of_server (server_name, css_Master_socket_anchor);
451  if (entry != NULL)
452  {
453  if (IS_INVALID_SOCKET (entry->fd))
454  {
455  /* accept a server that was auto-started */
456  css_accept_old_request (conn, rid, entry, server_name, name_length);
457  }
458  else
459  {
460  /* reject a server with a duplicate name */
462  }
463  }
464  else
465  {
466 #if defined(WINDOWS)
468 #if defined(DEBUG)
469  css_Active_server_count++;
470 #endif
471  css_add_request_to_socket_queue (conn, false, server_name, conn->fd, READ_WRITE, 0,
472  &css_Master_socket_anchor);
473 
474 #else /* ! WINDOWS */
475  /* accept a request from a new server */
476  css_accept_new_request (conn, rid, server_name, name_length);
477 #endif /* ! WINDOWS */
478  }
479  }
480  if (server_name != NULL)
481  {
482  free_and_init (server_name);
483  }
484 
485 #if !defined(WINDOWS)
486  /* WINDOWS wants to keep this conn--it is the main connection */
487  css_free_conn (conn);
488 #endif /* ! WINDOWS */
489 }
490 
491 /*
492  * css_register_new_server2()
493  * return: none
494  * conn(in)
495  * rid(in)
496  *
497  * Note:
498  * Register a server using the new-style of connection protocol where
499  * the port id is given to us explicitly.
500  */
501 static void
502 css_register_new_server2 (CSS_CONN_ENTRY * conn, unsigned short rid)
503 {
504  int name_length;
505  char *server_name = NULL;
506  SOCKET_QUEUE_ENTRY *entry;
507  int buffer;
508  int server_name_length, length;
509 
510  /* read server name */
511  if (css_receive_data (conn, rid, &server_name, &name_length, -1) == NO_ERRORS && server_name != NULL)
512  {
513  entry = css_return_entry_of_server (server_name, css_Master_socket_anchor);
514  if (entry != NULL)
515  {
516  if (IS_INVALID_SOCKET (entry->fd))
517  {
518  /* accept a server */
519  css_accept_old_request (conn, rid, entry, server_name, name_length);
520  }
521  else
522  {
523  /* reject a server with a duplicate name */
525  }
526  css_free_conn (conn);
527  }
528  else
529  {
530  /* save length info */
531  server_name_length = name_length;
532 
533  /* accept but make it send us a port id */
535  name_length = sizeof (buffer);
536  if (css_net_recv (conn->fd, (char *) &buffer, &name_length, -1) == NO_ERRORS)
537  {
538 #if defined(DEBUG)
539  css_Active_server_count++;
540 #endif
541  entry =
542  css_add_request_to_socket_queue (conn, false, server_name, conn->fd, READ_WRITE, 0,
543  &css_Master_socket_anchor);
544  /* store this for later */
545  if (entry != NULL)
546  {
547  entry->port_id = ntohl (buffer);
548  length = (int) strlen (server_name) + 1;
549  /* read server version_string, env_var, pid */
550  if (length < server_name_length)
551  {
552  entry = css_return_entry_of_server (server_name, css_Master_socket_anchor);
553  if (entry != NULL)
554  {
555  char *recv_data;
556 
557  recv_data = server_name + length;
558  entry->version_string = (char *) malloc (strlen (recv_data) + 1);
559  if (entry->version_string != NULL)
560  {
561  strcpy (entry->version_string, recv_data);
562  recv_data += strlen (entry->version_string) + 1;
563  entry->env_var = (char *) malloc (strlen (recv_data) + 1);
564  if (entry->env_var != NULL)
565  {
566  strcpy (entry->env_var, recv_data);
567  }
568  recv_data += strlen (recv_data) + 1;
569  entry->pid = atoi (recv_data);
570  }
571  else
572  {
573  entry->env_var = NULL;
574  }
575  }
576  }
577  }
578  else
579  {
580  css_free_conn (conn);
581  }
582  }
583  else
584  {
585  css_free_conn (conn);
586  }
587  }
588  }
589  else
590  {
591  css_free_conn (conn);
592  }
593  if (server_name != NULL)
594  {
595  free_and_init (server_name);
596  }
597 }
598 
599 /*
600  * Master server to Slave server communication support routines.
601  */
602 
603 /*
604  * css_send_new_request_to_server() - Attempts to transfer a clients request
605  * to the server
606  * return: true if success
607  * server_fd(in)
608  * client_fd(in)
609  * rid(in)
610  */
611 static bool
612 css_send_new_request_to_server (SOCKET server_fd, SOCKET client_fd, unsigned short rid, CSS_SERVER_REQUEST request)
613 {
614  return (css_transfer_fd (server_fd, client_fd, rid, request));
615 }
616 
617 /*
618  * css_send_to_existing_server() - Sends a new client request to
619  * an existing server
620  * return: none
621  * conn(in)
622  * rid(in)
623  *
624  * Note:
625  * There are two ways this can go. First we locate the requsted server on
626  * our connection list and then see if it was registered with an explicit
627  * port id. If not, we attempt to pass the open client fd to the server
628  * using the "old" style connection protocol.
629  *
630  * If the server has instead given us an explicit port id, we tell the
631  * client to use the new style protocol and establish their own connection
632  * to the server.
633  */
634 static void
635 css_send_to_existing_server (CSS_CONN_ENTRY * conn, unsigned short rid, CSS_SERVER_REQUEST request)
636 {
637  SOCKET_QUEUE_ENTRY *temp;
638  char *server_name = NULL;
639  int name_length, buffer;
640 
641  name_length = 1024;
642  if (css_receive_data (conn, rid, &server_name, &name_length, -1) == NO_ERRORS && server_name != NULL)
643  {
644  temp = css_return_entry_of_server (server_name, css_Master_socket_anchor);
645  if (temp != NULL
646 #if !defined(WINDOWS)
647  && (temp->ha_mode == false || hb_is_deactivation_started () == false)
648 #endif /* !WINDOWS */
649  )
650  {
651  if (temp->port_id == -1)
652  {
653  /* use old style connection */
654  if (IS_INVALID_SOCKET (temp->fd))
655  {
657  free_and_init (server_name);
658  css_free_conn (conn);
659  return;
660  }
661  else
662  {
663 #if !defined(WINDOWS)
664  if (hb_is_hang_process (temp->fd))
665  {
667  free_and_init (server_name);
668  css_free_conn (conn);
669  return;
670  }
671 #endif
672  if (css_send_new_request_to_server (temp->fd, conn->fd, rid, request))
673  {
674  free_and_init (server_name);
675  css_free_conn (conn);
676  return;
677  }
678  else if (!temp->ha_mode)
679  {
680  temp = css_return_entry_of_server (server_name, css_Master_socket_anchor);
681  if (temp != NULL)
682  {
683  css_remove_entry_by_conn (temp->conn_ptr, &css_Master_socket_anchor);
684  }
685  }
686  }
687  }
688  else
689  {
690  /* Use new style connection. We found a registered server, give the client a response telling it to
691  * re-connect using the server's port id. */
692 #if !defined(WINDOWS)
693  if (hb_is_hang_process (temp->fd))
694  {
696  free_and_init (server_name);
697  css_free_conn (conn);
698  return;
699  }
700 #endif
701  buffer = htonl (SERVER_CONNECTED_NEW);
702  css_send_data (conn, rid, (char *) &buffer, sizeof (int));
703  buffer = htonl (temp->port_id);
704  css_send_data (conn, rid, (char *) &buffer, sizeof (int));
705  }
706  }
708  }
709  css_free_conn (conn);
710  if (server_name != NULL)
711  {
712  free_and_init (server_name);
713  }
714 }
715 
716 /*
717  * css_process_new_connection()
718  * return: none
719  * fd(in)
720  *
721  * Note:
722  * Selects the appropriate handler based on the type of connection. We can
723  * support a client request (to connect to a server), a server request (to
724  * register itself) and an information client request (master control client).
725  */
726 static void
728 {
729  CSS_CONN_ENTRY *conn;
730  int function_code;
731  int buffer_size;
732  unsigned short rid;
733 
734  buffer_size = sizeof (NET_HEADER);
736  conn = css_make_conn (fd);
737  if (conn == NULL)
738  {
739  return;
740  }
741 
742  if (css_check_magic (conn) != NO_ERRORS)
743  {
744  css_free_conn (conn);
745  return;
746  }
747 
748  if (css_receive_request (conn, &rid, &function_code, &buffer_size) == NO_ERRORS)
749  {
750  switch (function_code)
751  {
752  case INFO_REQUEST: /* request for information */
753  css_add_request_to_socket_queue (conn, true, NULL, fd, READ_WRITE, 0, &css_Master_socket_anchor);
754  break;
755  case DATA_REQUEST: /* request from a remote client */
757  break;
758  case SERVER_REQUEST: /* request from a new server */
759  css_register_new_server (conn, rid);
760  break;
761  case SERVER_REQUEST_NEW: /* request from a new server */
762  /* here the server wants to manage its own connection port */
763  css_register_new_server2 (conn, rid);
764  break;
765  default:
766  css_free_conn (conn);
767  break;
768  }
769  }
770  else
771  {
772  css_free_conn (conn);
773  }
774 }
775 
776 /*
777  * css_enroll_read_sockets() - Sets the fd positions in fd_set for the
778  * input fds we are interested in reading
779  * return: none
780  *
781  * anchor_p(in)
782  * fd_var(out)
783  */
784 static int
785 css_enroll_read_sockets (SOCKET_QUEUE_ENTRY * anchor_p, fd_set * fd_var)
786 {
787  SOCKET_QUEUE_ENTRY *temp;
788  SOCKET max_fd = 0;
789 
790  FD_ZERO (fd_var);
791  for (temp = anchor_p; temp; temp = temp->next)
792  {
793  if (!IS_INVALID_SOCKET (temp->fd) && temp->fd_type != WRITE_ONLY)
794  {
795  FD_SET (temp->fd, fd_var);
796  if (temp->fd > max_fd)
797  {
798  max_fd = temp->fd;
799  }
800  }
801  }
802 
803  return (int) max_fd;
804 }
805 
806 /*
807  * css_enroll_master_read_sockets() -
808  * return: none
809  *
810  * fd_var(out)
811  */
812 static int
814 {
815  return css_enroll_read_sockets (css_Master_socket_anchor, fd_var);
816 }
817 
818 /*
819  * css_enroll_write_sockets() - Sets the fd positions in fd_set for the
820  * input fds we are interested in writing (none presently)
821  * return: none
822  *
823  * anchor_p(in)
824  * fd_var(out)
825  */
826 static int
827 css_enroll_write_sockets (SOCKET_QUEUE_ENTRY * anchor_p, fd_set * fd_var)
828 {
829  FD_ZERO (fd_var);
830  return 0;
831 }
832 
833 /*
834  * css_enroll_master_write_sockets() -
835  *
836  * return: none
837  * fd_var(out)
838  */
839 static int
841 {
842  return css_enroll_write_sockets (css_Master_socket_anchor, fd_var);
843 }
844 
845 /*
846  * css_enroll_exception_sockets() - Sets the fd positions in fd_set
847  * for the input fds we are interested in detecting error conditions
848  * return: last fd
849  *
850  * anchor_p(int)
851  * fd_var(out)
852  */
853 static int
855 {
856  SOCKET_QUEUE_ENTRY *temp;
857  SOCKET max_fd = 0;
858 
859  FD_ZERO (fd_var);
860  for (temp = anchor_p; temp; temp = temp->next)
861  {
862  if (!IS_INVALID_SOCKET (temp->fd))
863  {
864  FD_SET (temp->fd, fd_var);
865  if (temp->fd > max_fd)
866  {
867  max_fd = temp->fd;
868  }
869  }
870  }
871 
872  return (int) max_fd;
873 }
874 
875 /*
876  * css_enroll_master_exception_sockets()
877  * return: last fd
878  * fd_var(out)
879  */
880 static int
882 {
883  return css_enroll_exception_sockets (css_Master_socket_anchor, fd_var);
884 }
885 
886 /*
887  * css_master_select_error() - Check status of all known fds and remove those
888  * that are closed
889  * return: none
890  */
891 static void
893 {
894 #if !defined(WINDOWS)
895  int rv;
896  SOCKET_QUEUE_ENTRY *temp;
897 
898 again:
900  for (temp = css_Master_socket_anchor; temp; temp = temp->next)
901  {
902  if (!IS_INVALID_SOCKET (temp->fd) && fcntl (temp->fd, F_GETFL, 0) < 0)
903  {
904 #if defined(DEBUG)
905  if (css_Active_server_count > 0)
906  {
907  css_Active_server_count--;
908  }
909 #endif
910 #if !defined(WINDOWS)
911  if (temp->ha_mode)
912  {
914  }
915  else
916 #endif
917  {
918  css_remove_entry_by_conn (temp->conn_ptr, &css_Master_socket_anchor);
919  }
921  goto again;
922  }
923  }
925 #endif
926 }
927 
928 
929 /*
930  * css_check_master_socket_input() - checks if there is input from a client
931  * that must be processed
932  * return: none
933  * count(in/out)
934  * fd_var(in/out)
935  */
936 static void
937 css_check_master_socket_input (int *count, fd_set * fd_var)
938 {
939 #if !defined(WINDOWS)
940  int rv;
941 #endif
942  SOCKET_QUEUE_ENTRY *temp, *next;
943  SOCKET new_fd;
944 
945 #if !defined(WINDOWS)
947 #endif
948  for (temp = css_Master_socket_anchor; *count && temp; temp = next)
949  {
950  next = temp->next;
951  if (!IS_INVALID_SOCKET (temp->fd) && FD_ISSET (temp->fd, fd_var))
952  {
953  FD_CLR (temp->fd, fd_var);
954  (*count)--;
955  if (temp->fd == css_Master_socket_fd[0] || temp->fd == css_Master_socket_fd[1])
956  {
957  new_fd = css_master_accept (temp->fd);
958  if (!IS_INVALID_SOCKET (new_fd))
959  {
961  }
962  }
963  else if (!IS_INVALID_SOCKET (temp->fd))
964  {
965  if (temp->info_p)
966  {
967  css_process_info_request (temp->conn_ptr);
968  }
969  else
970  {
971  if (temp->ha_mode)
972  {
973  css_process_heartbeat_request (temp->conn_ptr);
974  }
975  else
976  {
977 #if defined(DEBUG)
978  if (css_Active_server_count > 0)
979  {
980  css_Active_server_count--;
981  }
982 #endif
983  css_remove_entry_by_conn (temp->conn_ptr, &css_Master_socket_anchor);
984  }
985  }
986  /* stop loop in case an error caused temp to be deleted */
987  break;
988  }
989  }
990  }
991 
992 #if !defined(WINDOWS)
994 #endif
995 }
996 
997 /*
998  * css_check_master_socket_output()
999  * return: none
1000  *
1001  * Note: currently no-op.
1002  */
1003 static void
1005 {
1006 }
1007 
1008 /*
1009  * css_check_master_socket_exception() - Checks for exception conditions for
1010  * open sockets
1011  * return: 0 if master will terminate, otherwise 1.
1012  * fd_var(in/out)
1013  */
1014 static int
1016 {
1017 #if !defined(WINDOWS)
1018  int rv;
1019 #endif
1020  SOCKET_QUEUE_ENTRY *temp;
1021 
1022 again:
1023 #if !defined(WINDOWS)
1025 #endif
1026  for (temp = css_Master_socket_anchor; temp; temp = temp->next)
1027  {
1028  if (!IS_INVALID_SOCKET (temp->fd) && ((FD_ISSET (temp->fd, fd_var) ||
1029 #if !defined(WINDOWS)
1030  (fcntl (temp->fd, F_GETFL, 0) < 0) ||
1031 #endif /* !WINDOWS */
1032  (temp->error_p != 0) || (temp->conn_ptr == NULL)
1033  || (temp->conn_ptr->status == CONN_CLOSED))))
1034  {
1035 #if defined(DEBUG)
1036  if (css_Active_server_count > 0)
1037  {
1038  css_Active_server_count--;
1039  }
1040 #endif
1041  FD_CLR (temp->fd, fd_var);
1042  if (temp->fd == css_Master_socket_fd[0] || temp->fd == css_Master_socket_fd[1])
1043  {
1044 #if !defined(WINDOWS)
1046 #endif
1047  return (0);
1048  }
1049 
1050 #if !defined(WINDOWS)
1051  if (temp->ha_mode)
1052  {
1054  }
1055  else
1056 #endif
1057  {
1058  css_remove_entry_by_conn (temp->conn_ptr, &css_Master_socket_anchor);
1059  }
1060 #if !defined(WINDOWS)
1062 #endif
1063  goto again;
1064  }
1065  }
1066 
1067 #if !defined(WINDOWS)
1069 #endif
1070  return (1);
1071 }
1072 
1073 /*
1074  * css_master_loop() - main loop for master
1075  * return: none
1076  */
1077 static void
1079 {
1080  fd_set read_fd, write_fd, exception_fd;
1081  static struct timeval timeout;
1082  int rc, run_code;
1083 
1084  run_code = 1;
1085  while (run_code)
1086  {
1087  int max_fd, max_fd1, max_fd2, max_fd3;
1088 
1089  max_fd1 = css_enroll_master_read_sockets (&read_fd);
1090  max_fd2 = css_enroll_master_write_sockets (&write_fd);
1091  max_fd3 = css_enroll_master_exception_sockets (&exception_fd);
1092 
1093  max_fd = MAX (MAX (max_fd1, max_fd2), max_fd3);
1094 
1095  timeout.tv_sec = css_Master_timeout_value_in_seconds;
1096  timeout.tv_usec = css_Master_timeout_value_in_microseconds;
1097 
1098  rc = select (max_fd + 1, &read_fd, &write_fd, &exception_fd, &timeout);
1099  switch (rc)
1100  {
1101  case 0:
1102  run_code = css_master_timeout ();
1103  break;
1104  case -1:
1105  /* switch error */
1107  break;
1108  default:
1109  css_check_master_socket_input (&rc, &read_fd);
1111  run_code = css_check_master_socket_exception (&exception_fd);
1112  break;
1113  }
1114  }
1115 }
1116 
1117 /*
1118  * main() - master main function
1119  * return: EXIT_SUCCESS/EXIT_FAILURE
1120  */
1121 int
1122 main (int argc, char **argv)
1123 {
1124  int port_id;
1125  CSS_CONN_ENTRY *conn;
1126  static const char suffix[] = "_master.err";
1127  char hostname[CUB_MAXHOSTNAMELEN + sizeof (suffix)];
1128  char *errlog = NULL;
1129  int status = EXIT_SUCCESS;
1130  const char *msg_format;
1131 
1132  if (utility_initialize () != NO_ERROR)
1133  {
1134  return EXIT_FAILURE;
1135  }
1136 
1137 #if defined(WINDOWS)
1138  FreeConsole ();
1139 
1140  if (css_windows_startup () < 0)
1141  {
1142  printf ("Unable to initialize Winsock.\n");
1143  status = EXIT_FAILURE;
1144  goto cleanup;
1145  }
1146 #endif /* WINDOWS */
1147 
1148  if (GETHOSTNAME (hostname, CUB_MAXHOSTNAMELEN) == 0)
1149  {
1150  /* css_gethostname won't null-terminate if the name is overlong. Put in a guaranteed null-terminator of our own
1151  * so that strcat doesn't go wild. */
1152  hostname[CUB_MAXHOSTNAMELEN] = '\0';
1153  strcat (hostname, suffix);
1154  errlog = hostname;
1155  }
1156 
1157  if (er_init (errlog, ER_NEVER_EXIT) != NO_ERROR)
1158  {
1159  PRINT_AND_LOG_ERR_MSG ("Failed to initialize error manager.\n");
1160  status = EXIT_FAILURE;
1161  goto cleanup;
1162  }
1163  if (master_util_config_startup ((argc > 1) ? argv[1] : NULL, &port_id) == false)
1164  {
1166  css_master_error (msg_format);
1167  util_log_write_errstr (msg_format);
1168  status = EXIT_FAILURE;
1169  goto cleanup;
1170  }
1171 
1172  if (css_does_master_exist (port_id))
1173  {
1175  util_log_write_errstr (msg_format, argv[0]);
1176  /* printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_DUPLICATE), argv[0]); */
1177  status = EXIT_FAILURE;
1178  goto cleanup;
1179  }
1180 
1182 
1183  /* close the message catalog and let the master daemon reopen. */
1184  (void) msgcat_final ();
1186 
1187 #if !defined(WINDOWS)
1188  if (envvar_get ("NO_DAEMON") == NULL)
1189  {
1190  css_daemon_start ();
1191  }
1192 #endif
1193 
1194  (void) utility_initialize ();
1195  (void) er_init (errlog, ER_NEVER_EXIT);
1196 
1197  time (&css_Start_time);
1198 
1199  if (css_master_init (port_id, css_Master_socket_fd) != NO_ERROR)
1200  {
1201  PRINT_AND_LOG_ERR_MSG ("%s: %s\n", argv[0], db_error_string (1));
1203  status = EXIT_FAILURE;
1204  goto cleanup;
1205  }
1206 
1207  if (envvar_get ("NO_DAEMON") != NULL)
1208  {
1209  (void) os_set_signal_handler (SIGINT, css_master_cleanup);
1210  }
1211 
1212 #if !defined(WINDOWS)
1213  if (!HA_DISABLED ())
1214  {
1215  if (hb_master_init () != NO_ERROR)
1216  {
1217  status = EXIT_FAILURE;
1218  goto cleanup;
1219  }
1220  }
1221 #endif
1222 
1223  conn = css_make_conn (css_Master_socket_fd[0]);
1225  &css_Master_socket_anchor);
1226  conn = css_make_conn (css_Master_socket_fd[1]);
1228  &css_Master_socket_anchor);
1229  css_master_loop ();
1230  css_master_cleanup (SIGINT);
1232 
1233 cleanup:
1234 #if defined(WINDOWS)
1235  /* make sure Winsock is properly closed */
1237 #endif /* WINDOWS */
1238  msgcat_final ();
1239 
1241 
1242  return status;
1243 }
1244 
1245 /*
1246  * These are the queuing routines for the Master socket queue (which is the
1247  * queue used by the Master Server) and the Open socket queue (which is the
1248  * queue used by the servers).
1249  */
1250 /*
1251  * css_free_entry() -
1252  * return: void
1253  * entry_p(in/out):
1254  */
1255 static void
1257 {
1258  if (entry_p->conn_ptr)
1259  {
1260  css_free_conn (entry_p->conn_ptr);
1261  }
1262 
1263  if (entry_p->name)
1264  {
1265  free_and_init (entry_p->name);
1266  }
1267  if (entry_p->version_string)
1268  {
1269  free_and_init (entry_p->version_string);
1270  }
1271  if (entry_p->env_var)
1272  {
1273  free_and_init (entry_p->env_var);
1274  }
1275 
1276  /* entry->fd has already been closed by css_free_conn */
1277  free_and_init (entry_p);
1278 }
1279 
1280 /*
1281  * css_remove_entry_by_conn() -
1282  * return: void
1283  * conn_p(in):
1284  * anchor_p(out):
1285  */
1286 void
1288 {
1289  SOCKET_QUEUE_ENTRY *p, *q;
1290 
1291  if (conn_p == NULL)
1292  {
1293  return;
1294  }
1295 
1296  for (p = *anchor_p, q = NULL; p; q = p, p = p->next)
1297  {
1298  if (p->conn_ptr != conn_p)
1299  {
1300  continue;
1301  }
1302 
1303  if (p == *anchor_p)
1304  {
1305  *anchor_p = p->next;
1306  }
1307  else
1308  {
1309  q->next = p->next;
1310  }
1311 
1312  css_free_entry (p);
1313  break;
1314  }
1315 }
1316 
1317 /*
1318  * css_add_request_to_socket_queue() -
1319  * return:
1320  * conn_p(in):
1321  * info_p(in):
1322  * name_p(in):
1323  * fd(in):
1324  * fd_type(in):
1325  * pid(in):
1326  * anchor_p(out):
1327  */
1329 css_add_request_to_socket_queue (CSS_CONN_ENTRY * conn_p, int info_p, char *name_p, SOCKET fd, int fd_type, int pid,
1330  SOCKET_QUEUE_ENTRY ** anchor_p)
1331 {
1333 
1334  p = (SOCKET_QUEUE_ENTRY *) malloc (sizeof (SOCKET_QUEUE_ENTRY));
1335  if (p == NULL)
1336  {
1337  return NULL;
1338  }
1339 
1340  p->conn_ptr = conn_p;
1341  p->fd = fd;
1342  p->ha_mode = FALSE;
1343 
1344  if (name_p)
1345  {
1346  p->name = (char *) malloc (strlen (name_p) + 1);
1347  if (p->name)
1348  {
1349  strcpy (p->name, name_p);
1350 #if !defined(WINDOWS)
1353  {
1354  p->ha_mode = TRUE;
1355  }
1356 #endif
1357  }
1358  }
1359  else
1360  {
1361  p->name = NULL;
1362  }
1363 
1364  p->version_string = NULL;
1365  p->env_var = NULL;
1366  p->fd_type = fd_type;
1367  p->queue_p = 0;
1368  p->info_p = info_p;
1369  p->error_p = FALSE;
1370  p->pid = pid;
1371  p->db_error = 0;
1372  p->next = *anchor_p;
1373  p->port_id = -1;
1374  *anchor_p = p;
1375 
1376  return p;
1377 }
1378 
1379 /*
1380  * css_return_entry_of_server() -
1381  * return:
1382  * name_p(in):
1383  * anchor_p(in):
1384  */
1387 {
1389 
1390  if (name_p == NULL)
1391  {
1392  return NULL;
1393  }
1394 
1395  for (p = anchor_p; p; p = p->next)
1396  {
1397  if (p->name && strcmp (p->name, name_p) == 0)
1398  {
1399  return p;
1400  }
1401 
1402 #if !defined(WINDOWS)
1403  /* if HA server exist */
1404  if (p->name && (IS_MASTER_CONN_NAME_HA_SERVER (p->name)))
1405  {
1406  if (strcmp ((char *) (p->name + 1), name_p) == 0)
1407  {
1408  return p;
1409  }
1410  }
1411 #endif
1412  }
1413 
1414  return NULL;
1415 }
1416 
1417 /*
1418  * css_return_entry_by_conn() -
1419  * return:
1420  * conn(in):
1421  * anchor_p(in):
1422  */
1425 {
1427 
1428  if (conn_p == NULL)
1429  {
1430  return NULL;
1431  }
1432 
1433  for (p = *anchor_p; p; p = p->next)
1434  {
1435  if (p->conn_ptr != conn_p)
1436  {
1437  continue;
1438  }
1439 
1440  return (p);
1441  }
1442 
1443  return NULL;
1444 }
1445 
1446 
1447 #if !defined(WINDOWS)
1448 /*
1449  * css_daemon_start() - detach a process from login session context
1450  * return: none
1451  */
1452 static void
1454 {
1455  int childpid, fd;
1456 #if defined (sun)
1457  struct rlimit rlp;
1458 #endif /* sun */
1459  int fd_max;
1460  int ppid = getpid ();
1461 
1462 
1463  /* If we were started by init (process 1) from the /etc/inittab file there's no need to detatch. This test is
1464  * unreliable due to an unavoidable ambiguity if the process is started by some other process and orphaned (i.e., if
1465  * the parent process terminates before we get here). */
1466 
1467  if (getppid () == 1)
1468  {
1469  goto out;
1470  }
1471 
1472  /*
1473  * Ignore the terminal stop signals (BSD).
1474  */
1475 
1476 #ifdef SIGTTOU
1477  if (os_set_signal_handler (SIGTTOU, SIG_IGN) == SIG_ERR)
1478  {
1479  exit (0);
1480  }
1481 #endif
1482 #ifdef SIGTTIN
1483  if (os_set_signal_handler (SIGTTIN, SIG_IGN) == SIG_ERR)
1484  {
1485  exit (0);
1486  }
1487 #endif
1488 #ifdef SIGTSTP
1489  if (os_set_signal_handler (SIGTSTP, SIG_IGN) == SIG_ERR)
1490  {
1491  exit (0);
1492  }
1493 #endif
1494 
1495  /*
1496  * Call fork and have the parent exit.
1497  * This does several things. First, if we were started as a simple shell
1498  * command, having the parent terminate makes the shell think that the
1499  * command is done. Second, the child process inherits the process group ID
1500  * of the parent but gets a new process ID, so we are guaranteed that the
1501  * child is not a process group leader, which is a prerequirement for the
1502  * call to setsid
1503  */
1504 
1505  childpid = fork ();
1506  if (childpid < 0)
1507  {
1509  }
1510  else if (childpid > 0)
1511  {
1512  exit (0); /* parent goes bye-bye */
1513  }
1514  else
1515  {
1516  /*
1517  * Wait until the parent process has finished. Coded with polling since
1518  * the parent should finish immediately. SO, it is unlikely that we are
1519  * going to loop at all.
1520  */
1521  while (getppid () == ppid)
1522  {
1523  sleep (1);
1524  }
1525  }
1526 
1527  /*
1528  * Create a new session and make the child process the session leader of
1529  * the new session, the process group leader of the new process group.
1530  * The child process has no controlling terminal.
1531  */
1532 
1533  if (os_set_signal_handler (SIGHUP, SIG_IGN) == SIG_ERR)
1534  {
1535  exit (0); /* fail to immune from pgrp leader death */
1536  }
1537 
1538  setsid ();
1539 
1540 out:
1541 
1542  /*
1543  * Close unneeded file descriptors which prevent the daemon from holding
1544  * open any descriptors that it may have inherited from its parent which
1545  * could be a shell. For now, leave in/out/err open
1546  */
1547 
1548  fd_max = css_get_max_socket_fds ();
1549 
1550  for (fd = 3; fd < fd_max; fd++)
1551  {
1552  close (fd);
1553  }
1554 
1555  errno = 0; /* Reset errno from last close */
1556 
1557  /*
1558  * The file mode creation mask that is inherited could be set to deny
1559  * certain permissions. Therefore, clear the file mode creation mask.
1560  */
1561 
1562  umask (0);
1563 }
1564 #endif
int status
static void css_accept_new_request(CSS_CONN_ENTRY *conn, unsigned short rid, char *server_name, int server_name_length)
Definition: master.c:326
int hb_master_init(void)
#define NO_ERROR
Definition: error_code.h:46
#define TRUE
Definition: broker_admin.c:49
char * name
Definition: master_util.h:84
pthread_mutex_t css_Master_er_log_lock
Definition: master.c:129
#define IS_MASTER_CONN_NAME_HA_APPLYLOG(name)
Definition: master_util.h:104
int SOCKET
Definition: porting.h:482
int css_Total_request_count
Definition: master.c:119
#define PRINT_AND_LOG_ERR_MSG(...)
Definition: util_func.h:49
#define pthread_mutex_init(a, b)
Definition: area_alloc.c:48
static bool css_send_new_request_to_server(SOCKET server_fd, SOCKET client_fd, unsigned short rid, CSS_SERVER_REQUEST request)
Definition: master.c:612
int argc
Definition: dynamic_load.c:951
static void css_free_entry(SOCKET_QUEUE_ENTRY *entry_p)
Definition: master.c:1256
static int css_master_init(int cport, SOCKET *clientfd)
Definition: master.c:241
unsigned int htonl(unsigned int from)
#define IS_MASTER_CONN_NAME_HA_SERVER(name)
Definition: master_util.h:102
void css_free_conn(CSS_CONN_ENTRY *conn)
CSS_CONN_ENTRY * conn_ptr
Definition: master_util.h:87
#define pthread_mutex_unlock(a)
Definition: area_alloc.c:51
static void css_send_to_existing_server(CSS_CONN_ENTRY *conn, unsigned short rid, CSS_SERVER_REQUEST request)
Definition: master.c:635
void css_remove_entry_by_conn(CSS_CONN_ENTRY *conn_p, SOCKET_QUEUE_ENTRY **anchor_p)
Definition: master.c:1287
static void css_reject_client_request(CSS_CONN_ENTRY *conn, unsigned short rid, int reason)
Definition: master.c:278
SOCKET fd
pthread_mutex_t css_Master_socket_anchor_lock
Definition: master.c:127
static int css_enroll_exception_sockets(SOCKET_QUEUE_ENTRY *anchor_p, fd_set *fd_var)
Definition: master.c:854
int main(int argc, char **argv)
Definition: master.c:1122
int error_p
Definition: master_util.h:82
int css_Master_timeout_value_in_seconds
Definition: master.c:112
int css_get_max_socket_fds(void)
Definition: tcp.c:1315
static void css_process_new_connection(SOCKET fd)
Definition: master.c:727
#define INVALID_SOCKET
Definition: porting.h:483
bool css_does_master_exist(int port_id)
bool css_transfer_fd(SOCKET server_fd, SOCKET client_fd, unsigned short rid, CSS_SERVER_REQUEST request_for_server)
Definition: tcp.c:1122
int er_init(const char *msglog_filename, int exit_ask)
int css_receive_request(CSS_CONN_ENTRY *conn, unsigned short *rid, int *request, int *buffer_size)
int db_error
Definition: master_util.h:79
static int css_enroll_master_read_sockets(fd_set *fd_var)
Definition: master.c:813
static void css_check_master_socket_input(int *count, fd_set *fd_var)
Definition: master.c:937
void er_final(ER_FINAL_CODE do_global_final)
static int css_enroll_read_sockets(SOCKET_QUEUE_ENTRY *anchor_p, fd_set *fd_var)
Definition: master.c:785
void css_process_heartbeat_request(CSS_CONN_ENTRY *conn)
#define ER_GENERIC_ERROR
Definition: error_code.h:49
static int css_check_master_socket_exception(fd_set *fd_var)
Definition: master.c:1015
void css_master_cleanup(int sig)
Definition: master.c:218
SOCKET fd
Definition: master_util.h:77
int ha_mode
Definition: master_util.h:89
#define ERR_CSS_CANNOT_FORK
Definition: error_code.h:417
#define IS_INVALID_SOCKET(socket)
Definition: porting.h:484
const char * db_error_string(int level)
Definition: db_admin.c:2116
int info_p
Definition: master_util.h:81
static void css_register_new_server(CSS_CONN_ENTRY *conn, unsigned short rid)
Definition: master.c:441
void css_shutdown_socket(SOCKET fd)
Definition: tcp.c:1179
static int rv
Definition: area_alloc.c:52
static void cleanup(int signo)
Definition: broker.c:717
int utility_initialize()
Definition: util_common.c:69
#define NULL
Definition: freelistheap.h:34
bool master_util_config_startup(const char *db_name, int *port_id)
Definition: master_util.c:42
pid_t pid
Definition: dynamic_load.c:955
bool hb_is_hang_process(int sfd)
char * env_var
Definition: master_util.h:86
static void css_accept_old_request(CSS_CONN_ENTRY *conn, unsigned short rid, SOCKET_QUEUE_ENTRY *entry, char *server_name, int server_name_length)
Definition: master.c:395
#define TPRINTF(error_string, arg)
char * version_string
Definition: master_util.h:85
struct packet_header NET_HEADER
Definition: master_util.h:75
int pid
Definition: master_util.h:83
int count(int &result, const cub_regex_object &reg, const std::string &src, const int position, const INTL_CODESET codeset)
SOCKET css_Master_socket_fd[2]
Definition: master.c:122
int css_Master_timeout_value_in_microseconds
Definition: master.c:113
bool css_tcp_master_datagram(char *path_name, SOCKET *sockfd)
Definition: tcp.c:967
const char * envvar_get(const char *name)
#define MASTER_ER_SET(...)
Definition: master_util.h:47
static int rc
Definition: serial.c:50
int css_receive_data(CSS_CONN_ENTRY *conn, unsigned short req_id, char **buffer, int *buffer_size, int timeout)
SOCKET_QUEUE_ENTRY * css_add_request_to_socket_queue(CSS_CONN_ENTRY *conn_p, int info_p, char *name_p, SOCKET fd, int fd_type, int pid, SOCKET_QUEUE_ENTRY **anchor_p)
Definition: master.c:1329
#define ARG_FILE_LINE
Definition: error_manager.h:44
static void css_daemon_start(void)
Definition: master.c:1453
static void css_check_master_socket_output(void)
Definition: master.c:1004
int css_windows_startup(void)
Definition: wintcp.c:94
char * css_get_master_domain_path(void)
Definition: tcp.c:155
#define ER_HB_STOPPED
Definition: error_code.h:1237
const char ** argv
Definition: dynamic_load.c:952
int msgcat_final(void)
#define free_and_init(ptr)
Definition: memory_alloc.h:147
#define strlen(s1)
Definition: intl_support.c:43
struct timeval * css_Master_timeout
Definition: master.c:111
static int css_master_timeout(void)
Definition: master.c:163
int css_tcp_master_open(int port, SOCKET *sockfd)
Definition: tcp.c:663
int queue_p
Definition: master_util.h:80
void css_windows_shutdown(void)
Definition: wintcp.c:140
static void css_master_loop(void)
Definition: master.c:1078
static void css_accept_server_request(CSS_CONN_ENTRY *conn, int reason)
Definition: master.c:309
#define FALSE
Definition: broker_admin.c:50
int util_log_write_errstr(const char *format,...)
Definition: util_func.c:493
static void css_master_error(const char *error_string)
Definition: master.c:141
int css_net_recv(SOCKET fd, char *buffer, int *maxlen, int timeout)
static void css_register_new_server2(CSS_CONN_ENTRY *conn, unsigned short rid)
Definition: master.c:502
SOCKET_QUEUE_ENTRY * css_return_entry_by_conn(CSS_CONN_ENTRY *conn_p, SOCKET_QUEUE_ENTRY **anchor_p)
Definition: master.c:1424
char * msgcat_message(int cat_id, int set_id, int msg_id)
static int css_enroll_master_write_sockets(fd_set *fd_var)
Definition: master.c:840
int fd_type
Definition: master_util.h:78
#define HA_DISABLED()
enum css_server_request CSS_SERVER_REQUEST
#define pthread_mutex_lock(a)
Definition: area_alloc.c:50
struct socket_queue_entry * next
Definition: master_util.h:90
void css_process_info_request(CSS_CONN_ENTRY *conn)
static int css_enroll_master_exception_sockets(fd_set *fd_var)
Definition: master.c:881
unsigned int ntohl(unsigned int from)
int css_send_data(CSS_CONN_ENTRY *conn, unsigned short rid, const char *buffer, int buffer_size)
static void css_reject_server_request(CSS_CONN_ENTRY *conn, int reason)
Definition: master.c:293
static int css_enroll_write_sockets(SOCKET_QUEUE_ENTRY *anchor_p, fd_set *fd_var)
Definition: master.c:827
SOCKET_QUEUE_ENTRY * css_return_entry_of_server(char *name_p, SOCKET_QUEUE_ENTRY *anchor_p)
Definition: master.c:1386
int css_check_magic(CSS_CONN_ENTRY *conn)
pthread_mutex_t css_Master_er_log_enable_lock
Definition: master.c:130
bool css_Master_er_log_enabled
Definition: master.c:131
#define CUB_MAXHOSTNAMELEN
Definition: porting.h:379
static void css_master_select_error(void)
Definition: master.c:892
int port_id
Definition: master_util.h:88
bool hb_is_deactivation_started(void)
#define IS_MASTER_CONN_NAME_HA_COPYLOG(name)
Definition: master_util.h:103
SIGNAL_HANDLER_FUNCTION os_set_signal_handler(const int sig_no, SIGNAL_HANDLER_FUNCTION sig_handler)
Definition: porting.c:1333
SOCKET css_master_accept(SOCKET sockfd)
Definition: tcp.c:836
#define GETHOSTNAME(p, l)
Definition: porting.h:381
const char ** p
Definition: dynamic_load.c:945
SOCKET_QUEUE_ENTRY * css_Master_socket_anchor
Definition: master.c:125
time_t css_Start_time
Definition: master.c:118
void hb_cleanup_conn_and_start_process(CSS_CONN_ENTRY *conn, SOCKET sfd)
CSS_CONN_ENTRY * css_make_conn(SOCKET fd)
#define MSGCAT_CATALOG_UTILS