[PATCH v3] tgtd: support pid file for tgtd daemon

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Specify the pid file by command argument -p/--pid-file, tgtd can
write pid in pid file after running into daemon, and remove the
file before exiting.
The pid file's life cycle should be as the same as the tgtd, so we
can only remove it before tgtd exiting. The pid file may still remains
after tgtd crashing due to a bug, but it's does not matter. The logic
of monitor agent may be like this:
	static int tgtd_pid;

	int pid = get_pid_from_pidfile(path);
	if (!is_running(pid) || (tgdt_pid != pid)) {
		do_something();
	}

Signed-off-by: zhenwei pi <pizhenwei@xxxxxxxxxxxxx>
Acked-by: FUJITA Tomonori <fujita.tomonori@xxxxxxxxx>
---
 usr/tgtd.c | 40 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/usr/tgtd.c b/usr/tgtd.c
index ae2f489..dd6e6f2 100644
--- a/usr/tgtd.c
+++ b/usr/tgtd.c
@@ -55,13 +55,14 @@ static struct option const long_options[] = {
 	{"foreground", no_argument, 0, 'f'},
 	{"control-port", required_argument, 0, 'C'},
 	{"nr_iothreads", required_argument, 0, 't'},
+	{"pid-file", required_argument, 0, 'p'},
 	{"debug", required_argument, 0, 'd'},
 	{"version", no_argument, 0, 'V'},
 	{"help", no_argument, 0, 'h'},
 	{0, 0, 0, 0},
 };
 
-static char *short_options = "fC:d:t:Vh";
+static char *short_options = "fC:d:t:p:Vh";
 static char *spare_args;
 
 static void usage(int status)
@@ -77,6 +78,7 @@ static void usage(int status)
 		"-f, --foreground        make the program run in the foreground\n"
 		"-C, --control-port NNNN use port NNNN for the mgmt channel\n"
 		"-t, --nr_iothreads NNNN specify the number of I/O threads\n"
+		"-p, --pid-file filename specify the pid file\n"
 		"-d, --debug debuglevel  print debugging information\n"
 		"-V, --version           print version and exit\n"
 		"-h, --help              display this help and exit\n",
@@ -174,6 +176,28 @@ set_rlimit:
 	return 0;
 }
 
+void create_pid_file(const char *path)
+{
+	int fd, ret;
+	int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+	char buf[32] = {0};
+
+	fd = open(path, O_RDWR | O_CREAT, mode);
+	if (fd < 0) {
+		eprintf("can't create %s, %m\n", path);
+		return;
+	}
+
+	snprintf(buf, sizeof(buf), "%d", getpid());
+	ret = write(fd, buf, strlen(buf));
+	close(fd);
+
+	if (ret < 0) {
+		eprintf("can't write and remove %s, %m\n", path);
+		unlink(path);
+	}
+}
+
 int tgt_event_add(int fd, int events, event_handler_t handler, void *data)
 {
 	struct epoll_event ev;
@@ -525,6 +549,7 @@ int main(int argc, char **argv)
 	int err, ch, longindex, nr_lld = 0;
 	int is_daemon = 1, is_debug = 0;
 	int ret;
+	char *pidfile = NULL;
 
 	sa_new.sa_handler = signal_catch;
 	sigemptyset(&sa_new.sa_mask);
@@ -555,6 +580,13 @@ int main(int argc, char **argv)
 			if (ret)
 				bad_optarg(ret, ch, optarg);
 			break;
+		case 'p':
+			pidfile = strdup(optarg);
+			if (pidfile == NULL) {
+				fprintf(stderr, "can't duplicate pid file\n");
+				exit(1);
+			}
+			break;
 		case 'd':
 			ret = str_to_int_range(optarg, is_debug, 0, 1);
 			if (ret)
@@ -621,6 +653,9 @@ int main(int argc, char **argv)
 	sd_notify(0, "READY=1\nSTATUS=Starting event loop...");
 #endif
 
+	if (is_daemon && pidfile)
+		create_pid_file(pidfile);
+
 	event_loop();
 
 	lld_exit();
@@ -631,5 +666,8 @@ int main(int argc, char **argv)
 
 	log_close();
 
+	if (is_daemon && pidfile)
+		unlink(pidfile);
+
 	return 0;
 }
-- 
2.7.4




[Index of Archives]     [Linux SCSI]     [Linux RAID]     [Linux Clusters]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]

  Powered by Linux