Service doesn't run stop script

Hello

I have been trying to get a game server to run as a service and am having issues getting the stop command to run the script that I wrote for it to use. The script when ran by itself works fine. When I issue the systemctl stop command it just kills that process without running the script it seems and I would like to get it to save before it just kills the service. My service file is

[Unit]
Description=Minecraft_Server
Wants=network.target
After=syslog.target network.target

[Service]
Type=simple
WorkingDirectory=/home/bulbasaur/Minecraft/Java/Nightcraft
User=bulbasaur
Group=bulbasaur
ExecStart=/usr/bin/screen -DmS NightcraftJava /home/bulbasaur/Minecraft/Java/NightcraftJava/run.sh
ExecStop=/usr/bin/screen -p NightcraftJava /home/bulbasaur/Minecraft/Java/NightcraftJava/stop.sh

[Install]
WantedBy=multi-user.target

My start script is:

#!/bin/bash

#set location

cd /home/bulbasaur/Minecraft/Java/Nightcraft

#start game

java -Xmx4G -Xms4G -jar server.jar -nogui

My stop script is this

#!/bin/bash

#stop warning
screen -S NightcraftJava -X stuff $’/say server shutting down in 5 minutes\n’

#delay d=days h=hours m=minutes s=seconds
sleep 5m

#shutdown
screen -S NightcraftJava -X stuff $‘stop\n’

when I check the status after issuing the stop command I get this

minecraftjava.service - Minecraft_Server
Loaded: loaded (/etc/systemd/system/minecraftjava.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Wed 2021-04-14 23:58:35 EDT; 11min ago
Main PID: 2075974 (code=exited, status=1/FAILURE)

Apr 14 23:58:01 bulbasaur systemd[1]: Started Minecraft_Server.
Apr 14 23:58:34 bulbasaur systemd[1]: Stopping Minecraft_Server…
Apr 14 23:58:34 bulbasaur systemd[1]: minecraftjava.service: Main process exited, code=exited, status=1/FAILURE
Apr 14 23:58:35 bulbasaur systemd[1]: minecraftjava.service: Failed with result ‘exit-code’.
Apr 14 23:58:35 bulbasaur systemd[1]: Stopped Minecraft_Server.

and the log file says this

[23:58:07] [main/INFO]: Environment: authHost=‘https://authserver.mojang.com’, accountsHost=‘https://api.mojang.com’, sessionHost=‘https://sessionserver.mojang.com’, servic>
[23:58:08] [main/WARN]: Ambiguity between arguments [teleport, destination] and [teleport, targets] with inputs: [Player, 0123, @e, dd12be42-52a9-4a91-a8a1-11c01849e498]
[23:58:08] [main/WARN]: Ambiguity between arguments [teleport, location] and [teleport, destination] with inputs: [0.1 -0.5 .9, 0 0 0]
[23:58:08] [main/WARN]: Ambiguity between arguments [teleport, location] and [teleport, targets] with inputs: [0.1 -0.5 .9, 0 0 0]
[23:58:08] [main/WARN]: Ambiguity between arguments [teleport, targets] and [teleport, destination] with inputs: [Player, 0123, dd12be42-52a9-4a91-a8a1-11c01849e498]
[23:58:08] [main/WARN]: Ambiguity between arguments [teleport, targets, location] and [teleport, targets, destination] with inputs: [0.1 -0.5 .9, 0 0 0]
[23:58:08] [main/INFO]: Reloading ResourceManager: Default, afk display v1.1.0.zip, armor statues v2.8.1.zip, armored elytra v1.0.3.zip, coordinates hud v1.2.0.zip, double >
[23:58:10] [Worker-Main-11/INFO]: Loaded 7 recipes
[23:58:10] [Worker-Main-11/WARN]: Found validation problem in {minecraft:entities/ender_dragon}.pools[0].entries[0]: Unknown loot table called minecraft:entities/reference/>
[23:58:10] [Worker-Main-11/INFO]: Loaded 945 advancements
[23:58:12] [Server thread/INFO]: Starting minecraft server version 1.16.5
[23:58:12] [Server thread/INFO]: Loading properties
[23:58:12] [Server thread/INFO]: Default game type: SURVIVAL
[23:58:12] [Server thread/INFO]: Generating keypair
[23:58:12] [Server thread/INFO]: Starting Minecraft server on 192.168.0.18:25565
[23:58:12] [Server thread/INFO]: Using epoll channel type
[23:58:12] [Server thread/INFO]: Preparing level “Nightcraft JS1”
[23:58:12] [Server thread/INFO]: Preparing start region for dimension minecraft:overworld
[23:58:14] [Server thread/INFO]: Preparing spawn area: 0%
[23:58:14] [Server thread/INFO]: Preparing spawn area: 0%
[23:58:14] [Server thread/INFO]: Preparing spawn area: 0%
[23:58:14] [Server thread/INFO]: Preparing spawn area: 0%
[23:58:15] [Server thread/INFO]: Preparing spawn area: 0%
[23:58:15] [Server thread/INFO]: Preparing spawn area: 84%
[23:58:15] [Server thread/INFO]: Time elapsed: 2725 ms
[23:58:15] [Server thread/INFO]: Done (2.870s)! For help, type “help”
[23:58:15] [Server thread/WARN]: Trying to add entity with duplicated UUID 291dfbec-2b7b-4c2b-9899-f665ea53af5d. Existing minecraft:armor_stand#27, new: minecraft:armor_sta>
[23:58:34] [Server console handler/ERROR]: Exception handling console input
java.io.IOException: Input/output error
at java.io.FileInputStream.readBytes(Native Method) ~[?:?]
at java.io.FileInputStream.read(FileInputStream.java:279) ~[?:?]
at java.io.BufferedInputStream.read1(BufferedInputStream.java:290) ~[?:?]
at java.io.BufferedInputStream.read(BufferedInputStream.java:351) ~[?:?]
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) ~[?:?]
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) ~[?:?]
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) ~[?:?]
at java.io.InputStreamReader.read(InputStreamReader.java:181) ~[?:?]
at java.io.BufferedReader.fill(BufferedReader.java:161) ~[?:?]
at java.io.BufferedReader.readLine(BufferedReader.java:326) ~[?:?]
at java.io.BufferedReader.readLine(BufferedReader.java:392) ~[?:?]
at zg$1.run(SourceFile:95) [server.jar:?]

and when I run the stop stript I get this output which is what I want
[00:13:05] [main/WARN]: Ambiguity between arguments [teleport, destination] and [teleport, targets] with inputs: [Player, 0123, @e, dd12be42-52a9-4a91-a8a1-11c01849e498]
[00:13:05] [main/WARN]: Ambiguity between arguments [teleport, location] and [teleport, destination] with inputs: [0.1 -0.5 .9, 0 0 0]
[00:13:05] [main/WARN]: Ambiguity between arguments [teleport, location] and [teleport, targets] with inputs: [0.1 -0.5 .9, 0 0 0]
[00:13:05] [main/WARN]: Ambiguity between arguments [teleport, targets] and [teleport, destination] with inputs: [Player, 0123, dd12be42-52a9-4a91-a8a1-11c01849e498]
[00:13:05] [main/WARN]: Ambiguity between arguments [teleport, targets, location] and [teleport, targets, destination] with inputs: [0.1 -0.5 .9, 0 0 0]
[00:13:05] [main/INFO]: Reloading ResourceManager: Default, afk display v1.1.0.zip, armor statues v2.8.1.zip, armored elytra v1.0.3.zip, coordinates hud v1.2.0.zip, double >
[00:13:07] [Worker-Main-13/INFO]: Loaded 7 recipes
[00:13:07] [Worker-Main-13/WARN]: Found validation problem in {minecraft:entities/ender_dragon}.pools[0].entries[0]: Unknown loot table called minecraft:entities/reference/>
[00:13:07] [Worker-Main-13/INFO]: Loaded 945 advancements
[00:13:09] [Server thread/INFO]: Starting minecraft server version 1.16.5
[00:13:09] [Server thread/INFO]: Loading properties
[00:13:09] [Server thread/INFO]: Default game type: SURVIVAL
[00:13:09] [Server thread/INFO]: Generating keypair
[00:13:10] [Server thread/INFO]: Starting Minecraft server on 192.168.0.18:25565
[00:13:10] [Server thread/INFO]: Using epoll channel type
[00:13:10] [Server thread/INFO]: Preparing level “Nightcraft JS1”
[00:13:10] [Server thread/INFO]: Preparing start region for dimension minecraft:overworld
[00:13:12] [Server thread/INFO]: Preparing spawn area: 0%
[00:13:12] [Server thread/INFO]: Preparing spawn area: 0%
[00:13:12] [Server thread/INFO]: Preparing spawn area: 0%
[00:13:12] [Server thread/INFO]: Preparing spawn area: 0%
[00:13:12] [Server thread/INFO]: Preparing spawn area: 2%
[00:13:13] [Server thread/INFO]: Time elapsed: 2546 ms
[00:13:13] [Server thread/INFO]: Done (2.732s)! For help, type “help”
[00:13:13] [Server thread/WARN]: Trying to add entity with duplicated UUID 291dfbec-2b7b-4c2b-9899-f665ea53af5d. Existing minecraft:armor_stand#27, new: minecraft:armor_sta>
[00:13:48] [Server thread/INFO]: [Server] server shutting down in 5 minutes
[00:18:48] [Server thread/INFO]: Stopping the server
[00:18:48] [Server thread/INFO]: Stopping server
[00:18:48] [Server thread/INFO]: Saving players
[00:18:48] [Server thread/INFO]: Saving worlds
[00:18:48] [Server thread/INFO]: Saving chunks for level ‘ServerLevel[Nightcraft JS1]’/minecraft:overworld
[00:18:48] [Server thread/INFO]: ThreadedAnvilChunkStorage (Nightcraft JS1): All chunks are saved
[00:18:48] [Server thread/INFO]: Saving chunks for level ‘ServerLevel[Nightcraft JS1]’/minecraft:the_nether
[00:18:48] [Server thread/INFO]: ThreadedAnvilChunkStorage (DIM-1): All chunks are saved
[00:18:48] [Server thread/INFO]: Saving chunks for level ‘ServerLevel[Nightcraft JS1]’/minecraft:the_end
[00:18:48] [Server thread/INFO]: ThreadedAnvilChunkStorage (DIM1): All chunks are saved
[00:18:48] [Server thread/INFO]: ThreadedAnvilChunkStorage (Nightcraft JS1): All chunks are saved
[00:18:48] [Server thread/INFO]: ThreadedAnvilChunkStorage (DIM-1): All chunks are saved
[00:18:48] [Server thread/INFO]: ThreadedAnvilChunkStorage (DIM1): All chunks are saved

what am I doing wrong here?

I did look in the journalctl and saw that it is ignoring the script for stopping for some reason…

Apr 14 23:50:18 bulbasaur systemd[1]: Stopping Minecraft_Server…
Apr 14 23:50:18 bulbasaur screen[2065149]: Must be connected to a terminal.
Apr 14 23:50:18 bulbasaur systemd[1]: minecraftjava.service: Control process exited, code=exited, status=1/FAILURE
Apr 14 23:50:18 bulbasaur systemd[1]: minecraftjava.service: Main process exited, code=exited, status=1/FAILURE
Apr 14 23:50:20 bulbasaur systemd[1]: minecraftjava.service: Failed with result ‘exit-code’.
Apr 14 23:50:20 bulbasaur systemd[1]: Stopped Minecraft_Server.
Apr 14 23:57:51 bulbasaur systemd[1]: /etc/systemd/system/minecraftjava.service:12: Failed to parse signal name, ignoring: /usr/bin/screen -p NightcraftJava /home/bulbasaur/Minecraft/Java/Nightcraft/stop.sh

Maybe try to call the stop script directly without attaching to the screen instance first. The script is doing all the screen instance attaching commands as it is.

ExecStop=/usr/bin/screen -p NightcraftJava /home/bulbasaur/Minecraft/Java/NightcraftJava/stop.sh

to

ExecStop=/home/bulbasaur/Minecraft/Java/NightcraftJava/stop.sh

I do not have a ton of experience with writing service files that interact with screen, so someone else may have a better idea.

1 Like

I made that change and it started running the stop script because I saw the warning message in the log but it didn’t wait the full 5 minutes before it terminated the process. The journalctl for the service shows this

Apr 15 01:24:45 bulbasaur systemd[1]: Stopping Minecraft_Java_Server…
Apr 15 01:26:15 bulbasaur systemd[1]: minecraftjava.service: Stopping timed out. Terminating.
Apr 15 01:26:15 bulbasaur systemd[1]: minecraftjava.service: Control process exited, code=killed, status=15/TERM
Apr 15 01:26:15 bulbasaur systemd[1]: minecraftjava.service: Main process exited, code=exited, status=1/FAILURE
Apr 15 01:26:16 bulbasaur systemd[1]: minecraftjava.service: Failed with result ‘timeout’.
Apr 15 01:26:16 bulbasaur systemd[1]: Stopped Minecraft_Java_Server.

and the log for the game shows this

[01:19:06] [Server thread/INFO]: Gamebuster37 joined the game
[01:19:24] [Server thread/INFO]: Gamebuster37 lost connection: Disconnected
[01:19:24] [Server thread/INFO]: Gamebuster37 left the game
[01:24:45] [Server thread/INFO]: [Server] server shutting down in 5 minutes
[01:26:15] [Server console handler/ERROR]: Exception handling console input
java.io.IOException: Input/output error
at java.io.FileInputStream.readBytes(Native Method) ~[?:?]
at java.io.FileInputStream.read(FileInputStream.java:279) ~[?:?]
at java.io.BufferedInputStream.read1(BufferedInputStream.java:290) ~[?:?]
at java.io.BufferedInputStream.read(BufferedInputStream.java:351) ~[?:?]
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) ~[?:?]
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) ~[?:?]
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) ~[?:?]
at java.io.InputStreamReader.read(InputStreamReader.java:181) ~[?:?]

do I need to put a delay in the service file so the timer in the script has enough time to run? What would I need to put in to do that?

Looks like it is timing out, can try adding TimeoutStopSec= to your service file to give it enough time to complete.

TimeoutStopSec

You can’t just sleep 5 minutes in a systemd stop script.

First, the default stop time is probably 30 seconds and it might repeat that 3 times for 90 seconds. I’d have to look up the details.

After that, systemd will basically kill -9 the entire cgroup which contains the service. That includes the first script or program and every other program it launched. This is a major feature of systemd that it can guarantee cleanup of all programs.

Then besides that timeout is the system shutdown timeout. Even if you extend the shutdown timeout of this one service the entire shutdown process has a timeout of its own. If that is exceeded it will do an emergency sync and force-reboot. That also depends on settings that I’d have to look up.

2 Likes

So should I change the shutdown script to just run the save command then shutdown and not give people a warning? Other than a manual one?

Have you thought of writing a stop script that sends the warning message, waits 5 mins, then send the systemd shutdown of the service? That way you’re not having systemd doing the waiting?

That is the script I’m trying to get systemd to run that way if it ends up on backup power during an outage there is still time for players to get to a safe place before they would get kicked. It’s never good jumping back into a game and having to defend immediately…
I’m running the server out of my house and am not always there when the power might go out

What would I have to add to a script to send a warning to those on the server that it had been switch to backup power and they need to logout?

Do you have a way to process the signal from the backup power or does it just shutdown the system?

If you can handle the signal, then you can send the 5 minute warning and schedule the system shutdown.

# stop warning
screen -S NightcraftJava -X stuff $’/say server shutting down in 5 minutes\n’

# schedule shutdown
shutdown +5

All you will need to do in the minecraft server shutdown script is issue the stop command.

1 Like

I have an apc ups and I did install the companion service but being new to Linux and running a server at that, so I’m not sure how to do that. I’m fumbling around trying to learn how to do all of this

What is the companion service you are using, apcupsd? and how do you have it currently shutting things down?

Yes that is the service that I have installed. I believe it is supposed to shut down once it gets to a certain battery percentage.

I have never used the program before, but found some info that may be helpful.

APCUPSD User Manual

There should be a script, /etc/apcupsd/apccontrol, that has all the sane defaults for the UPS.

Looks like you can create a script for whichever event you want to handle in that directory, /etc/apcupsd/, and it will be called when that event happens. So you could create file called onbattery with the script I posted previously to start the shutdown process.

So your saying that I should try using a different script that will run when the power state changes? I will try to look at figuring that out

Friend, here’s a minecraft site for you.

https://99minecraft.com/mods/wildycraft-mod-1-7-10/

I think they can help you there, they solve such issues every day

thank you sir I will look into it