summaryrefslogtreecommitdiffabout
authorSergey Poznyakoff <gray@gnu.org.ua>2011-05-22 16:05:39 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2011-05-22 16:05:39 (GMT)
commitb2eb1ef329680f0faff37550954748fec4616001 (patch) (side-by-side diff)
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.
Diffstat (more/less context) (ignore whitespace changes)
-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
@@ -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 <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)",
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;

Return to:

Send suggestions and report system problems to the System administrator.