aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-05-22 19:05:39 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2011-05-22 19:05:39 +0300
commitb2eb1ef329680f0faff37550954748fec4616001 (patch)
treeb20a61b20750d928c3055cfc94b2254dd694880e
parentb32cc9bd4d9695fee857e71520833ce89134169e (diff)
downloadnssync-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.c6
-rw-r--r--src/nssync.c72
-rw-r--r--src/nssync.h1
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;

Return to:

Send suggestions and report system problems to the System administrator.