15a8b20
From d371c4769dac5d84fa2089299efd77b5341c5079 Mon Sep 17 00:00:00 2001
15a8b20
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
15a8b20
Date: Thu, 3 Feb 2011 17:57:09 +0100
15a8b20
Subject: [PATCH] Store PID of quota_nld
15a8b20
15a8b20
If quota_nld is run as daemon, daemon's PID will be stored into
15a8b20
/var/run/${PROGNAME}.pid file and it will be deleted on receiving SIGTERM
15a8b20
just before program termination.
15a8b20
15a8b20
PID file is used by init scripts to find and kill forked daemon.
15a8b20
---
15a8b20
 quota_nld.c |   79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15a8b20
 1 files changed, 79 insertions(+), 0 deletions(-)
15a8b20
15a8b20
diff --git a/quota_nld.c b/quota_nld.c
15a8b20
index 538702d..600bdf1 100644
15a8b20
--- a/quota_nld.c
15a8b20
+++ b/quota_nld.c
15a8b20
@@ -25,6 +25,7 @@
15a8b20
 #include <string.h>
15a8b20
 #include <fcntl.h>
15a8b20
 #include <limits.h>
15a8b20
+#include <signal.h>
15a8b20
 
15a8b20
 #include <netlink/genl/genl.h>
15a8b20
 #include <netlink/genl/ctrl.h>
15a8b20
@@ -369,6 +370,83 @@ static void run(struct nl_handle *nhandle)
15a8b20
 	}
15a8b20
 }
15a8b20
 
15a8b20
+/* Build file name (absolute path) to PID file of this daemon.
15a8b20
+ * The returned name is allocated on heap. */
15a8b20
+static char *build_pid_file_name(void)
15a8b20
+{
15a8b20
+	char *pid_name = NULL;
15a8b20
+	if (!progname) {
15a8b20
+		errstr(_("Undefined program name.\n"));
15a8b20
+		return NULL;
15a8b20
+	}
15a8b20
+	pid_name = malloc(9 + strlen(progname) + 4 + 1);
15a8b20
+	if (!pid_name) {
15a8b20
+		errstr(_("Not enough memory to build PID file name.\n"));
15a8b20
+		return NULL;
15a8b20
+	}
15a8b20
+	sprintf(pid_name, "/var/run/%s.pid", progname);
15a8b20
+	return pid_name;
15a8b20
+}
15a8b20
+
15a8b20
+/* Store daemon's PID to file */
15a8b20
+static int store_pid(void)
15a8b20
+{
15a8b20
+	FILE *pid_file;
15a8b20
+	char *pid_name;
15a8b20
+
15a8b20
+	pid_name = build_pid_file_name();
15a8b20
+	if (!pid_name) return -1;
15a8b20
+
15a8b20
+	pid_file = fopen(pid_name, "w");
15a8b20
+	if (!pid_file) {
15a8b20
+		errstr(_("Could not open PID file '%s': %s\n"),
15a8b20
+			pid_name, strerror(errno));
15a8b20
+		free(pid_name);
15a8b20
+		return -1;
15a8b20
+	}
15a8b20
+	if (0 > fprintf(pid_file, "%jd\n", (intmax_t)getpid())) {
15a8b20
+		errstr(_("Could not write daemon's PID into '%s'.\n"),
15a8b20
+		       	pid_name);
15a8b20
+		fclose(pid_file);
15a8b20
+		free(pid_name);
15a8b20
+		return -1;
15a8b20
+	}
15a8b20
+	if (fclose(pid_file)) {
15a8b20
+		errstr(_("Could not close PID file '%s'.\n"), pid_name);
15a8b20
+		free(pid_name);
15a8b20
+		return -1;
15a8b20
+	}
15a8b20
+
15a8b20
+	free(pid_name);
15a8b20
+	return 0;
15a8b20
+}
15a8b20
+
15a8b20
+/* Handler for SIGTERM to remove PID file */
15a8b20
+static void remove_pid(int signal)
15a8b20
+{
15a8b20
+	char *pid_name;
15a8b20
+
15a8b20
+	pid_name = build_pid_file_name();
15a8b20
+	if (pid_name) {
15a8b20
+		unlink(pid_name);
15a8b20
+		free(pid_name);
15a8b20
+	}
15a8b20
+	exit(EXIT_SUCCESS);
15a8b20
+}
15a8b20
+
15a8b20
+/* Store daemon's PID into file and register its removal on SIGTERM */
15a8b20
+static int use_pid_file(void)
15a8b20
+{
15a8b20
+	struct sigaction term_action;
15a8b20
+
15a8b20
+	term_action.sa_handler = remove_pid;
15a8b20
+	term_action.sa_flags = 0;
15a8b20
+	if (sigaction(SIGTERM, &term_action, NULL))
15a8b20
+		errstr(_("Could not register PID file removal on SIGTERM.\n"));
15a8b20
+	if (store_pid())
15a8b20
+		errstr(_("Could not store my PID %jd.\n"), (intmax_t )getpid());
15a8b20
+}
15a8b20
+
15a8b20
 int main(int argc, char **argv)
15a8b20
 {
15a8b20
 	struct nl_handle *nhandle;
15a8b20
@@ -383,6 +461,7 @@ int main(int argc, char **argv)
15a8b20
 	if (!(flags & FL_NODAEMON)) {
15a8b20
 		use_syslog();
15a8b20
 		daemon(0, 0);
15a8b20
+		use_pid_file();
15a8b20
 	}
15a8b20
 	run(nhandle);
15a8b20
 	return 0;
15a8b20
-- 
15a8b20
1.7.4
15a8b20