4

I'm using Debian Jessie with the latest updates. I made a systemd service to run a script when my server starts. Here's its configuration:

[Unit]
Description=(my description)

[Service]
ExecStart=/usr/bin/bot
Restart=restart-always

[Install]
WantedBy=multi-user.target

/usr/bin/bot is a script running a Mono executable. It consists of:

#!/bin/bash
(cd /path/to/my/executable && mono bot.exe)

(I replaced the path here, but the one on my script is correct.)

When I run the script /usr/bin/bot normally (simply /usr/bin/bot on my terminal), it is working as expected. top reports it's using between 0 and, say, 20% of my CPU, which is normal. But when I start it with service bot start, top says it's always using at least 100% of my CPU.

In both cases bot is working as expected.

What could explain such a big difference in CPU usage?

Thank you.

10
  • Have you tried this on any other systemd based systems? Jessie isn't a stable release yet. Might be good to bring this to their attention.
    – Devon
    Mar 21, 2015 at 14:32
  • I'll install Wheezy and try. Mar 21, 2015 at 14:35
  • Wheezy only included a tech preview of systemd. So I don't know if it will be any different. systemd is new to the Debian and Ubuntu scene. Here is a list of distributions: en.wikipedia.org/wiki/Systemd#Adoption_and_reception
    – Devon
    Mar 21, 2015 at 14:37
  • Oh, right. Well, I don't actually need to use systemd, I only started using it because after upgrading to Jessie (I believe), my inittab wasn't taken into account anymore, probably because it was using systemd instead. Though there are other scripts that Debian runs with systemd, and those don't use 100% CPU. But I'd rather not go back to SysV since systemd is probably going to be widespread in the future. Mar 21, 2015 at 14:42
  • 3
    It doesn't really make sense for this to be a systemd bug if it is literally the bot process which is using all the CPU. Systemd is not magical and can't affect your program's behavior beyond starting it, sending it signals, and perhaps killing it.
    – goldilocks
    Mar 21, 2015 at 15:12

5 Answers 5

4

Problem is not located in systemd.

Systemd runs process without stdin (=/dev/null). All syscalls to read() are finished immediately (with normal stdin, read() is blocked until new data arrive). In general practice read() is called within unfinished loop making huge CPU usage. To confirm this, try to attach to running process with strace -p <pid>.

Process has to be adapted to run without stdin or use some wrappers like proposed screen command or nohup

1
  • +1 for the info about the root cause. But you could elaborate your resolution.
    – SandRock
    Jun 20 at 17:08
3

I "fixed it" by putting my bot under a screen, like so:

[Unit]
Description=(my description)

[Service]
RemainAfterExit=yes
ExecStart=/usr/bin/screen -dmS bot /usr/bin/bot
Restart=restart-always

[Install]
WantedBy=multi-user.target

I don't know why putting my process in a screen fixes its high CPU usage, but hey, it works.

2
  • I was having the same issue, and this worked. However, I used -D instead of -d so that the screen would stay attached and systemd could continue to track the service after it started.
    – Thomas M
    May 11, 2017 at 16:21
  • This is a workaround for a real solution. Either configure your service to have a standard input, or avoid reading from standard input in your code.
    – SandRock
    Jun 20 at 17:07
1

As per @niziak's solution the input is blocking. In my case solved by Adding StandardInput=tty to the [Service] fixed it. I was already re-directing output to an (unused) console on /dev/tty12.

My [service] section:

[Service]
ExecStart=/usr/local/bin/vtclock -1  -c| -f /tmp/ntpstatus
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=simple
User=vtclock
StandardInput=tty
StandardOutput=tty
StandardError=null
TTYPath=/dev/tty12 

(OS = Ubuntu 16.04.3 LTS, my first attempt at a systemd service)

1

I see this is an old thread, but I leave my scenario here, maybe a few years time some finds it usefull.

I have a discord bot in c# dotnet core.

I made a systemctl daemon for it in my ubuntu server.

I have the git repo stored on te server as well. when I used it in test, I went with the

dotnet run 

it consumed 0,3% of cpu.

I made a publish of it and placed it in my active server folder. From there in the daemon it went to 100% cpu usage in the daemon.

I got mixed between the differrent versions, but I felt that it was runing normally from terminal.

but no.

My rookie mistake was doing

dotnet publish -r linux-x64 --self-contained true

instead of

dotnet publish -r linux-x64 

But for a long time I did not noticed, because the self contained version was runing fine with minimal cpu, until I moved out from the procet bin directory.

1
  • This answer is missing a root cause information. Why would a self-contained build use 100% CPU? Is this a bug in the runtime?
    – SandRock
    Jun 20 at 17:09
0

If you've developed a console application in C# / .NET Core, don't use this to keep the console running:

Console.Read();

As it will result in 100% CPU usage when you run the application as a systemd service on linux.

Rather use:

while (true) { Console.ReadKey(); }

I had the same problem.

1
  • Thanks. You can also have a command-line argument to start your application in a way that would avoid calling Console methods.
    – SandRock
    Jun 20 at 17:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .