2

I just switched to 16.04 server from 14.04 server. With Upstart I used to start my server with a file that I had in /etc/rcS.d called M95. M95 was called by /etc/rc.local. Now with systemd I have written a file in /etc/systemd/system called my.service. It looks like this:

[Unit]
Description=MyService

[Service]
WorkingDirectory=/etc
ExecStart=/bin/sh rc.local

[Install]
WantedBy=multi-user.target

When I type "/bin/sh rc.local" into the command line my server does start. When I try to start the service by doing "systemctl start my.service" nothing happens.

The relevant lines in journalctl -b are:

Started MyService.
eth0 ...(basically the info I see from ifconfig)
root : TTY=unknown ; PWD=/etc ; USER=root ; COMMAND=/etc/rcS.d/M95
pam_unix(sudo:session): session opened for user root by (uid=0)
$File not found:: /new/den-routes
udhcpd already running
pam_unix(sudo:session): session closed for user root
/bin/rm: cannot remove '/var/log/rewriting-net-rules': No such file or directory.

In rc.local it looks like:

#!/bin/sh -e
...
sudo /etc/rcS.d/M95
/bin/rm /var/log/rewriting-net-rules

exit 0

In M95 it starts udhcpd (which is where the "udhcpd already running" message comes from) and at the end starts the server by saying:

cd /new
/bin/sh StartServer&

It seems that it does get to M95 because messages are getting logged from it, but the server does not start. When I run these files in the command line it works, but as the service it does not work. I am very unfamiliar with systemd so I have no idea if I am doing this correctly. For a week I have been reading examples and tutorials for it but I am still unsure how this works and how the service file should be written.

Edit: Here is my StartServer file:

#!/bin/bash
nohup /jre/jdk1.8.0_101/jre/bin/myserver -Xrs -Xmx1000m -jar /new/MyServer.jar nowd &

It runs just fine when I start it from the command line. It runs when I call it from my.service. I put in some echos to see that it gets through the whole file, but myserver and MyServer.jar don't start for some reason.

khm
  • 283

2 Answers2

4

My goodness, there are a lot of things wrong here.

  • You aren't running your service directly; but instead your service unit is running a shell that interprets rc.local in working directory /etc. This despite the fact that systemd has a pre-supplied service unit for running /etc/rc.local if one really wants to. (rc.local is a mechanism that has been superseded three times over on Ubuntu, first by van Smoorenburg rc, then by upstart, then by systemd.)
  • But /etc/rc.local isn't running your service either. Instead it is invoking sudo, despite the fact that it is already running as the superuser.
  • That's in turn running a (second) script from /etc/rcS.d, despite the fact that directory is a symbolic link farm that isn't supposed to contain actual rc script files.
  • That script runs by hand dæmons that systemd is clearly already running as actual services.
  • It thinks that the working directory should be /new not /etc.
  • But even that isn't your service. Instead it is forking a shell to interpret a third script named StartServer.
  • It's not using exec to overlay itself.
  • It's using & to run that shell asynchronously.
  • That fourth script is then forking and running a Java program.
  • It too is not using exec to overlay itself.
  • And the icing on the cake is that that is also using & to run that Java program asynchronously.

None of this is necessary.

And you appear for no apparent reason to have plonked it in the middle of a mechanism for re-setting MAC addresses in cloned virtual machines.

[Unit]
Documentation=https://askubuntu.com/a/831314/43344
After=udhcpd.service

[Service]
WorkingDirectory=/new
ExecStart=/jre/jdk1.8.0_101/jre/bin/myserver -Xrs -Xmx1000m -jar /new/MyServer.jar nowd

[Install]
WantedBy=multi-user.target

There's also clearly an After= addition needed for whatever it is that is writing out the den-routes file that your dæmon is expecting; you, however, not providing any information to determine what that is.

Further reading

JdeBP
  • 3,959
0

It turned out the problem was in a piece of code in rc.local. A line that someone put in trying to remove a file would produce an error and cause the program to exit if the file didn't exist. I am not sure why it did not produce this error when I ran it in the command line, but when run using a service, it stopped everything from working.

I fixed it by adding an if statement to check if that file exists before I try to remove it.

khm
  • 283
  • Little late now, but an 'if' statement is not necessary. Just add a -'f' option to the 'rm' command. If file does not exist, no error. – Mark J. Bobak Jul 11 '19 at 15:46