diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-05-22 19:05:39 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-05-22 19:05:39 +0300 |
commit | b2eb1ef329680f0faff37550954748fec4616001 (patch) | |
tree | b20a61b20750d928c3055cfc94b2254dd694880e | |
parent | b32cc9bd4d9695fee857e71520833ce89134169e (diff) | |
download | nssync-b2eb1ef329680f0faff37550954748fec4616001.tar.gz nssync-b2eb1ef329680f0faff37550954748fec4616001.tar.bz2 |
Optionally check if there is a running instance already
* src/config.c (nssync_kw) <pidfile>: 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.
-rw-r--r-- | src/config.c | 6 | ||||
-rw-r--r-- | src/nssync.c | 72 | ||||
-rw-r--r-- | src/nssync.h | 1 |
3 files changed, 79 insertions, 0 deletions
diff --git a/src/config.c b/src/config.c index ff9c9e4..a2d92b1 100644 --- a/src/config.c +++ b/src/config.c @@ -116,12 +116,18 @@ static struct grecs_keyword nssync_kw[] = { "file", "File name of the Certificate Authority (CA) certificate", grecs_type_string, &sql_cacert }, { "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 <file> 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)", grecs_type_string, &tempdir }, { "named-conf", diff --git a/src/nssync.c b/src/nssync.c index 3d90c40..9f8fb9d 100644 --- a/src/nssync.c +++ b/src/nssync.c @@ -21,12 +21,13 @@ int lint_mode; int dry_run_mode; 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"; char *compare_command = "cmp $oldfile $newfile > /dev/null"; unsigned error_count; unsigned changed_zones; @@ -231,13 +232,82 @@ check_slave_status() fprintf(fp, "%s %s\n", sql_file, sql_off); fclose(fp); } 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) { struct grecs_list_entry *ep; @@ -246,12 +316,14 @@ main(int argc, char **argv) if (preprocess_only) exit(grecs_preproc_run(config_file, grecs_preprocessor) ? EX_CONFIG : 0); config_parse(); sql_connect(); + check_pidfile(); + if (slave_status_file) check_slave_status(); for (ep = synclist->head; ep; ep = ep->next) synchronize(ep->data); diff --git a/src/nssync.h b/src/nssync.h index 52c317a..d083e7f 100644 --- a/src/nssync.h +++ b/src/nssync.h @@ -30,12 +30,13 @@ extern int lint_mode; extern int dry_run_mode; 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; extern unsigned changed_zones; |