From b2eb1ef329680f0faff37550954748fec4616001 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Sun, 22 May 2011 19:05:39 +0300 Subject: Optionally check if there is a running instance already * src/config.c (nssync_kw) : New statement. * src/nssync.c (pidfile): New global. (create_pidfile, remove_pidfile, check_pidfile): New functions. (main): Call check_pidfile. * src/nssync.h (pidfile): New extern. --- src/config.c | 6 +++++ src/nssync.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/nssync.h | 1 + 3 files changed, 79 insertions(+) diff --git a/src/config.c b/src/config.c index ff9c9e4..a2d92b1 100644 --- a/src/config.c +++ b/src/config.c @@ -119,6 +119,12 @@ static struct grecs_keyword nssync_kw[] = { { "slave-status-file", NULL, "Check slave status and save it in the given file", grecs_type_string, &slave_status_file }, + + { "pidfile", + "file", + "At startup, check if already exists and is " + "owned by an existing process. Exit if so.", + grecs_type_string, &pidfile }, { "tempdir", NULL, "Name for the temporary directory (must exist)", diff --git a/src/nssync.c b/src/nssync.c index 3d90c40..9f8fb9d 100644 --- a/src/nssync.c +++ b/src/nssync.c @@ -24,6 +24,7 @@ int preprocess_only; int debug_level; char *config_file = SYSCONFDIR "/nssync.conf"; char *slave_status_file; +char *pidfile; int force; char *tempdir; char *reload_command = "/usr/sbin/rndc reload"; @@ -234,7 +235,76 @@ check_slave_status() free(sql_file); free(sql_off); } + +void +create_pidfile() +{ + FILE *fp; + + if (!pidfile) + return; + + fp = fopen(pidfile, "w"); + if (!fp) { + error(_("cannot create pidfile `%s': %s"), + pidfile, strerror(errno)); + exit(EX_TEMPFAIL); + } + fprintf(fp, "%lu", (unsigned long) getpid()); + fclose(fp); +} + +void +remove_pidfile() +{ + if (pidfile && unlink(pidfile)) + error(_("cannot unlink pidfile `%s': %s"), + pidfile, strerror(errno)); +} + +/* Check whether pidfile NAME exists and if so, whether its PID is still + active. Exit if it is. */ +void +check_pidfile() +{ + unsigned long pid; + FILE *fp; + + if (!pidfile) + return; + + fp = fopen(pidfile, "r"); + + if (!fp) { + if (errno == ENOENT) + return; + error(_("cannot open pidfile `%s': %s"), + pidfile, strerror(errno)); + exit(EX_TEMPFAIL); + } + if (fscanf(fp, "%lu", &pid) != 1) { + error(_("cannot get pid from pidfile `%s'"), pidfile); + } else { + if (kill(pid, 0) == 0) { + error(_("%s appears to run with pid %lu. " + "If it does not, remove `%s' and retry."), + program_name, pid, pidfile); + exit(EX_TEMPFAIL); + } + } + fclose(fp); + if (unlink(pidfile)) { + error(_("cannot unlink pidfile `%s': %s"), + pidfile, strerror(errno)); + exit(EX_NOPERM); + } + + create_pidfile(); + atexit(remove_pidfile); +} + + int main(int argc, char **argv) @@ -249,6 +319,8 @@ main(int argc, char **argv) config_parse(); sql_connect(); + check_pidfile(); + if (slave_status_file) check_slave_status(); diff --git a/src/nssync.h b/src/nssync.h index 52c317a..d083e7f 100644 --- a/src/nssync.h +++ b/src/nssync.h @@ -33,6 +33,7 @@ extern int preprocess_only; extern int debug_level; extern char *config_file; extern char *slave_status_file; +extern char *pidfile; extern char *tempdir; extern char *compare_command; extern char *reload_command; -- cgit v1.2.1