RE: [Exim] Frozen deferred messages

Top Page
Delete this message
Reply to this message
Author: Mike Bethune
Date:  
To: exim-users
Subject: RE: [Exim] Frozen deferred messages
> and a delivery process has done a re-exec on the Exim binary, so the
> signal handlers should have all been reset.


maybe why I noticed this starting in 4.24:
    Exim version 4.24
    -----------------
     6. When the daemon running as "exim" started a queue runner, it always
        re-executed Exim in the spun-off process. This is a waste of effort when
        deliver_drop_privilege is set. The new process now just calls the
        queue-runner function directly.


If deliver_drop_privilege is set and we already dropped privilege (or never had any :), then the signal handlers don't get set up since they are reset in this child (see below snip from daemon.c).
Probably the signal handlers should be set up again before the queue_run() or they shouldn't be reset here? (I'd like to not have to re-exec since it is a waste).
Thanks,


      if ((pid = fork()) == 0)
        {
        int sk;
        DEBUG(D_any) debug_printf("Starting queue-runner: pid %d\n",
          (int)getpid());


        /* Close any open listening sockets in the child */


        for (sk = 0; sk < listen_socket_count; sk++) close(listen_sockets[sk]);


        /* Reset signals in the child */


        signal(SIGALRM, SIG_DFL);
        signal(SIGHUP,  SIG_DFL);
        signal(SIGCHLD, SIG_DFL);


        /* Re-exec if privilege has been given up, unless deliver_drop_
        privilege is set. */


        if (geteuid() != root_uid && !deliver_drop_privilege)
          {
          uschar opt[8];
          uschar *p = opt;


          *p++ = '-';
          *p++ = 'q';
          if (queue_2stage) *p++ = 'q';
          if (queue_run_first_delivery) *p++ = 'i';
          if (queue_run_force) *p++ = 'f';
          if (deliver_force_thaw) *p++ = 'f';
          if (queue_run_local) *p++ = 'l';
          *p = 0;


          (void)child_exec_exim(CEE_EXEC_PANIC, FALSE, NULL, TRUE, 1, opt);
          /* Control never returns here. */
          }


        /* No need to re-exec */


        queue_run(NULL, NULL, FALSE);
        _exit(EXIT_SUCCESS);
        }