From 9ee5efde7df57cbe70fb9b32c9d898e8ef7eca1e Mon Sep 17 00:00:00 2001 From: Bob Halley Date: Sat, 29 Jan 2000 01:38:09 +0000 Subject: [PATCH] pid file support --- bin/named/server.c | 25 +++++---- bin/named/unix/include/named/os.h | 9 ++-- bin/named/unix/os.c | 90 ++++++++++++++++++++++++++++--- 3 files changed, 105 insertions(+), 19 deletions(-) diff --git a/bin/named/server.c b/bin/named/server.c index 16ce122354..f4a85fb2ff 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -603,7 +603,9 @@ configure_server_querysource(dns_c_ctx_t *cctx, ns_server_t *server, } static isc_result_t -load_configuration(const char *filename, ns_server_t *server) { +load_configuration(const char *filename, ns_server_t *server, + isc_boolean_t first_time) +{ isc_result_t result; ns_load_t lctx; dns_c_cbks_t callbacks; @@ -612,6 +614,7 @@ load_configuration(const char *filename, ns_server_t *server) { dns_viewlist_t tmpviewlist; dns_aclconfctx_t aclconfctx; dns_dispatch_t *dispatch; + char *pidfilename; dns_aclconfctx_init(&aclconfctx); @@ -776,6 +779,14 @@ load_configuration(const char *filename, ns_server_t *server) { dns_tkeyctx_destroy(&server->tkeyctx); server->tkeyctx = t; } + + if (first_time) + ns_os_changeuser(ns_g_username); + + if (dns_c_ctx_getpidfilename(configctx, &pidfilename) == + ISC_R_NOTFOUND) + pidfilename = "/var/run/named.pid"; + ns_os_writepidfile(pidfilename); dns_aclconfctx_destroy(&aclconfctx); @@ -833,6 +844,7 @@ static void run_server(isc_task_t *task, isc_event_t *event) { isc_result_t result; ns_server_t *server = (ns_server_t *) event->arg; + (void)task; isc_event_free(&event); @@ -846,19 +858,12 @@ run_server(isc_task_t *task, isc_event_t *event) { &server->interfacemgr), "creating interface manager"); - CHECKFATAL(load_configuration(ns_g_conffile, server), + CHECKFATAL(load_configuration(ns_g_conffile, server, ISC_TRUE), "loading configuration"); CHECKFATAL(load_zones(server, ISC_TRUE), "loading zones"); - /* - * XXXRTH Currently ns_os_changeuser() will call ns_main_earlyfatal() - * if it fails. Perhaps it should be changed to return an - * error code? - */ - ns_os_changeuser(ns_g_username); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_INFO, "running"); } @@ -1021,7 +1026,7 @@ ns_server_reload(isc_task_t *task, isc_event_t *event) { ns_server_t *server = (ns_server_t *) event->arg; UNUSED(task); - result = load_configuration(ns_g_conffile, server); + result = load_configuration(ns_g_conffile, server, ISC_FALSE); if (result != DNS_R_SUCCESS) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, diff --git a/bin/named/unix/include/named/os.h b/bin/named/unix/include/named/os.h index 9bcd9d08ef..9dba02d6de 100644 --- a/bin/named/unix/include/named/os.h +++ b/bin/named/unix/include/named/os.h @@ -26,13 +26,16 @@ ns_os_init(void); void ns_os_daemonize(void); -void -ns_os_shutdown(void); - void ns_os_chroot(const char *root); void ns_os_changeuser(const char *username); +void +ns_os_writepidfile(const char *filename); + +void +ns_os_shutdown(void); + #endif /* NS_OS_H */ diff --git a/bin/named/unix/os.c b/bin/named/unix/os.c index 23cb5a785d..b759339d15 100644 --- a/bin/named/unix/os.c +++ b/bin/named/unix/os.c @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -36,6 +37,10 @@ #include #include +static char *pidfile = NULL; +#ifdef HAVE_LINUXTHREADS +static pid_t mainpid = 0; +#endif #ifdef HAVE_LINUX_CAPABILITY_H @@ -119,6 +124,9 @@ ns_os_init(void) { #ifdef HAVE_LINUX_CAPABILITY_H linux_initialprivs(); #endif +#ifdef HAVE_LINUXTHREADS + mainpid = getpid(); +#endif } void @@ -136,6 +144,10 @@ ns_os_daemonize(void) { * We're the child. */ +#ifdef HAVE_LINUXTHREADS + mainpid = getpid(); +#endif + if (setsid() == -1) ns_main_earlyfatal("setsid(): %s", strerror(errno)); @@ -155,12 +167,6 @@ ns_os_daemonize(void) { } } -void -ns_os_shutdown(void) { - closelog(); -} - - static isc_boolean_t all_digits(const char *s) { if (*s == '\0') @@ -211,3 +217,75 @@ ns_os_changeuser(const char *username) { if (setuid(pw->pw_uid) < 0) ns_main_earlyfatal("setuid(): %s", strerror(errno)); } + +static int +safe_open(const char *filename) { + struct stat sb; + + if (stat(filename, &sb) == -1) { + if (errno != ENOENT) + return (-1); + } else if ((sb.st_mode & S_IFREG) == 0) + return (-1); + + (void)unlink(filename); + return (open(filename, O_WRONLY|O_CREAT|O_EXCL, + S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)); +} + +static void +cleanup_pidfile(void) { + if (pidfile != NULL) + (void)unlink(pidfile); + free(pidfile); + pidfile = NULL; +} + +void +ns_os_writepidfile(const char *filename) { + int fd; + FILE *lockfile; + size_t len; + pid_t pid; + + /* + * The caller must ensure any required synchronization. + */ + + cleanup_pidfile(); + + len = strlen(filename); + pidfile = malloc(len + 1); + if (pidfile == NULL) + ns_main_earlyfatal("couldn't malloc '%s': %s", + filename, strerror(errno)); + /* This is safe. */ + strcpy(pidfile, filename); + + fd = safe_open(filename); + if (fd < 0) + ns_main_earlyfatal("couldn't open pid file '%s': %s", + filename, strerror(errno)); + lockfile = fdopen(fd, "w"); + if (lockfile == NULL) + ns_main_earlyfatal("could not fdopen() pid file '%s': %s", + filename, strerror(errno)); +#ifdef HAVE_LINUXTHREADS + pid = mainpid; +#else + pid = getpid(); +#endif + if (fprintf(lockfile, "%ld\n", (long)pid) < 0) + ns_main_earlyfatal("fprintf() to pid file '%s' failed", + filename); + if (fflush(lockfile) == EOF) + ns_main_earlyfatal("fflush() to pid file '%s' failed", + filename); + (void)fclose(lockfile); +} + +void +ns_os_shutdown(void) { + closelog(); + cleanup_pidfile(); +}