1

The problem I am trying to solve is to start and stop a listener service when a custom service is started or stopped. The specific case is IBM MQ V8 on RHEL7 but the same principle should apply to e.g. Oracle DB and listener as well.

The listener service should start after and stop before the main service.

I'll post my own systemd unit files as an answer but I'm looking for additional replies to improve my answer.

1

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.

  • Thank you for the example systemd unit files, I am just starting to look into this topic instead of older init.d style start/stop scripts. Why not let queue manager start the listener with a LISTENER object? This is by far the most common way of doing this that I have seen, is there a reason that you want the listener to start before the queue manager? – JoshMc Jul 13 '17 at 18:04
  • Hi @JoshMc, I hope this can help you get started. I believe I later did change the solution to use a LISTENER object. At the time I wrote this I was rewriting the init scripts of an older version of MQ and simply re-used the logic. I left the answer to get suggestions to improve it and to serve as an example for others. – Bram Jul 13 '17 at 18:14
  • Thank you for the quick response and for providing the examples. – JoshMc Jul 13 '17 at 18:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.