Day 43 of 60: Multiple queues, multiple queue runners (pt 3)

It's definitely a bug.

Specifically, in the default case, and contrary to the documentation, sendmail does not run one queue runner for every queue directory. It runs precisely one. I brought this up on the Sendmail mailing list, The most recent message in that discussion (at the time of writing) follows.

From: Nik Clayton
Subject: Re: Queue runners and multiple queue dirs. Doc bug or sendmail bug?

John Beck wrote:
Nik Clayton wrote:
I take this to mean that if you have configured five queue directories (e.g., /var/spool/mqueue/qdir00 through /var/spool/mqueue/qdir04) then a queue run will create 5 processes, one for each of the queue directories, unless the -v flag is given, in which case only one queue running process is created.

A logical conclusion based on the op guide text.

I've taken a look at the code.

sendmail/queue.c:makeworkgroups() has this code (comments elided)

#line 7540

if (NumQueue == 1 && strcmp(Queue[0]->qg_name, "mqueue") == 0)
NumWorkGroups = 1;
WorkGrp[0].wg_numqgrp = 1;
WorkGrp[0].wg_qgs =
(QUEUEGRP **) xalloc(sizeof(QUEUEGRP *));
WorkGrp[0].wg_qgs[0] = Queue[0];
if (MaxQueueChildren > 0 &&
Queue[0]->qg_numqueues > MaxQueueChildren)
WorkGrp[0].wg_runners = MaxQueueChildren;
WorkGrp[0].wg_runners = Queue[0]->qg_numqueues;

Queue[0]->qg_wgrp = 0;

/* ... */

I've instrumented that with some printf()s, and the body of the first if() is being executed (ie, NumQueue == 1, and Queue[0]->qg_name == "mqueue").

Just before the second if() statement, MaxQueueChildren == 0, and Queue[0]->qg_numqueues == 0.

This results in the second branch being taken, so WorkGrp[0].wg_runners is set to Queue[0]->qg_numqueues, which is 0.

Doing a bit more digging, it looks like qg_numqueues is is incremented in queue.c:multiqueue_cache(), line 6198. But makeworkgroups() is called long before multiqueue_cache() is called. So qg_numqueues is always going to be 0 when makeworkgroups() is called.


  calls makeworkgroups() # on line 1310

  calls queue.c:setup_queues() # on line 1870
    calls queue.c:multiqueue_cache()

I think this is a bug.


End of message

I brought this up in the comp.mail.sendmail newsgroup too, in this thread. The consensus there was that this was also a bug, with Per Hedeland writing:

Yes, it's definitely broken - the 8.10/8.11 backward compatibility code (in queue.c/makeworkgroups()) that is supposed to set up the number of queue runners based on the number of queues (i.e. directories) in the "mqueue" group is run long before the code (in queue.c/setup_queues()) that figures out how many directories there are...

which matches my findings. Per was less convinced about the seriousness of this though.

Anyway, the problem's been reported to Sendmail. My next round of tests are going to look at whether persistent queue directories fare any better. More news soon.

No comments:

Post a Comment