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