1 /* -*-pgsql-c-*- */
2 /*
3  * $Header$
4  *
5  * pgpool: a language independent connection pool server for PostgreSQL
6  * written by Tatsuo Ishii
7  *
8  * Copyright (c) 2003-2020	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 #include "pool.h"
22 #include "pool_config.h"
23 #include "version.h"
24 #include "pool_config_variables.h"
25 
26 #include <fcntl.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <unistd.h>
30 
31 
32 #ifdef HAVE_GETOPT_H
33 #include <getopt.h>
34 #else
35 #include "utils/getopt_long.h"
36 #endif
37 
38 #include <errno.h>
39 #include <string.h>
40 #include <libgen.h>
41 
42 #include "utils/elog.h"
43 #include "utils/palloc.h"
44 #include "utils/memutils.h"
45 #include "utils/pool_path.h"
46 #include "utils/pool_signal.h"
47 #include "utils/pool_ipc.h"
48 #include "utils/ps_status.h"
49 #include "utils/pool_ssl.h"
50 
51 #include "auth/pool_passwd.h"
52 #include "auth/pool_hba.h"
53 #include "query_cache/pool_memqcache.h"
54 #include "watchdog/wd_utils.h"
55 
56 
57 static bool get_pool_key_filename(char *poolKeyFile);
58 
59 static void daemonize(void);
60 static char *get_pid_file_path(void);
61 static int	read_pid_file(void);
62 static void write_pid_file(void);
63 static void usage(void);
64 static void show_version(void);
65 static void stop_me(void);
66 static void FileUnlink(int code, Datum path);
67 
68 char	   *pcp_conf_file = NULL;	/* absolute path of the pcp.conf */
69 char	   *conf_file = NULL;	/* absolute path of the pgpool.conf */
70 char	   *hba_file = NULL;	/* absolute path of the hba.conf */
71 char	   *base_dir = NULL;	/* The working dir from where pgpool was
72 								 * invoked from */
73 
74 static int	not_detach = 0;		/* non 0 if non detach option (-n) is given */
75 int			stop_sig = SIGTERM; /* stopping signal default value */
76 int			myargc;
77 char	  **myargv;
78 int			assert_enabled = 0;
79 char	   *pool_key = NULL;
80 int
main(int argc,char ** argv)81 main(int argc, char **argv)
82 {
83 	int			opt;
84 	int			debug_level = 0;
85 	int			optindex;
86 	bool		discard_status = false;
87 	bool		clear_memcache_oidmaps = false;
88 
89 	char		pcp_conf_file_path[POOLMAXPATHLEN + 1];
90 	char		conf_file_path[POOLMAXPATHLEN + 1];
91 	char		hba_file_path[POOLMAXPATHLEN + 1];
92 	char		pool_passwd_key_file_path[POOLMAXPATHLEN + 1 + sizeof(POOLKEYFILE) + 1];
93 
94 	static struct option long_options[] = {
95 		{"hba-file", required_argument, NULL, 'a'},
96 		{"debug", no_argument, NULL, 'd'},
97 		{"config-file", required_argument, NULL, 'f'},
98 		{"key-file", required_argument, NULL, 'k'},
99 		{"pcp-file", required_argument, NULL, 'F'},
100 		{"help", no_argument, NULL, 'h'},
101 		{"mode", required_argument, NULL, 'm'},
102 		{"dont-detach", no_argument, NULL, 'n'},
103 		{"discard-status", no_argument, NULL, 'D'},
104 		{"clear-oidmaps", no_argument, NULL, 'C'},
105 		{"debug-assertions", no_argument, NULL, 'x'},
106 		{"version", no_argument, NULL, 'v'},
107 		{NULL, 0, NULL, 0}
108 	};
109 
110 	myargc = argc;
111 	myargv = argv;
112 
113 	snprintf(conf_file_path, sizeof(conf_file_path), "%s/%s", DEFAULT_CONFIGDIR, POOL_CONF_FILE_NAME);
114 	snprintf(pcp_conf_file_path, sizeof(pcp_conf_file_path), "%s/%s", DEFAULT_CONFIGDIR, PCP_PASSWD_FILE_NAME);
115 	snprintf(hba_file_path, sizeof(hba_file_path), "%s/%s", DEFAULT_CONFIGDIR, HBA_CONF_FILE_NAME);
116 	pool_passwd_key_file_path[0] = 0;
117 
118 	while ((opt = getopt_long(argc, argv, "a:df:k:F:hm:nDCxv", long_options, &optindex)) != -1)
119 	{
120 		switch (opt)
121 		{
122 			case 'a':			/* specify hba configuration file */
123 				if (!optarg)
124 				{
125 					usage();
126 					exit(1);
127 				}
128 				strlcpy(hba_file_path, optarg, sizeof(hba_file_path));
129 				break;
130 
131 			case 'x':			/* enable cassert */
132 				assert_enabled = 1;
133 				break;
134 
135 			case 'd':			/* debug option */
136 				debug_level = 1;
137 				break;
138 
139 			case 'f':			/* specify configuration file */
140 				if (!optarg)
141 				{
142 					usage();
143 					exit(1);
144 				}
145 				strlcpy(conf_file_path, optarg, sizeof(conf_file_path));
146 				break;
147 
148 			case 'F':			/* specify PCP password file */
149 				if (!optarg)
150 				{
151 					usage();
152 					exit(1);
153 				}
154 				strlcpy(pcp_conf_file_path, optarg, sizeof(pcp_conf_file_path));
155 				break;
156 
157 			case 'k':			/* specify key file for decrypt pool_password
158 								 * entries */
159 				if (!optarg)
160 				{
161 					usage();
162 					exit(1);
163 				}
164 				strlcpy(pool_passwd_key_file_path, optarg, sizeof(pool_passwd_key_file_path));
165 				break;
166 
167 			case 'h':
168 				usage();
169 				exit(0);
170 				break;
171 
172 			case 'm':			/* stop mode */
173 				if (!optarg)
174 				{
175 					usage();
176 					exit(1);
177 				}
178 				if (*optarg == 's' || !strcmp("smart", optarg))
179 					stop_sig = SIGTERM; /* smart shutdown */
180 				else if (*optarg == 'f' || !strcmp("fast", optarg))
181 					stop_sig = SIGINT;	/* fast shutdown */
182 				else if (*optarg == 'i' || !strcmp("immediate", optarg))
183 					stop_sig = SIGQUIT; /* immediate shutdown */
184 				else
185 				{
186 					usage();
187 					exit(1);
188 				}
189 				break;
190 
191 			case 'n':			/* no detaching control ttys */
192 				not_detach = 1;
193 				break;
194 
195 			case 'D':			/* discard pgpool_status */
196 				discard_status = true;
197 				break;
198 
199 			case 'C':			/* discard caches in memcached */
200 				clear_memcache_oidmaps = true;
201 				break;
202 
203 			case 'v':
204 				show_version();
205 				exit(0);
206 
207 			default:
208 				usage();
209 				exit(1);
210 		}
211 	}
212 
213 	myargv = save_ps_display_args(myargc, myargv);
214 	/* create MemoryContexts */
215 	MemoryContextInit();
216 
217 	/* load the CWD before it is changed */
218 	base_dir = get_current_working_dir();
219 	/* convert all the paths to absolute paths */
220 	conf_file = make_absolute_path(conf_file_path, base_dir);
221 	pcp_conf_file = make_absolute_path(pcp_conf_file_path, base_dir);
222 	hba_file = make_absolute_path(hba_file_path, base_dir);
223 
224 	mypid = getpid();
225 	SetProcessGlobalVaraibles(PT_MAIN);
226 
227 
228 	pool_init_config();
229 
230 	pool_get_config(conf_file, CFGCXT_INIT);
231 
232 	/*
233 	 * Override debug level if command line -d arg is given adjust the
234 	 * log_min_message config variable
235 	 */
236 	if (debug_level > 0 && pool_config->log_min_messages > DEBUG1)
237 		set_one_config_option("log_min_messages", "DEBUG1", CFGCXT_INIT, PGC_S_ARGV, INFO);
238 
239 	/*
240 	 * If a non-switch argument remains, then it should be either "reload" or
241 	 * "stop".
242 	 */
243 	if (optind == (argc - 1))
244 	{
245 		if (!strcmp(argv[optind], "reload"))
246 		{
247 			pid_t		pid;
248 
249 			pid = read_pid_file();
250 			if (pid < 0)
251 			{
252 				ereport(FATAL,
253 						(return_code(1),
254 						 errmsg("could not read pid file")));
255 			}
256 
257 			if (kill(pid, SIGHUP) == -1)
258 			{
259 				ereport(FATAL,
260 						(return_code(1),
261 						 errmsg("could not reload configuration file pid: %d", pid),
262 						 errdetail("%m")));
263 			}
264 			exit(0);
265 		}
266 		if (!strcmp(argv[optind], "stop"))
267 		{
268 			stop_me();
269 			exit(0);
270 		}
271 		else
272 		{
273 			usage();
274 			exit(1);
275 		}
276 	}
277 
278 	/*
279 	 * else if no non-switch argument remains, then it should be a start
280 	 * request
281 	 */
282 	else if (optind == argc)
283 	{
284 		int			pid = read_pid_file();
285 
286 		if (pid > 0)
287 		{
288 			if (kill(pid, 0) == 0)
289 			{
290 				fprintf(stderr, "ERROR: pid file found. is another pgpool(%d) is running?\n", pid);
291 				exit(EXIT_FAILURE);
292 			}
293 			else
294 				fprintf(stderr, "NOTICE: pid file found but it seems bogus. Trying to start pgpool anyway...\n");
295 		}
296 	}
297 
298 	/*
299 	 * otherwise an error...
300 	 */
301 	else
302 	{
303 		usage();
304 		exit(1);
305 	}
306 
307 	if (pool_config->enable_pool_hba)
308 		load_hba(hba_file);
309 
310 #ifdef USE_SSL
311 
312 	/*
313 	 * If ssl is enabled, initialize the SSL context
314 	 */
315 	if (pool_config->ssl)
316 		SSL_ServerSide_init();
317 #endif							/* USE_SSL */
318 
319 	/* check effective user id for watchdog */
320 	/* watchdog must be started under the privileged user */
321 	wd_check_network_command_configurations();
322 
323 	/* set signal masks */
324 	poolinitmask();
325 
326 	/* read the pool password key */
327 	if (strlen(pool_passwd_key_file_path) == 0)
328 	{
329 		get_pool_key_filename(pool_passwd_key_file_path);
330 	}
331 	pool_key = read_pool_key(pool_passwd_key_file_path);
332 
333 	if (not_detach)
334 		write_pid_file();
335 	else
336 		daemonize();
337 
338 	/*
339 	 * Locate pool_passwd The default file name "pool_passwd" can be changed
340 	 * by setting pgpool.conf's "pool_passwd" directive.
341 	 */
342 	if (strcmp("", pool_config->pool_passwd))
343 	{
344 		char		pool_passwd[POOLMAXPATHLEN + 1];
345 		char		dirnamebuf[POOLMAXPATHLEN + 1];
346 		char	   *dirp;
347 
348 		if (pool_config->pool_passwd[0] != '/')
349 		{
350 			strlcpy(dirnamebuf, conf_file, sizeof(dirnamebuf));
351 			dirp = dirname(dirnamebuf);
352 			snprintf(pool_passwd, sizeof(pool_passwd), "%s/%s",
353 					 dirp, pool_config->pool_passwd);
354 		}
355 		else
356 			strlcpy(pool_passwd, pool_config->pool_passwd,
357 				 sizeof(pool_passwd));
358 
359 		pool_init_pool_passwd(pool_passwd, POOL_PASSWD_R);
360 	}
361 
362 	pool_semaphore_create(MAX_NUM_SEMAPHORES);
363 
364 	PgpoolMain(discard_status, clear_memcache_oidmaps); /* this is an infinate
365 														 * loop */
366 
367 	exit(0);
368 
369 }
370 
371 static void
show_version(void)372 show_version(void)
373 {
374 	fprintf(stderr, "%s version %s (%s)\n", PACKAGE, VERSION, PGPOOLVERSION);
375 }
376 
377 static void
usage(void)378 usage(void)
379 {
380 	char		homedir[POOLMAXPATHLEN];
381 
382 	if (!get_home_directory(homedir, sizeof(homedir)))
383 		strncpy(homedir, "USER-HOME-DIR", POOLMAXPATHLEN);
384 
385 	fprintf(stderr, "%s version %s (%s),\n", PACKAGE, VERSION, PGPOOLVERSION);
386 	fprintf(stderr, "  A generic connection pool/replication/load balance server for PostgreSQL\n\n");
387 	fprintf(stderr, "Usage:\n");
388 	fprintf(stderr, "  pgpool [ -c] [ -f CONFIG_FILE ] [ -F PCP_CONFIG_FILE ] [ -a HBA_CONFIG_FILE ]\n");
389 	fprintf(stderr, "         [ -n ] [ -D ] [ -d ]\n");
390 	fprintf(stderr, "  pgpool [ -f CONFIG_FILE ] [ -F PCP_CONFIG_FILE ] [ -a HBA_CONFIG_FILE ]\n");
391 	fprintf(stderr, "         [ -m SHUTDOWN-MODE ] stop\n");
392 	fprintf(stderr, "  pgpool [ -f CONFIG_FILE ] [ -F PCP_CONFIG_FILE ] [ -a HBA_CONFIG_FILE ] reload\n\n");
393 	fprintf(stderr, "Common options:\n");
394 	fprintf(stderr, "  -a, --hba-file=HBA_CONFIG_FILE\n");
395 	fprintf(stderr, "                      Set the path to the pool_hba.conf configuration file\n");
396 	fprintf(stderr, "                      (default: %s/%s)\n", DEFAULT_CONFIGDIR, HBA_CONF_FILE_NAME);
397 	fprintf(stderr, "  -f, --config-file=CONFIG_FILE\n");
398 	fprintf(stderr, "                      Set the path to the pgpool.conf configuration file\n");
399 	fprintf(stderr, "                      (default: %s/%s)\n", DEFAULT_CONFIGDIR, POOL_CONF_FILE_NAME);
400 	fprintf(stderr, "  -k, --key-file=KEY_FILE\n");
401 	fprintf(stderr, "                      Set the path to the pgpool key file\n");
402 	fprintf(stderr, "                      (default: %s/%s)\n", homedir, POOLKEYFILE);
403 	fprintf(stderr, "                      can be over ridden by %s environment variable\n", POOLKEYFILEENV);
404 	fprintf(stderr, "  -F, --pcp-file=PCP_CONFIG_FILE\n");
405 	fprintf(stderr, "                      Set the path to the pcp.conf configuration file\n");
406 	fprintf(stderr, "                      (default: %s/%s)\n", DEFAULT_CONFIGDIR, PCP_PASSWD_FILE_NAME);
407 	fprintf(stderr, "  -h, --help          Print this help\n\n");
408 	fprintf(stderr, "Start options:\n");
409 	fprintf(stderr, "  -C, --clear-oidmaps Clear query cache oidmaps when memqcache_method is memcached\n");
410 	fprintf(stderr, "                      (If shmem, discards whenever pgpool starts.)\n");
411 	fprintf(stderr, "  -n, --dont-detach   Don't run in daemon mode, does not detach control tty\n");
412 	fprintf(stderr, "  -x, --debug-assertions   Turns on various assertion checks, This is a debugging aid\n");
413 	fprintf(stderr, "  -D, --discard-status Discard pgpool_status file and do not restore previous status\n");
414 	fprintf(stderr, "  -d, --debug         Debug mode\n\n");
415 	fprintf(stderr, "Stop options:\n");
416 	fprintf(stderr, "  -m, --mode=SHUTDOWN-MODE\n");
417 	fprintf(stderr, "                      Can be \"smart\", \"fast\", or \"immediate\"\n\n");
418 	fprintf(stderr, "Shutdown modes are:\n");
419 	fprintf(stderr, "  smart       quit after all clients have disconnected\n");
420 	fprintf(stderr, "  fast        quit directly, with proper shutdown\n");
421 	fprintf(stderr, "  immediate   the same mode as fast\n");
422 }
423 
424 static bool
get_pool_key_filename(char * poolKeyFile)425 get_pool_key_filename(char *poolKeyFile)
426 {
427 	char	   *passfile_env;
428 
429 	if ((passfile_env = getenv(POOLKEYFILEENV)) != NULL)
430 	{
431 		/* use the literal path from the environment, if set */
432 		strlcpy(poolKeyFile, passfile_env, POOLMAXPATHLEN);
433 	}
434 	else
435 	{
436 		char		homedir[POOLMAXPATHLEN];
437 
438 		if (!get_home_directory(homedir, sizeof(homedir)))
439 			return false;
440 		snprintf(poolKeyFile, POOLMAXPATHLEN + sizeof(POOLKEYFILE) + 1, "%s/%s", homedir, POOLKEYFILE);
441 	}
442 	return true;
443 }
444 
445 
446 char *
get_pool_key(void)447 get_pool_key(void)
448 {
449 	return pool_key;
450 }
451 
452 /*
453 * detach control ttys
454 */
455 static void
daemonize(void)456 daemonize(void)
457 {
458 	int			i;
459 	pid_t		pid;
460 	int			fdlimit;
461 
462 	pid = fork();
463 	if (pid == (pid_t) -1)
464 	{
465 		ereport(FATAL,
466 				(errmsg("could not daemonize the pgpool-II"),
467 				 errdetail("fork() system call failed with reason: \"%m\"")));
468 	}
469 	else if (pid > 0)
470 	{							/* parent */
471 		exit(0);
472 	}
473 
474 #ifdef HAVE_SETSID
475 	if (setsid() < 0)
476 	{
477 		ereport(FATAL,
478 				(errmsg("could not daemonize the pgpool-II"),
479 				 errdetail("setsid() system call failed with reason: \"%m\"")));
480 	}
481 #endif
482 
483 	mypid = getpid();
484 	SetProcessGlobalVaraibles(PT_MAIN);
485 	write_pid_file();
486 	if (chdir("/"))
487 		ereport(WARNING,
488 				(errmsg("change directory failed"),
489 				 errdetail("chdir() system call failed with reason: \"%m\"")));
490 
491 	/* redirect stdin, stdout and stderr to /dev/null */
492 	i = open("/dev/null", O_RDWR);
493 	if (i < 0)
494 	{
495 		ereport(WARNING,
496 				(errmsg("failed to open \"/dev/null\""),
497 				 errdetail("%m")));
498 	}
499 	else
500 	{
501 		dup2(i, 0);
502 		dup2(i, 1);
503 		dup2(i, 2);
504 		close(i);
505 	}
506 	/* close syslog connection for daemonizing */
507 	if (pool_config->log_destination & LOG_DESTINATION_SYSLOG)
508 	{
509 		closelog();
510 	}
511 
512 	/* close other file descriptors */
513 	fdlimit = sysconf(_SC_OPEN_MAX);
514 	for (i = 3; i < fdlimit; i++)
515 		close(i);
516 }
517 
518 /*
519 * stop myself
520 */
521 static void
stop_me(void)522 stop_me(void)
523 {
524 	pid_t		pid;
525 	char	   *pid_file;
526 
527 	pid = read_pid_file();
528 	if (pid < 0)
529 	{
530 		ereport(FATAL,
531 				(errmsg("could not read pid file")));
532 	}
533 
534 	if (kill(pid, stop_sig) == -1)
535 	{
536 		ereport(FATAL,
537 				(errmsg("could not stop process with pid: %d", pid),
538 				 errdetail("%m")));
539 	}
540 	ereport(LOG,
541 			(errmsg("stop request sent to pgpool. waiting for termination...")));
542 
543 	while (kill(pid, 0) == 0)
544 	{
545 		fprintf(stderr, ".");
546 		sleep(1);
547 	}
548 	fprintf(stderr, "done.\n");
549 	pid_file = get_pid_file_path();
550 	unlink(pid_file);
551 	pfree(pid_file);
552 }
553 
554 /*
555  * The function returns the palloc'd copy of pid_file_path,
556  * caller must free it after use
557  */
558 static char *
get_pid_file_path(void)559 get_pid_file_path(void)
560 {
561 	char	   *new = NULL;
562 
563 	if (!is_absolute_path(pool_config->pid_file_name))
564 	{
565 		/*
566 		 * some implementations of dirname() may modify the string argument
567 		 * passed to it, so do not use the original conf_file as an argument
568 		 */
569 		char	   *conf_file_copy = pstrdup(conf_file);
570 		char	   *conf_dir = dirname(conf_file_copy);
571 		size_t		path_size;
572 
573 		if (conf_dir == NULL)
574 		{
575 			ereport(LOG,
576 					(errmsg("failed to get the dirname of pid file:\"%s\"",
577 							pool_config->pid_file_name),
578 					 errdetail("%m")));
579 			return NULL;
580 		}
581 		path_size = strlen(conf_dir) + strlen(pool_config->pid_file_name) + 1 + 1;
582 		new = palloc(path_size);
583 		snprintf(new, path_size, "%s/%s", conf_dir, pool_config->pid_file_name);
584 
585 		ereport(DEBUG1,
586 				(errmsg("pid file location is \"%s\"",
587 						new)));
588 
589 		pfree(conf_file_copy);
590 	}
591 	else
592 	{
593 		new = pstrdup(pool_config->pid_file_name);
594 	}
595 
596 	return new;
597 }
598 
599 /*
600 * read the pid file
601 */
602 static int
read_pid_file(void)603 read_pid_file(void)
604 {
605 	int			fd;
606 	int			readlen;
607 	char		pidbuf[128];
608 	char	   *pid_file = get_pid_file_path();
609 
610 	if (pid_file == NULL)
611 	{
612 		ereport(FATAL,
613 				(errmsg("failed to read pid file"),
614 				 errdetail("failed to get pid file path from \"%s\"",
615 						   pool_config->pid_file_name)));
616 	}
617 	fd = open(pid_file, O_RDONLY);
618 	if (fd == -1)
619 	{
620 		pfree(pid_file);
621 		return -1;
622 	}
623 	if ((readlen = read(fd, pidbuf, sizeof(pidbuf))) == -1)
624 	{
625 		close(fd);
626 		pfree(pid_file);
627 		ereport(FATAL,
628 				(errmsg("could not read pid file \"%s\"",
629 						pool_config->pid_file_name),
630 				 errdetail("%m")));
631 	}
632 	else if (readlen == 0)
633 	{
634 		close(fd);
635 		pfree(pid_file);
636 		ereport(FATAL,
637 				(errmsg("EOF detected while reading pid file \"%s\"",
638 						pool_config->pid_file_name),
639 				 errdetail("%m")));
640 	}
641 	pfree(pid_file);
642 	close(fd);
643 	return (atoi(pidbuf));
644 }
645 
646 /*
647 * write the pid file
648 */
649 static void
write_pid_file(void)650 write_pid_file(void)
651 {
652 	int			fd;
653 	char		pidbuf[128];
654 	char	   *pid_file = get_pid_file_path();
655 
656 	if (pid_file == NULL)
657 	{
658 		ereport(FATAL,
659 				(errmsg("failed to write pid file"),
660 				 errdetail("failed to get pid file path from \"%s\"",
661 						   pool_config->pid_file_name)));
662 	}
663 
664 	fd = open(pid_file, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR);
665 	if (fd == -1)
666 	{
667 		ereport(FATAL,
668 				(errmsg("could not open pid file \"%s\"",
669 						pool_config->pid_file_name),
670 				 errdetail("%m")));
671 	}
672 	snprintf(pidbuf, sizeof(pidbuf), "%d", (int) getpid());
673 	if (write(fd, pidbuf, strlen(pidbuf) + 1) == -1)
674 	{
675 		close(fd);
676 		pfree(pid_file);
677 		ereport(FATAL,
678 				(errmsg("could not write pid file \"%s\"",
679 						pool_config->pid_file_name),
680 				 errdetail("%m")));
681 	}
682 	if (fsync(fd) == -1)
683 	{
684 		close(fd);
685 		pfree(pid_file);
686 		ereport(FATAL,
687 				(errmsg("could not fsync pid file \"%s\"",
688 						pool_config->pid_file_name),
689 				 errdetail("%m")));
690 	}
691 	if (close(fd) == -1)
692 	{
693 		pfree(pid_file);
694 		ereport(FATAL,
695 				(errmsg("could not close pid file \"%s\"",
696 						pool_config->pid_file_name),
697 				 errdetail("%m")));
698 	}
699 	/* register the call back to delete the pid file at system exit */
700 	on_proc_exit(FileUnlink, (Datum) pid_file);
701 }
702 
703 /*
704  * get_config_file_name: return full path of pgpool.conf.
705  */
706 char *
get_config_file_name(void)707 get_config_file_name(void)
708 {
709 	return conf_file;
710 }
711 
712 /*
713  * get_hba_file_name: return full path of pool_hba.conf.
714  */
715 char *
get_hba_file_name(void)716 get_hba_file_name(void)
717 {
718 	return hba_file;
719 }
720 
721 /*
722  * Call back function to unlink the file
723  */
724 static void
FileUnlink(int code,Datum path)725 FileUnlink(int code, Datum path)
726 {
727 	char	   *filePath = (char *) path;
728 
729 	if (unlink(filePath) == 0)
730 		return;
731 
732 	/*
733 	 * We are already exiting the system just produce a log entry to report an
734 	 * error
735 	 */
736 	ereport(LOG,
737 			(errmsg("unlink failed for file at path \"%s\"", filePath),
738 			 errdetail("%m")));
739 }
740