1

I have written a systemd script mqtt.service which is in /home/root directory

This is my mqtt.service script :

#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.
[Unit]
Description=mqtt

DefaultDependencies=no
After=xdk-daemon.service


[Service]

Restart=always
RestartSec=10
ExecStart=/bin/sh /home/root/mosquitto-1.4/mqtt_start.sh



[Install]

WantedBy=multi-user.target

And this is the content of mqtt_start.sh

#!/bin/sh
/home/root/mosquitto-1.4/src/mosquitto -c /home/root/mosquitto-1.4/mosquitto.conf -d -p 1885 > /dev/null 2>&1

If I paste the line :

/home/root/mosquitto-1.4/src/mosquitto -c /home/root/mosquitto-1.4/mosquitto.conf -d -p 1885

into terminal, the mqtt broker starts normally But here I am not able to start it

I did

$ systemctl enable /home/root/mqtt.service
$ systemctl status mqtt.service
● mqtt.service - mqtt
   Loaded: loaded (/home/root/mqtt.service; enabled)
   Active: failed (Result: resources) since Mon 2015-04-06 10:42:48 UTC; 24s ago
 Main PID: 677 (code=exited, status=0/SUCCESS)

Apr 06 10:42:39 edison sh[677]: 1428316959: Warning: Mosquitto should not be run as root/administrator.
Apr 06 10:42:48 edison systemd[1]: mqtt.service holdoff time over, scheduling restart.
Apr 06 10:42:48 edison systemd[1]: mqtt.service failed to schedule restart job: Unit mqtt.service failed to load: No such file or directory.
Apr 06 10:42:48 edison systemd[1]: Unit mqtt.service entered failed state.

Let me know where I have mistaken.

EDIT :

after I reboot I did:

systemctl status mqtt.service and result :

● mqtt.service
   Loaded: not-found (Reason: No such file or directory)
   Active: inactive (dead)
Wieland
  • 6,489

1 Answers1

3

Your systemd service unit is defaulting to Type=simple but your wrapper script is using the --daemon option. That is a readiness protocol mismatch. Readiness protocol mismatches cause services not to start correctly, or (more usually) to be (mis-)diagnosed by systemd as failing.

The latter is happening here. Because you've overengineered your system, your dæmon is unnecessarily forking twice over, and the wrong process is the actual dæmon process. Also, you are needlessly duplicating systemd service unit functionality in your wrapper script.

Get rid of the wrapper shell script entirely, and write your service unit like this:

[Unit]
Description=Mosquitto MQTT Broker
Documentation=man:mosquitto(8)
Documentation=man:mosquitto.conf(5)
ConditionPathExists=/home/root/mosquitto-1.4/mosquitto.conf
After=xdk-daemon.service

[Service]
ExecStart=/home/root/mosquitto-1.4/src/mosquitto -p 1885 -c /home/root/mosquitto-1.4/mosquitto.conf
ExecReload=/bin/kill -HUP $MAINPID
User=mosquitto
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target

Notice that:

  • You do not need the --daemon option. The broker is already daemonized when systemd runs it.
  • You should not use the --daemon option. Mosquitto does not speak the forking readiness protocol, since it is not actually ready after the fork-and-exit. (We live in hope of people one day writing programs like this such that they can inherit their listening sockets and thus be socket-activatable.)
  • You do not need to fiddle around with standard output and error in a wrapper script. systemd will handle a dæmon's standard output and error. They are configurable in the service unit file if really necessary, but that does not seem necessary at all for this program.
  • Since the correct process, identifiable by systemd, is now the dæmon process, systemctl reload mqtt.service can now send a signal to the right place, and work.
  • systemd itself will invoke the broker as user mosquitto; so you need to make sure that a user account by that name exists, with the requisite access rights. Notice the warning in your log.
  • The systemd folk recommend on-failure as the restart policy over always.
  • One should not set DefaultDependencies to false unless one's dæmon is actually capable of running very early in the boot process and late in the shutdown process, which is usually not the case for most things. The default service unit dependencies are appropriate for this sort of dæmon.
JdeBP
  • 68,745
  • Thank you friend. It worked. Can you please let me know where I can get all the details how to properly write scripts like that and any tutorials and complete usage of all the parameters written in any place? systemd man page is kind of messy : http://www.freedesktop.org/software/systemd/man/systemd.service.html can you please give me any link that explains neat and clean? It will be very helpful for me – ninja.stop Apr 08 '15 at 05:34
  • I have created a service and type is forking but it is exiting after a while and restarting the service again the error log is : ● mqtt_to_REST.service - TCUP MQTT to RESTful connector Loaded: loaded (/lib/systemd/system/mqtt_to_REST.service; enabled) Active: activating (auto-restart) (Result: timeout) since Wed 2015-04-08 12:19:18 UTC; 648ms ago Process: 289 ExecStart=/usr/bin/sim (code=killed, signal=TERM)

    Apr 08 12:19:18 edison systemd[1]: Failed to start TCUP MQTT to RESTful connector. Apr 08 12:19:18 edison systemd[1]: Unit mqtt_to_REST.service entered failed state.

    – ninja.stop Apr 08 '15 at 12:21