The main service /etc/systemd/system/qm@.service is defined as:
[Unit]
Description=IBM MQ V8 QM %i
Requires=qm-listener@%i.service
Before=qm-listener@%i.service
[Service]
Type=forking
User=mqm
Group=mqm
ExecStart=/opt/mqm/bin/strmqm %i
LimitNOFILE=10240
LimitNPROC=4096
ExecStop=/opt/mqm/bin/endmqm %i
KillMode=none
[Install]
WantedBy=multi-user.target
The listener service/etc/systemd/system/qm-listener@.service is defined as:
[Unit]
Description=IBM MQ V8 %i Listener
PartOf=qm@%i.service
[Service]
Type=simple
User=mqm
Group=mqm
ExecStart=/opt/mqm/bin/runmqlsr -t TCP -m %i
LimitNOFILE=10240
LimitNPROC=4096
ExecStop=/opt/mqm/bin/endmqlsr -m %i
KillMode=none
[Install]
WantedBy=multi-user.target
I am using the template function so that a single unit file can be used to manage multiple Queue Managers.
The actual command to start queue manager QM1 is
$ sudo systemctl start qm@QM1
This will instantiate and start a service qm@QM1 as well as qm-listener@QM1
Some additional notes I learned while creating this:
- Type is forking for the qm@.service because the command strmqm exits after forking the actual qmgr process for the qm-listener@.service the type is simple because the runmqlsr process is the main process
- KillMode is none is required because systemd by default sends a SIGTERM to all processes in the cgroup after executing the ExecStop command. MQ throws an error when it receives a SIGTERM.
- no PIDfile is specified because MQ does not generate one and if specified systemd considers the startup to fail
- LimitNOFILE and LimitNPROC added because the limits defined in /etc/security/limits.conf or /etc/security/limits.d/*conf are only applied to pam login sessions and services started by systemd do not run in a pam login session.
- PartOf in the listener ensures it is stopped when the correspondig qm service is stopped
What I'm not sure about is whether the PartOf option is the right choice.