diff --git a/src/openvpn/error.c b/src/openvpn/error.c
index ad4f0ef4..d6247fec 100644
--- a/src/openvpn/error.c
+++ b/src/openvpn/error.c
@@ -743,6 +743,7 @@ openvpn_exit(const int status)
 #ifdef _WIN32
         uninit_win32();
 #endif
+        remove_pid_file();
 
         close_syslog();
 
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index dd1747f3..cb850bc0 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -58,6 +58,7 @@
 
 
 static struct context *static_context; /* GLOBAL */
+static const char *saved_pid_file_name; /* GLOBAL */
 
 /*
  * Crypto initialization flags
@@ -4687,6 +4688,47 @@ close_context(struct context *c, int sig, unsigned int flags)
     }
 }
 
+/* Write our PID to a file */
+void
+write_pid_file(const char *filename, const char *chroot_dir)
+{
+    if (filename)
+    {
+        unsigned int pid = 0;
+        FILE *fp = platform_fopen(filename, "w");
+        if (!fp)
+        {
+            msg(M_ERR, "Open error on pid file %s", filename);
+            return;
+        }
+
+        pid = platform_getpid();
+        fprintf(fp, "%u\n", pid);
+        if (fclose(fp))
+        {
+            msg(M_ERR, "Close error on pid file %s", filename);
+        }
+
+        /* remember file name so it can be deleted "out of context" later */
+	/* (the chroot case is more complex and not handled today) */
+        if (!chroot_dir)
+        {
+            saved_pid_file_name = strdup(filename);
+        }
+    }
+}
+
+/* remove PID file on exit, called from openvpn_exit() */
+void
+remove_pid_file(void)
+{
+    if (saved_pid_file_name)
+    {
+        platform_unlink(saved_pid_file_name);
+    }
+}
+
+
 /*
  * Do a loopback test
  * on the crypto subsystem.
diff --git a/src/openvpn/init.h b/src/openvpn/init.h
index 0e6258f0..a2fdccd3 100644
--- a/src/openvpn/init.h
+++ b/src/openvpn/init.h
@@ -143,4 +143,7 @@ void open_plugins(struct context *c, const bool import_options, int init_point);
 
 void tun_abort(void);
 
+void write_pid_file(const char *filename, const char *chroot_dir);
+void remove_pid_file(void);
+
 #endif /* ifndef INIT_H */
diff --git a/src/openvpn/openvpn.c b/src/openvpn/openvpn.c
index dc7001dc..857c5faa 100644
--- a/src/openvpn/openvpn.c
+++ b/src/openvpn/openvpn.c
@@ -46,28 +46,6 @@ process_signal_p2p(struct context *c)
     return process_signal(c);
 }
 
-/* Write our PID to a file */
-static void
-write_pid(const char *filename)
-{
-    if (filename)
-    {
-        unsigned int pid = 0;
-        FILE *fp = platform_fopen(filename, "w");
-        if (!fp)
-        {
-            msg(M_ERR, "Open error on pid file %s", filename);
-        }
-
-        pid = platform_getpid();
-        fprintf(fp, "%u\n", pid);
-        if (fclose(fp))
-        {
-            msg(M_ERR, "Close error on pid file %s", filename);
-        }
-    }
-}
-
 
 /**************************************************************************/
 /**
@@ -274,7 +252,7 @@ openvpn_main(int argc, char *argv[])
             if (c.first_time)
             {
                 c.did_we_daemonize = possibly_become_daemon(&c.options);
-                write_pid(c.options.writepid);
+                write_pid_file(c.options.writepid, c.options.chroot_dir);
             }
 
 #ifdef ENABLE_MANAGEMENT
