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]
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 ]
pid_t mypid;
apr_status_t rv;
const char *fname;
+ char *temp_fname;
+ apr_fileperms_t perms;
+ char pidstr[64];
if (!filename) {
return;
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;
}