Systemctl (again)

Home » CentOS » Systemctl (again)
CentOS 13 Comments

I’ve been trying to get the timidity system running as a daemon. I
wrote the following init script:

#!/bin/sh
#
# timidity
#
### BEGIN INIT INFO
# Provides: timidity
# Required-Start:
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Add and remove timidity
# Description:
### END INIT INFO

. /etc/rc.d/init.d/functions

RETVAL=0
PROG=timidity EXEC=/bin/$PROG
PIDFILE=/var/run/timidity.pid

function start {
[[ -x $EXEC ]] || exit 5
echo -n “Starting $PROG: ”
$EXEC -iAD
RETVAL=$?
echo
return $RETVAL
}

function stop {
echo -n “Stopping $PROG: ”
killproc $EXEC -TERM
RETVAL=$?
echo
return $RETVAL
}

case “$1″ in
start) start
RETVAL=$?
;;
stop) stop
RETVAL=$?
;;
status)
status $PROG
RETVAL=$?
;;
restart)
stop
start
;;
reload)
stop
start
;;
*)
echo $”Usage: $prog {start|stop|status|restart|reload}”
exit 1
esac exit $RETVAL

When run through systemctl during startup it fails:

[root@tamar init.d]# systemctl status timidity timidity.service – LSB: Add and remove timidity
Loaded: loaded (/etc/rc.d/init.d/timidity)
Active: active (exited) since Thu …
Process: 784 ExecStart=/etc/rc.d/init.d/timidity start
(code=exited, status=0/SUCCESS)

… Starting LSB: Add and remove timidity…
… Starting timidity:
… jack_client_new: deprecated
… Started LSB: Add and remove timidity.
… Cannot connect to server socket err = No such file or directory
… Cannot connect to server request channel
… jack server is not running or cannot be started
… Couldn’t open output device

But when run directly is works fine:

[root@tamar init.d]# ./timidity start Starting timidity:
TiMidity starting in ALSA server mode Opening sequencer port: 128:0 128:1 128:2 128:3

If I use # service timidity start it also fails.

I _think_ that what is happening is that systemctl is stripping off the switch. I’ve spent a couple of hours searching for any links or explanation and got nowhere. I even knocked up a script to try and separate the two parts:
#!/bin/sh cd /etc/init.d
./timidity start but to no avail.

If there is a simple fix could someone point me there, if it’s complex don’t bother, I only need the daemon when running MIDI and can start it by hand.
—–BEGIN PGP SIGNATURE—

13 thoughts on - Systemctl (again)

  • SELinux certainly was causing fun and games. I copied your suggestion to /etc/systemd/user/timidity.service (mode 750) but it’s still not happy:

    [root@tamar user]# systemctl status timidity timidity.service
    Loaded: not-found (Reason: No such file or directory)
    Active: failed (Result: exit-code) since Th…

    … Starting LSB: Add and remove timidity…
    … timidity.service: control process exited, code=exited status 3
    … Failed to start LSB: Add and remove timidity.
    … Unit timidity.service entered failed state.
    … Stopped timidity.service.

    I’ve wasted way too much time on this, I’ve put it in my .profile. The weirdness of systemctl will have to wait!

    Thanks all

    —–BEGIN PGP SIGNATURE—

  • status 3

    For the record based on your email chain this issue has little to nothing to do with systemd or systemctl but rather a poor script for some reason that I haven’t troubleshooted in detail.

    Remember you should never call /etc/init.d/script even on el6 as your environment and profile will pollute the scripts environment leading to inconsistent behaviour.

    From the above it’s clear after putting in place the service unit you did not do systemctl daemon-reload to pick up the new unit – hence the clear error Not Found.

  • Inline

    Sorry if that sounded more brusque than it should. I’ve got a filthy cold, it was 20 to midnight and I’ve been chasing this problem for a couple of days. Frustration is directed at the implementers, not those tying to help.

    The script was a minor alteration to an existing RH supplied script, probably originally from 5.3. Poor standard noted with amusement!

    I tried using the service mechanism, just as for the last 16 years, but it continued to fail, apparently stripping off the -iAD, which is rather critical; -iA sets up an ALSA interface and the D modifier tells it to daemonise, without them it tries to run in the foreground. directly executing is debugging mode, until it starts to work and then you can look for differences. Mind you, making any significant changes to root’s environment and profile would be asking for trouble IMHO.

    Nope, wasn’t aware that I had to. You don’t need to do any such thing with init scripts. :-o

    Anyhow, as I said, thanks for the input, but I moved it to my .profile so that I can get on with something useful. I’m sure in time I’ll wade through the manuals and adapt, but I was just trying to be positive and adapt to the new regime. My error!

    Since you appear to be a systemd guru, is there any easy way to spin off a system session that could call in simple init-type scripts?
    Just an ability to execute a simple script at system startup would be helpful. I (and I would guess many others) would find it a useful transition. Don’t worry about how to code up the driver, it’s trivial.

    Thanks.
    —–BEGIN PGP SIGNATURE—

  • Further to my earlier post. I must confess to occasionally getting to be a bit stubborn, and in this case didn’t want to be beaten by Poettering. I re-installed your script, modifying some fields in what I hope was the appropriate manner:
    # ls -l /etc/systemd/user total 4
    -rwxr-x—. 1 root root 246 Apr 3 21:21 timidity.service
    # cat /etc/systemd/user/timidity.service
    [Unit]
    Description=timidity daemon

    [Service]
    PIDFile=/var/run/timidity.pid User=jmr Group=users WorkingDirectory=/home/jmr ExecStart=/usr/bin/timidity -iAD
    ExecReload=/bin/kill -s HUP $MAINPID
    ExecStop=/bin/kill -s TERM $MAINPID
    PrivateTmp=true

    jmr:users is my account, it will do for the moment; at least I know
    /home/jmr is usable! I changed the ExecStart to use
    /usr/bin/timidity, that is the output from command -v timidity.

    # systemctl daemon-reload
    # echo $?
    0
    # systemctl start timidity Failed to issue method call: Unit timidity.service failed to load: No such file or directory.
    # setenforce 0
    # getenforce Permissive
    # systemctl start timidity Failed to issue method call: Unit timidity.service failed to load: No such file or directory.
    # systemctl daemon-reload
    # systemctl start timidity Failed to issue method call: Unit timidity.service failed to load: No such file or directory.

    I then rebooted the system:
    # systemctl status timidity timidity.service
    Loaded: not-found (Reason: No such file or directory)
    Active: inactive (dead)

    # systemctl daemon-reload
    # echo $?
    0
    # systemctl start timidity Failed to issue method call: Unit timidity.service failed to load: No such file or directory.

    I checked all logs which had been modified since the reboot and there was no reference to timidity in any of them, which does seem odd if the startup is failing.

    Any pointers as to where to go next? I did briefly think of running systemctl with sh -vx, but but as I expected it is an image! Back to square 1.

    Fortunately this is my home machine, so I am free to pull it to bits to try and find out what is happening. My next thought is to add dummy services in /etc/systemd/user, possibly pulling one out of the system directory to prove it is working. Poettering has certainly set me an interesting puzzle.

    Thanks. Martin
    —–BEGIN PGP SIGNATURE—

  • Yet more information:

    As a test I moved the link
    /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service into
    /etc/systemd/user and reran systemctl daemon-reload. I then rebooted.

    # ls -l /etc/systemd/user total 4
    lrwxrwxrwx. 1 root root 41 Jul 27 2014
    dbus-org.fedoraproject.FirewallD1.service ->
    /usr/lib/systemd/system/firewalld.service
    -rwxr-x—. 1 root root 246 Apr 3 21:21 timidity.service
    # systemctl status dbus-org.fedoraproject.FirewallD1.service dbus-org.fedoraproject.FirewallD1.service
    Loaded: not-found (Reason: No such file or directory)
    Active: inactive (dead)

    # systemctl status timidity timidity.service
    Loaded: not-found (Reason: No such file or directory)
    Active: inactive (dead)

    So it’s starting to look like a distro problem. Next I moved both the Firewall service link and the timidity service file into
    /etc/systemd/system:

    # systemctl daemon-reload
    # echo $?
    0

    and rebooted.

    # systemctl status dbus-org.fedoraproject.FirewallD1.service firewalld.service – firewalld – dynamic firewall daemon
    Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled)
    Active: active (running) since Fri 2015-04-03 22:50:50 …
    Main PID: 785 (firewalld)
    CGroup: /system.slice/firewalld.service
    └─785 /usr/bin/python -Es /usr/sbin/firewalld …

    … Starting firewalld – dynamic firewall daemon…
    … Started firewalld – dynamic firewall daemon.
    # systemctl status timidity timidity.service – timidity daemon
    Loaded: loaded (/etc/systemd/system/timidity.service; static)
    Active: inactive (dead)

    Which is progress, but where to I’m not sure.

    # ls -ld system user drwxr-xr-x. 14 root root 4096 Apr 3 22:48 system drwxr-xr-x. 2 root root 4096 Apr 3 22:48 user
    # getfacl system user
    # file: system
    # owner: root
    # group: root user::rwx group::r-x other::r-x

    # file: user
    # owner: root
    # group: root user::rwx group::r-x other::r-x

    Clearly there is a problem with my assumption about the default settings. systemd appears not to read the user directory without modification.

    Trying to enable it leads to:

    # systemctl enable timidity The unit files have no [Install] section. They are not meant to be enabled using systemctl. Possible reasons for having this kind of units are:
    1) A unit may be statically enabled by being symlinked from another unit’s .wants/ or .requires/ directory.
    2) A unit’s purpose may be to act as a helper for some other unit which has a requirement dependency on it.
    3) A unit may be started when needed via activation (socket, path, timer, D-Bus, udev, scripted systemctl call, …).

    Ah well, bed time. I’ll tussle with Poettering’s logic in the morning.
    —–BEGIN PGP SIGNATURE—–
    Version: GnuPG v2.0.22 (GNU/Linux)

    iQIcBAEBAgAGBQJVHw8xAAoJEAF3yXsqtyBlieQP/3to6d4gqWZ1HQkTvwKwgSBf Mg3GM6R+10E8skhHEuwAe8uX3ZznbO4F7NOMy3yRBSrL+y/fu6+U8To7T6wLvGKC
    kFbdCbWradLP31clWzVjJYVVYIUXTVpMC6u59L5IFbYzIB//KShYC7NxDAtQ17qG
    sbi82BuJRlXgF44cPnkv1LVX8OajUa6d2bppwrpZFNFQyAl3OUa7KY8rqe03kvWm AxAXtHB/E72rHGG7RpdvdwkOJ4FEyxMjh1rzilVBmpuZPLGzfjJhX5ColKvmq34N
    pABaBSFZeBQw/yk0KRt1eff/CBPR7pMTinxJPKuoVhbUXfJQ9yNcgXcWUg/R23+9
    DfJBYwSCAYqvdKwKx7V/1kuQD/INvQiO3NtCc9Ck4cPj1b6udCjsImof07smy7jn xe4q0mh4u7bx76gQQAq/4IQBBp5O8KkjK5oHt4gU2psqFLlSzvRen+fnqsDH2LaN
    HvjOAWlxS40a5+GAcXkIk9qG9kzAV6lyNvG/lPrSQHyeitjGwClAJTwHBfWI7l0e NuW216klW6VZP6Wm35nEAL7EZV4ADzLH2pqsOxB8dR7KdHAVq1Wwxe5XTi8cWJ8J
    s4c2vT6uVpthpzGSbdEMoQla/DVp+h56vl2fFeY5Fww2MhODu7CmkUI2P7pvgKXy icO1B4BtoxgV4dEXuHMK
    =v3W6
    —–END PGP SIGNATURE—–

  • Thats wierd. I’ve never had any problem with systemctl or systemd like that.

    Do you have your service file in the right place with the right permissions. here is the httpd service file as a reference.

    [CentOS@ipa ~]$ ls /usr/lib/systemd/system/httpd.service -l

    -rw-r–r–. 1 root root 694 Mar 12 14:57
    /usr/lib/systemd/system/httpd.service

    [CentOS@ipa ~]$ cat /usr/lib/systemd/system/httpd.service

    [Unit]

    Description=The Apache HTTP Server

    After=network.target remote-fs.target nss-lookup.target

    [Service]

    Type=notify

    EnvironmentFile=/etc/sysconfig/httpd

    ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND

    ExecReload=/usr/sbin/httpd $OPTIONS -k graceful

    ExecStop=/bin/kill -WINCH ${MAINPID}

    KillSignal=SIGCONT

    PrivateTmp=true

    [Install]

    WantedBy=multi-user.target

    CentOS mailing list CentOS@CentOS.org http://lists.CentOS.org/mailman/listinfo/CentOS

  • Thanks Andrew.

    —–BEGIN PGP SIGNATURE—–
    Version: GnuPG v2.0.22 (GNU/Linux)

    iQIcBAEBAgAGBQJVH+05AAoJEAF3yXsqtyBlDTUQAMJPiZpKiJsDPQ/LXAzBUb8M
    k2+qnFCuKuBT5JVzttBGbm9YiNzIrn5A0X1TP7mSzZhJMr4DX4LbRJfnuBYP7mm7
    vRBixpbCZ+/un6oEudtoVt7EuEvR/MENQYf/CVbZRGarG+9CS0fecjKLNi+G6ltZ
    ySe4t1wHtvaZ1ujMpN7w30++CbV1DPyF0yGNQvaf8yI6uGZSTSRDd0mQ/aRkLTw1
    peYW1pGBtagvltIbY3vjTneFJ5UB4yQymnvZuCCrujlsc0ccMaWCbgLEuxxxLWoQ
    Lx//TegR1OTdDjb2yk8VWMQuUQzh5hBssrH2q2dTp+mBql8Ws8zNHwe/WdczM6Ti llPpafWpe1ZUKNevnY3Fe2Tem3W5w3S4KumFeR9Xu6tBLlDRXoTssbN59EfVS4wg J03z4xfKsCqP2BrlHgi0C5qWdZGC+aU6oFrMCetCForhP10zhdkoQLGJy4UTWYMS
    ja29I0LHTjLAtaRdD7N8bsCf9bY3t29v5nqlmXtC5mWHwwDyv7MLftDw1X9aJElv I/rcKEGcKBGlSH3IafgzbcriVZwK90NcskcpJX366qJTMb0/pMjkgV2Iu3Ki7/Ex DKg5o5/NxxqiJQz2etAKvP9Xgkn5svlQCj2n3filwgC3l1ePpGoG+056396PI1dj FxEhkVUZgUnrioH6g6ds
    =4Q/J
    —–END PGP SIGNATURE—–

  • The process exited, so systemd thinks the service has exited. You have a
    ‘-D’ option, which probably means daemonize, but you haven’t set an appropriate Type declaration in the service file.

    If the service offers it, the best way to do simple services with systemd is with *foreground* options in ExecStart. Then set Type=simple. STDOUT/STDERR all goes to the journal, making it easier to see what happens if the service legitimately fails.

    Take a look at packaged files in /usr/lib/systemd/system – plenty of examples to work from.

    –Pete

  • Is $MAINPID defined in your pidfile?

    It sounds to me like only the ‘kill’ is exiting with a non-zero exit code because the variable is undefined.

  • This would be better served as the following to accomplish the immediate goal:

    cat > /etc/systemd/system/timidity.service <
    [Service]
    User=jmr Group=users WorkingDirectory=/home/jmr Type=forking ExecStart=/usr/bin/timidity -iAD
    EOF

    systemctl daemon-reload

    systemctl start timidity

    You don’t need to define an ExecStop and the type of the service should be forking as you are daemonising it – simple if you didn’t daemonise it (or skip type which has this as default).

    There is also no need to deal with the race condition mess that is a PID file with systemd as well… technically there is no need to mess with MAINPID in this scenario.

    This is a quite messy though as you’re running a ‘system service’ in the context of a regular user…. you were better off doing this within the user space as you started with.

    The reason that failed for you before is that you were making calls to systemctl without the –user option so it was trying to act in the system context.

    However a google of “timidity systemd” has the arch wiki within the first few results that has good information which results in a technically much nicer solution.

    https://wiki.archlinux.org/index.php/Timidity#Daemon

    Note the –global option which makes it start on a per user basis when the session for that user starts. Also note they don’t daemonise it as there is no real reason to with systemd controlling the process state.

    If you want to stop/start/restart within the context of the user session you should be doing systemctl –user start/stop/restart timidity

  • Points noted, I just took Andrew’s file and changed the bare minimum.

    It’s getting rather windozy though if proper background system stuff is moved into user space. Multiple definitions of the D: drive anyone? :-(

    Running as jmr is purely temporary, ideally I will create a timidity account for it, but for the present I just hacked Andrew’s script to ensure the user/group/directory worked.

    Right, so user is user added code then. I assumed it was for site-local service files.

    Thanks.

    It does need to be daemonised for frescobaldi to talk to it. The default (non-daemonised) way plays a file, if it is daemonised then it sets up ports to listen on. Hence the D modifier on the interface switch. I’ll be honest though, when scanning for CentOS solutions I
    would routinely ignore ArchLinix.

    No – I want it to start on boot and sit there like a good little daemon doing what it’s told.

    —–BEGIN PGP SIGNATURE—

  • And of course, that’s not at all what running systemd user services is about.

    Its possible to have systemd start up a separate systemd process for each user, to manage user-based services (such as your example), but run outside of your login session, with all the resource management/cgroups and logging features you get with systemd.

    I’m not really thrilled with the service, though. Since it operates outside of user login sessions, anyone who uses homedirs that require network authentication (such as NFS w/ sec=krb5 or OpenAFS) can’t use it at all, since it looks in ~user/.config/systemd/ for services.