Bug 62268 - Using the -p option on rotatelogs causes it to fail in apr_poll()
Summary: Using the -p option on rotatelogs causes it to fail in apr_poll()
Status: NEEDINFO
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: support (show other bugs)
Version: 2.4.33
Hardware: PC NetBSD
: P2 normal (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-04-06 15:57 UTC by John Hascall
Modified: 2018-04-09 09:45 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description John Hascall 2018-04-06 15:57:40 UTC
Using the "-p program" option causes rotatelogs to fail in its call to apr_poll() when the program exits and the underlying poll() system errors with EINTR due to the SIGCHLD.   This is logged in Apache's error_log as:

piped log program '/usr/local/etc/rotatelogs -c -f -l -p /usr/local/etc/zipit -L /var/log/httpd/dnsrpz_log /var/log/httpd/dnsrpz_log.%Y-%m 86400' failed unexpectedly
Unable to poll stdin

Removing the "-p program" option is an unsatisfactory workaround.

The code in question:

                pollret = apr_poll(&pollfd, 1, &pollret, apr_time_from_sec(polltimeout));
            }
        }
        if (pollret == APR_SUCCESS) {
            rv = apr_file_read(f_stdin, buf, &nRead);
            if (APR_STATUS_IS_EOF(rv)) {
                break;
            }
            else if (rv != APR_SUCCESS) {
                exit(3);
            }
        }
        else if (pollret == APR_TIMEUP) {
            *buf = 0;   
            nRead = 0;
        }
        else {
            fprintf(stderr, "Unable to poll stdin\n");
            exit(5);
        }

before the final "else" should be a check for EINTR and a "continue;" used to cause the call to apr_poll() to just be retried in that case:

        else if (pollret == APR_TIMEUP) {
            *buf = 0;   
            nRead = 0;
        }
        else if (pollret == APR_EINTR) {   /* <========== */
            continue;
        }
        else {
            fprintf(stderr, "Unable to poll stdin\n");
            exit(5);
        }

There may be other approaches (eg ignore SIGCHLD).
Comment 1 Joe Orton 2018-04-09 09:45:18 UTC
We should ignore SIGCHLD already - can you get strace output or similar?

        case 'p':
            config.postrotate_prog = opt_arg;
#ifdef SIGCHLD
            /* Prevent creation of zombies (on modern Unix systems). */
            apr_signal(SIGCHLD, SIG_IGN);
#endif
            break;