mod_posix: Lock pidfile when in use, shut down if we can't write or lock the pidfile

Sun, 10 Jan 2010 23:49:38 +0000

author
Matthew Wild <mwild1@gmail.com>
date
Sun, 10 Jan 2010 23:49:38 +0000
changeset 2793
08892e3f24bd
parent 2792
1b14388f1512
child 2794
5f14cd94a563

mod_posix: Lock pidfile when in use, shut down if we can't write or lock the pidfile

plugins/mod_posix.lua file | annotate | diff | comparison | revisions
--- a/plugins/mod_posix.lua	Sun Jan 10 03:54:29 2010 +0000
+++ b/plugins/mod_posix.lua	Sun Jan 10 23:49:38 2010 +0000
@@ -19,6 +19,8 @@
 
 local logger_set = require "util.logger".setwriter;
 
+local lfs = require "lfs";
+
 local prosody = _G.prosody;
 
 module.host = "*"; -- we're a global module
@@ -59,28 +61,37 @@
 		end
 	end);
 
-local pidfile_written;
+local pidfile;
+local pidfile_handle;
 
 local function remove_pidfile()
-	if pidfile_written then
-		os.remove(pidfile_written);
-		pidfile_written = nil;
+	if pidfile_handle then
+		pidfile_handle:close();
+		os.remove(pidfile);
+		pidfile, pidfile_handle = nil, nil;
 	end
 end
 
 local function write_pidfile()
-	if pidfile_written then
+	if pidfile_handle then
 		remove_pidfile();
 	end
-	local pidfile = module:get_option("pidfile");
+	pidfile = module:get_option("pidfile");
 	if pidfile then
-		local pf, err = io.open(pidfile, "w+");
-		if not pf then
-			module:log("error", "Couldn't write pidfile; %s", err);
+		pidfile_handle, err = io.open(pidfile, "a+");
+		if not pidfile_handle then
+			module:log("error", "Couldn't write pidfile at %s; %s", pidfile, err);
+			prosody.shutdown("Couldn't write pidfile");
 		else
-			pf:write(tostring(pposix.getpid()));
-			pf:close();
-			pidfile_written = pidfile;
+			if not lfs.lock(pidfile_handle, "w") then -- Exclusive lock
+				local other_pid = pidfile_handle:read("*a");
+				module:log("error", "Another Prosody instance seems to be running with PID %s, quitting", other_pid);
+				pidfile_handle = nil;
+				prosody.shutdown("Prosody already running");
+			else
+				pidfile_handle:write(tostring(pposix.getpid()));
+				pidfile_handle:flush();
+			end
 		end
 	end
 end

mercurial