]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Backport to 2.4:
authorGraham Leggett <minfrin@apache.org>
Sat, 16 Jan 2021 13:03:49 +0000 (13:03 +0000)
committerGraham Leggett <minfrin@apache.org>
Sat, 16 Jan 2021 13:03:49 +0000 (13:03 +0000)
  *) core: Make writing the pidfile atomic to avoid startup failures
     after (e.g.) system crashes, but also races with multiple
     concurrent "httpd -k restart" runs which have a race between
     reading and writing a fresh pidfile.
     trunk patch: https://svn.apache.org/r1875153
                  https://svn.apache.org/r1875240
                  https://svn.apache.org/r1877645
     2.4.x patch: https://patch-diff.githubusercontent.com/raw/apache/httpd/pull/163.patch
     +1: jorton, covener, ylavic

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1885562 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
STATUS
server/log.c

diff --git a/CHANGES b/CHANGES
index 3ff8f6d5662bd43b32178e02c494aa9730eb2de9..4d6bf6969da34a2a9f8cc3da9fee02667af9104e 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -143,6 +143,11 @@ Changes with Apache 2.4.42
      with an empty body (regression introduced in 2.4.41). PR63891. 
      [Yann Ylavic]
 
+  *) core: Use a temporary file when writing the pid file, avoiding
+     startup failure if an empty pidfile is left over from a
+     previous crashed or aborted invocation of httpd.  PR 63140.
+     [Nicolas Carrier <carrier.nicolas0 gmail.com>, Joe Orton]
+
   *) mod_http2: Fixes issue where mod_unique_id would generate non-unique request
      identifier under load, see <https://github.com/icing/mod_h2/issues/195>.
      [Michael Kaufmann, Stefan Eissing]
diff --git a/STATUS b/STATUS
index cb63568730ecc515f78f3e79461aa89d1b80f199..dc7b0b192210407a8af0bed7418f635b2b3eb97c 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -138,15 +138,6 @@ RELEASE SHOWSTOPPERS:
 PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
   [ start all new proposals below, under PATCHES PROPOSED. ]
 
-  *) core: Make writing the pidfile atomic to avoid startup failures
-     after (e.g.) system crashes, but also races with multiple
-     concurrent "httpd -k restart" runs which have a race between
-     reading and writing a fresh pidfile.
-     trunk patch: https://svn.apache.org/r1875153
-                  https://svn.apache.org/r1875240
-                  https://svn.apache.org/r1877645
-     2.4.x patch: https://patch-diff.githubusercontent.com/raw/apache/httpd/pull/163.patch
-     +1: jorton, covener, ylavic
 
 PATCHES PROPOSED TO BACKPORT FROM TRUNK:
   [ New proposals should be added at the end of the list ]
index c75f58192fb562cebc5d31a6b636537cad3856d5..374f95d532d60c9c0249813d8854dc0ba21a702e 100644 (file)
@@ -1600,6 +1600,9 @@ AP_DECLARE(void) ap_log_pid(apr_pool_t *p, const char *filename)
     pid_t mypid;
     apr_status_t rv;
     const char *fname;
+    char *temp_fname;
+    apr_fileperms_t perms;
+    char pidstr[64];
 
     if (!filename) {
         return;
@@ -1628,19 +1631,31 @@ AP_DECLARE(void) ap_log_pid(apr_pool_t *p, const char *filename)
                       fname);
     }
 
-    if ((rv = apr_file_open(&pid_file, fname,
-                            APR_WRITE | APR_CREATE | APR_TRUNCATE,
-                            APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD, p))
-        != APR_SUCCESS) {
+    temp_fname = apr_pstrcat(p, fname, ".XXXXXX", NULL);
+    rv = apr_file_mktemp(&pid_file, temp_fname,
+                         APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_TRUNCATE, p);
+    if (rv != APR_SUCCESS) {
         ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, APLOGNO(00099)
-                     "could not create %s", fname);
+                     "could not create %s", temp_fname);
         ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, APLOGNO(00100)
                      "%s: could not log pid to file %s",
                      ap_server_argv0, fname);
         exit(1);
     }
-    apr_file_printf(pid_file, "%" APR_PID_T_FMT APR_EOL_STR, mypid);
-    apr_file_close(pid_file);
+
+    apr_snprintf(pidstr, sizeof pidstr, "%" APR_PID_T_FMT APR_EOL_STR, mypid);
+
+    perms = APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD;
+    if (((rv = apr_file_perms_set(temp_fname, perms)) != APR_SUCCESS && rv != APR_ENOTIMPL)
+        || (rv = apr_file_write_full(pid_file, pidstr, strlen(pidstr), NULL)) != APR_SUCCESS
+        || (rv = apr_file_close(pid_file)) != APR_SUCCESS
+        || (rv = apr_file_rename(temp_fname, fname, p)) != APR_SUCCESS) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, APLOGNO(10231)
+                     "%s: Failed creating pid file %s",
+                     ap_server_argv0, temp_fname);
+        exit(1);
+    }
+
     saved_pid = mypid;
 }