105 lines
4.5 KiB
Diff
105 lines
4.5 KiB
Diff
From: Michael Tokarev <mjt@tls.msk.ru>
|
|
Subject: re-run postfix start through systemd
|
|
Date: Fri, 13 Dec 2024 21:13:34 +0300
|
|
|
|
When `postfix start' (or `postmulti start') command is run from command line,
|
|
postfix instance is started outside a session manager such as systemd.
|
|
This is fine for traditional init-based systems, but systemd has a notion of
|
|
a service which it tracks. Postfix instance started this way line becomes
|
|
"orphaned", run within user session which started it, confuses session manager
|
|
and other tools which expects mail service to be running.
|
|
|
|
Systemd exports $INVOCATION_ID when it starts a service. This variable can
|
|
be used as a (weak) indicator that we're running under systemd, so if it
|
|
is set, just run `master' process the usual way. But if it is not set,
|
|
and the system is running under systemd (/run/systemd/system is present),
|
|
instead of running postfix master process directly, we run the systemd
|
|
service which corresponds to this instance. Which, in turn, should re-run
|
|
the same `postfix' command and control will come back to this same place,
|
|
where we now start `master' the usual way.
|
|
|
|
Only the regular `start' command is handled. All other commands, including
|
|
`start-fg', are not modified.
|
|
|
|
The service being started is either the main/default postfix instance, if
|
|
config_directory is /etc/postfix. Or, the service is assumed to be a path
|
|
unit after /etc/postfix-, like config directory being /etc/postfix-foo for
|
|
postfix@foo.service, or postfix@foo%2dbar-baz for config directory being
|
|
/etc/postfix-foo-bar/baz (see man:systemd-escape for details on the naming).
|
|
Other config directories (not prefixed with /etc/postfix-) are not rescheduled
|
|
through systemd.
|
|
|
|
Currently $MAIL_VERBOSE and $MAIL_DEBUG are not passed through to the master
|
|
process started through systemd. It can be implemented if needed.
|
|
|
|
diff --git a/src/postfix/postfix.c b/src/postfix/postfix.c
|
|
--- a/src/postfix/postfix.c
|
|
+++ b/src/postfix/postfix.c
|
|
@@ -218,2 +218,4 @@
|
|
/* environment overrides.
|
|
+/* On a Debian system, this command additionally imports \fBINVOCATION_ID\fR
|
|
+/* variable (used to detect \fBsystemd\fR(1) presence).
|
|
/* .IP "\fBsyslog_facility (mail)\fR"
|
|
@@ -577,2 +579,3 @@ int main(int argc, char **argv)
|
|
import_env = mail_parm_split(VAR_IMPORT_ENVIRON, var_import_environ);
|
|
+ argv_add(import_env, "INVOCATION_ID", NULL); /* systemd, debian-specific */
|
|
clean_env(import_env->argv);
|
|
diff --git a/src/postmulti/postmulti.c b/src/postmulti/postmulti.c
|
|
--- a/src/postmulti/postmulti.c
|
|
+++ b/src/postmulti/postmulti.c
|
|
@@ -331,2 +331,4 @@
|
|
/* environment overrides.
|
|
+/* On a Debian system, this command additionally imports \fBINVOCATION_ID\fR
|
|
+/* variable (used to detect \fBsystemd\fR(1) presence).
|
|
/* .IP "\fBmulti_instance_directories (empty)\fR"
|
|
@@ -1220,2 +1222,3 @@ static void export_helper_environment(INSTANCE *target, int export_flags)
|
|
import_env = mail_parm_split(VAR_IMPORT_ENVIRON, var_import_environ);
|
|
+ argv_add(import_env, "INVOCATION_ID", NULL); /* systemd, debian-specific */
|
|
clean_env(import_env->argv);
|
|
diff --git a/conf/postfix-script b/conf/postfix-script
|
|
--- a/conf/postfix-script
|
|
+++ b/conf/postfix-script
|
|
@@ -133,4 +133,17 @@ start|start-fg)
|
|
exit 1
|
|
}
|
|
+
|
|
+ if [ -f $queue_directory/debian-systemd-start ] # debian-specific
|
|
+ then # same as in debian-systemd-start patch, keep it here so old systemd unit works
|
|
+ rm -f $queue_directory/debian-systemd-start #XXX read MAIL_DEBUG & MAIL_VERBOSE
|
|
+ rm -f $queue_directory/quick-start
|
|
+ [ -d /run/systemd/system ] && [ -n "$INVOCATION_ID" ] || {
|
|
+ $FATAL "the Postfix mail system is started through systemd but not under systemd?"
|
|
+ exit 1
|
|
+ }
|
|
+ $daemon_directory/master -w
|
|
+ exit
|
|
+ fi
|
|
+
|
|
if [ -f $queue_directory/quick-start ]
|
|
then
|
|
@@ -144,4 +160,25 @@ start|start-fg)
|
|
$daemon_directory/postfix-script check-warn
|
|
fi
|
|
+
|
|
+ if [ -d /run/systemd/system ] && [ ! "$INVOCATION_ID" ] && # debian-specific
|
|
+ [ $1 = start ]
|
|
+ then
|
|
+ srv=$(systemd-escape -p $config_directory) || exit 1
|
|
+ case "$srv" in
|
|
+ (etc-postfix) srv=postfix.service ;;
|
|
+ (etc-postfix\\x2d*) srv=postfix@${srv#*\\x2d}.service ;;
|
|
+ (*) srv= ;;
|
|
+ esac
|
|
+ if [ -n "$srv" ]; then
|
|
+ $INFO "redirecting the Postfix mail system startup to systemd $srv" || exit 1
|
|
+ touch $queue_directory/debian-systemd-start #XXX write MAIL_DEBUG & MAIL_VERBOSE
|
|
+ systemctl start $srv || {
|
|
+ $FATAL "mail system startup through systemd failed"
|
|
+ exit 1
|
|
+ }
|
|
+ exit 0
|
|
+ fi
|
|
+ fi
|
|
+
|
|
$INFO starting the Postfix mail system || exit 1
|
|
case $1 in
|