From bd738d630c6df895d2e92706ea6bd3e0a8a9c084 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Mon, 17 Oct 2011 12:22:09 +0000 Subject: [PATCH] Allow to specify pidfile in HAST configuration file. MFC after: 1 week --- sbin/hastd/hast.conf.5 | 11 +++++++ sbin/hastd/hast.h | 2 ++ sbin/hastd/hastd.c | 74 ++++++++++++++++++++++++++++++++++-------- sbin/hastd/parse.y | 42 +++++++++++++++++++++++- sbin/hastd/token.l | 1 + 5 files changed, 116 insertions(+), 14 deletions(-) diff --git a/sbin/hastd/hast.conf.5 b/sbin/hastd/hast.conf.5 index 6410ae735933..1eb66e3202e5 100644 --- a/sbin/hastd/hast.conf.5 +++ b/sbin/hastd/hast.conf.5 @@ -64,17 +64,20 @@ compression timeout exec metaflush "on" | "off" +pidfile on { # Node section control listen + pidfile } on { # Node section control listen + pidfile } resource { @@ -146,6 +149,14 @@ unix:///var/run/hastctl .Pp The default value is .Pa uds:///var/run/hastctl . +.It Ic pidfile Aq path +.Pp +File in which to store the process ID of the main +.Xr hastd 8 +process. +.Pp +The default value is +.Pa /var/run/hastd.pid . .It Ic listen Aq addr .Pp Address to listen on in form of: diff --git a/sbin/hastd/hast.h b/sbin/hastd/hast.h index 52bc6299972e..94e572426dd8 100644 --- a/sbin/hastd/hast.h +++ b/sbin/hastd/hast.h @@ -116,6 +116,8 @@ struct hastd_config { struct proto_conn *hc_controlconn; /* Incoming control connection. */ struct proto_conn *hc_controlin; + /* PID file path. */ + char hc_pidfile[PATH_MAX]; /* List of addresses to listen on. */ TAILQ_HEAD(, hastd_listen) hc_listen; /* List of resources. */ diff --git a/sbin/hastd/hastd.c b/sbin/hastd/hastd.c index e4cd52022ec1..fdb1c5b99081 100644 --- a/sbin/hastd/hastd.c +++ b/sbin/hastd/hastd.c @@ -476,11 +476,15 @@ hastd_reload(void) struct hastd_config *newcfg; struct hast_resource *nres, *cres, *tres; struct hastd_listen *nlst, *clst; + struct pidfh *newpfh; unsigned int nlisten; uint8_t role; + pid_t otherpid; pjdlog_info("Reloading configuration..."); + newpfh = NULL; + newcfg = yy_config_parse(cfgpath, false); if (newcfg == NULL) goto failed; @@ -524,6 +528,31 @@ hastd_reload(void) pjdlog_error("No addresses to listen on."); goto failed; } + /* + * Check if pidfile's path has changed. + */ + if (strcmp(cfg->hc_pidfile, newcfg->hc_pidfile) != 0) { + newpfh = pidfile_open(newcfg->hc_pidfile, 0600, &otherpid); + if (newpfh == NULL) { + if (errno == EEXIST) { + pjdlog_errno(LOG_WARNING, + "Another hastd is already running, pidfile: %s, pid: %jd.", + newcfg->hc_pidfile, (intmax_t)otherpid); + } else { + pjdlog_errno(LOG_WARNING, + "Unable to open or create pidfile %s", + newcfg->hc_pidfile); + } + } else if (pidfile_write(newpfh) < 0) { + /* Write PID to a file. */ + pjdlog_errno(LOG_WARNING, + "Unable to write PID to file %s", + newcfg->hc_pidfile); + } else { + pjdlog_debug(1, "PID stored in %s.", + newcfg->hc_pidfile); + } + } /* No failures from now on. */ @@ -539,6 +568,13 @@ hastd_reload(void) strlcpy(cfg->hc_controladdr, newcfg->hc_controladdr, sizeof(cfg->hc_controladdr)); } + /* + * Switch to new pidfile. + */ + (void)pidfile_remove(pfh); + pfh = newpfh; + (void)strlcpy(cfg->hc_pidfile, newcfg->hc_pidfile, + sizeof(cfg->hc_pidfile)); /* * Switch to new listen addresses. Close all that were removed. */ @@ -666,6 +702,8 @@ failed: } yy_config_free(newcfg); } + if (newpfh != NULL) + (void)pidfile_remove(newpfh); pjdlog_warning("Configuration not reloaded."); } @@ -1123,7 +1161,7 @@ main(int argc, char *argv[]) foreground = false; debuglevel = 0; - pidfile = HASTD_PIDFILE; + pidfile = NULL; for (;;) { int ch; @@ -1157,17 +1195,6 @@ main(int argc, char *argv[]) g_gate_load(); - pfh = pidfile_open(pidfile, 0600, &otherpid); - if (pfh == NULL) { - if (errno == EEXIST) { - pjdlog_exitx(EX_TEMPFAIL, - "Another hastd is already running, pid: %jd.", - (intmax_t)otherpid); - } - /* If we cannot create pidfile from other reasons, only warn. */ - pjdlog_errno(LOG_WARNING, "Unable to open or create pidfile"); - } - /* * When path to the configuration file is relative, obtain full path, * so we can always find the file, even after daemonizing and changing @@ -1187,6 +1214,24 @@ main(int argc, char *argv[]) cfg = yy_config_parse(cfgpath, true); PJDLOG_ASSERT(cfg != NULL); + if (pidfile != NULL) { + if (strlcpy(cfg->hc_pidfile, pidfile, + sizeof(cfg->hc_pidfile)) >= sizeof(cfg->hc_pidfile)) { + pjdlog_exitx(EX_CONFIG, "Pidfile path is too long."); + } + } + pfh = pidfile_open(cfg->hc_pidfile, 0600, &otherpid); + if (pfh == NULL) { + if (errno == EEXIST) { + pjdlog_exitx(EX_TEMPFAIL, + "Another hastd is already running, pidfile: %s, pid: %jd.", + cfg->hc_pidfile, (intmax_t)otherpid); + } + /* If we cannot create pidfile for other reasons, only warn. */ + pjdlog_errno(LOG_WARNING, "Unable to open or create pidfile %s", + cfg->hc_pidfile); + } + /* * Restore default actions for interesting signals in case parent * process (like init(8)) decided to ignore some of them (like SIGHUP). @@ -1234,7 +1279,10 @@ main(int argc, char *argv[]) /* Write PID to a file. */ if (pidfile_write(pfh) < 0) { pjdlog_errno(LOG_WARNING, - "Unable to write PID to a file"); + "Unable to write PID to a file %s", + cfg->hc_pidfile); + } else { + pjdlog_debug(1, "PID stored in %s.", cfg->hc_pidfile); } } diff --git a/sbin/hastd/parse.y b/sbin/hastd/parse.y index 15b11430a124..6174a2bb312e 100644 --- a/sbin/hastd/parse.y +++ b/sbin/hastd/parse.y @@ -60,6 +60,7 @@ static struct hast_resource *curres; static bool mynode, hadmynode; static char depth0_control[HAST_ADDRSIZE]; +static char depth0_pidfile[PATH_MAX]; static char depth0_listen_tcp4[HAST_ADDRSIZE]; static char depth0_listen_tcp6[HAST_ADDRSIZE]; static TAILQ_HEAD(, hastd_listen) depth0_listen; @@ -193,6 +194,7 @@ yy_config_parse(const char *config, bool exitonerror) depth0_checksum = HAST_CHECKSUM_NONE; depth0_compression = HAST_COMPRESSION_HOLE; strlcpy(depth0_control, HAST_CONTROL, sizeof(depth0_control)); + strlcpy(depth0_pidfile, HASTD_PIDFILE, sizeof(depth0_pidfile)); TAILQ_INIT(&depth0_listen); strlcpy(depth0_listen_tcp4, HASTD_LISTEN_TCP4, sizeof(depth0_listen_tcp4)); @@ -238,6 +240,10 @@ yy_config_parse(const char *config, bool exitonerror) strlcpy(lconfig->hc_controladdr, depth0_control, sizeof(lconfig->hc_controladdr)); } + if (lconfig->hc_pidfile[0] == '\0') { + strlcpy(lconfig->hc_pidfile, depth0_pidfile, + sizeof(lconfig->hc_pidfile)); + } if (!TAILQ_EMPTY(&depth0_listen)) TAILQ_CONCAT(&lconfig->hc_listen, &depth0_listen, hl_next); if (TAILQ_EMPTY(&lconfig->hc_listen)) { @@ -365,7 +371,7 @@ yy_config_free(struct hastd_config *config) } %} -%token CONTROL LISTEN PORT REPLICATION CHECKSUM COMPRESSION METAFLUSH +%token CONTROL PIDFILE LISTEN PORT REPLICATION CHECKSUM COMPRESSION METAFLUSH %token TIMEOUT EXEC EXTENTSIZE RESOURCE NAME LOCAL REMOTE SOURCE ON OFF %token FULLSYNC MEMSYNC ASYNC NONE CRC32 SHA256 HOLE LZF %token NUM STR OB CB @@ -395,6 +401,8 @@ statements: statement: control_statement | + pidfile_statement + | listen_statement | replication_statement @@ -444,6 +452,36 @@ control_statement: CONTROL STR } ; +pidfile_statement: PIDFILE STR + { + switch (depth) { + case 0: + if (strlcpy(depth0_pidfile, $2, + sizeof(depth0_pidfile)) >= + sizeof(depth0_pidfile)) { + pjdlog_error("pidfile argument is too long."); + free($2); + return (1); + } + break; + case 1: + if (!mynode) + break; + if (strlcpy(lconfig->hc_pidfile, $2, + sizeof(lconfig->hc_pidfile)) >= + sizeof(lconfig->hc_pidfile)) { + pjdlog_error("pidfile argument is too long."); + free($2); + return (1); + } + break; + default: + PJDLOG_ABORT("pidfile at wrong depth level"); + } + free($2); + } + ; + listen_statement: LISTEN STR { struct hastd_listen *lst; @@ -658,6 +696,8 @@ node_entries: node_entry: control_statement | + pidfile_statement + | listen_statement ; diff --git a/sbin/hastd/token.l b/sbin/hastd/token.l index 3a868d7f1e48..0d1507563eed 100644 --- a/sbin/hastd/token.l +++ b/sbin/hastd/token.l @@ -46,6 +46,7 @@ int lineno; %% control { DP; return CONTROL; } +pidfile { DP; return PIDFILE; } listen { DP; return LISTEN; } port { DP; return PORT; } replication { DP; return REPLICATION; }