Package: mimedefang

On Debian/Ubuntu with systemd, restarting MIMEDefang does not work properly.

This was discussed upstream:
https://lists.roaringpenguin.com/pipermail/mimedefang/2017-September/038113.html

The problem is that systemd implements a restart as a stop followed by a
start. In the systemd design, the ExecStop action must wait for the
service to actually stop:
https://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStop=

Since the mimedefang package does not ship native systemd units, its
units are created by systemd-sysv-generator, which does this (see
/run/systemd/generator.late/mimedefang.service):
  ExecStart=/etc/init.d/mimedefang start
  ExecStop=/etc/init.d/mimedefang stop
  ExecReload=/etc/init.d/mimedefang reload

The /etc/init.d/mimedefang script does not wait on the stop action. To
get that, you need to pass a second argument of "wait".

There are three possible fixes. I recommend the third:

1) Make the init script always wait on stop.

OR

2) Copy the generated systemd unit into the package, make minimal
changes, and change ExecStop to specify wait:
  -ExecStop=/etc/init.d/mimedefang stop
  +ExecStop=/etc/init.d/mimedefang stop wait

OR

3) Provide fully native systemd units.

I have attached fully split, native, Type=simple (not forking) unit
files, which I have tested on Ubuntu 16.04 and am running in production
on multiple machines.

They honor the settings in /etc/default/mimedefang. This includes the
MX_USER setting (i.e. systemd does not directly control the service user).

They are configured such that if you do start/stop/reload/restart the
mimedefang service (as before), the actions propagate to
mimedefang-multiplexor appropriately.

Note that mimedefang-multiplexor prior to 2.82 has a bug where it exits
with status 1 on a SIGTERM. Accordingly, I have this in
mimedefang-multiplexor.service:
  # This can be removed with MIMEDefang 2.82:
  SuccessExitStatus=1

-- 
Richard

[Unit]
Description=MIMEDefang E-mail Filter
Documentation=man:mimedefang(8)
Before=multi-user.target
Before=postfix.service
Before=sendmail.service
After=remote-fs.target
After=systemd-journald-dev-log.socket
BindsTo=mimedefang-multiplexor.service
After=mimedefang-multiplexor.service
PropagatesReloadTo=mimedefang-multiplexor.service

[Service]
Type=simple
Restart=on-failure
TimeoutStopSec=30s
# LC_ALL=C may not be necessary for mimedefang, but it is for
# mimedefang-multiplexor, so upstream prefers it here also to be consistent.
Environment=LC_ALL=C 
MX_SOCKET=/var/spool/MIMEDefang/mimedefang-multiplexor.sock MX_USER=defang 
SOCKET=/var/spool/MIMEDefang/mimedefang.sock
EnvironmentFile=-/etc/default/mimedefang
ExecStartPre=/bin/rm -f $SOCKET
ExecStart=/bin/sh -c 'exec /usr/bin/mimedefang -D \
    `[ -n "$LOOPBACK_RESERVED_CONNECTIONS" ] && echo "-R 
$LOOPBACK_RESERVED_CONNECTIONS"` \
    -m $MX_SOCKET \
    `[ -n "$SPOOLDIR" ] && echo "-z $SPOOLDIR"` \
    `[ -n "$MX_USER" ] && echo "-U $MX_USER"` \
    `[ -n "$SYSLOG_FACILITY" ] && echo "-S $SYSLOG_FACILITY"` \
    `[ "$MX_RELAY_CHECK" = "yes" ] && echo "-r"` \
    `[ "$MX_HELO_CHECK" = "yes" ] && echo "-H"` \
    `[ "$MX_SENDER_CHECK" = "yes" ] && echo "-s"` \
    `[ "$MX_RECIPIENT_CHECK" = "yes" ] && echo "-t"` \
    `[ "$KEEP_FAILED_DIRECTORIES" = "yes" ] && echo "-k"` \
    `[ "$MD_EXTRA" != "" ] && echo $MD_EXTRA` \
    `[ "$MD_SKIP_BAD_RCPTS" = "yes" ] && echo "-N"` \
    "`[ -n "$X_SCANNED_BY" ] && \
      ( [ "$X_SCANNED_BY" = "-" ] && \
        echo "-X" || echo "-x$X_SCANNED_BY" )`" \
    `[ "$MD_ALLOW_GROUP_ACCESS" = "yes" ] && echo "-G"` \
    `[ "$ALLOW_NEW_CONNECTIONS_TO_QUEUE" = "yes" ] && echo "-q"` \
    -p $SOCKET'
ExecStopPost=/bin/rm -f $SOCKET
# Make this service eligible for a reload, so we can propagate it to
# mimedefang-multiplexor.service.
ExecReload=/bin/true

[Install]
WantedBy=multi-user.target
[Unit]
Description=MIMEDefang E-mail Filter (Multiplexor)
Documentation=man:mimedefang-multiplexor(8)
After=remote-fs.target
After=systemd-journald-dev-log.socket
PartOf=mimedefang.service

[Service]
Type=simple
Restart=on-failure
TimeoutStopSec=30s
KillMode=mixed
# Locale should be set to "C" for generating valid date headers
Environment=LC_ALL=C MX_BUSY=600 MX_LOG=yes MX_MAXIMUM=10 MX_MINIMUM=2 
MX_SOCKET=/var/spool/MIMEDefang/mimedefang-multiplexor.sock MX_USER=defang
EnvironmentFile=-/etc/default/mimedefang
# This can be removed with MIMEDefang 2.82:
SuccessExitStatus=1
ExecStart=/bin/sh -c 'HOME=${SPOOLDIR:=/var/spool/MIMEDefang} \
    exec /usr/bin/mimedefang-multiplexor -D \
    `[ "$MX_EMBED_PERL" = "yes" ] && echo "-E"` \
    `[ -n "$SPOOLDIR" ] && echo "-z $SPOOLDIR"` \
    `[ -n "$FILTER" ] && echo "-f $FILTER"` \
    `[ -n "$SYSLOG_FACILITY" ] && echo "-S $SYSLOG_FACILITY"` \
    `[ -n "$SUBFILTER" ] && echo "-F $SUBFILTER"` \
    `[ -n "$MX_MINIMUM" ] && echo "-m $MX_MINIMUM"` \
    `[ -n "$MX_MAXIMUM" ] && echo "-x $MX_MAXIMUM"` \
    `[ -n "$MX_MAP_SOCKET" ] && echo "-N $MX_MAP_SOCKET"` \
    `[ -n "$MX_LOG_SLAVE_STATUS_INTERVAL" ] && echo "-L 
$MX_LOG_SLAVE_STATUS_INTERVAL"` \
    `[ -n "$MX_USER" ] && echo "-U $MX_USER"` \
    `[ -n "$MX_IDLE" ] && echo "-i $MX_IDLE"` \
    `[ -n "$MX_BUSY" ] && echo "-b $MX_BUSY"` \
    `[ -n "$MX_REQUESTS" ] && echo "-r $MX_REQUESTS"` \
    `[ -n "$MX_SLAVE_DELAY" ] && echo "-w $MX_SLAVE_DELAY"` \
    `[ -n "$MX_MIN_SLAVE_DELAY" ] && echo "-W $MX_MIN_SLAVE_DELAY"` \
    `[ -n "$MX_MAX_RSS" ] && echo "-R $MX_MAX_RSS"` \
    `[ -n "$MX_MAX_AS" ] && echo "-M $MX_MAX_AS"` \
    `[ "$MX_LOG" = "yes" ] && echo "-l"` \
    `[ "$MX_STATS" = "yes" ] && echo "-t /var/log/mimedefang/stats"` \
    `[ "$MX_STATS" = "yes" -a "$MX_FLUSH_STATS" = "yes" ] && echo "-u"` \
    `[ "$MX_STATS_SYSLOG" = "yes" ] && echo "-T"` \
    `[ "$MD_ALLOW_GROUP_ACCESS" = "yes" ] && echo "-G"` \
    `[ "$MX_STATUS_UPDATES" = "yes" ] && echo "-Z"` \
    `[ -n "$MX_QUEUE_SIZE" ] && echo "-q $MX_QUEUE_SIZE"` \
    `[ -n "$MX_QUEUE_TIMEOUT" ] && echo "-Q $MX_QUEUE_TIMEOUT"` \
    `[ -n "$MX_NOTIFIER" ] && echo "-O $MX_NOTIFIER"` \
    `[ -n "$MX_RECIPOK_PERDOMAIN_LIMIT" ] && echo "-y 
$MX_RECIPOK_PERDOMAIN_LIMIT"` \
    -s $MX_SOCKET'
ExecStartPre=/bin/rm -f $MX_SOCKET
ExecStopPost=/bin/rm -f $MX_SOCKET
ExecReload=/bin/kill -INT $MAINPID

Reply via email to