0

I'm trying to create startup / shutdown script for my application, but I do not have experience with that, so I wanted to start with screen (I'll refer to it as "test_screen").

Firstly I thought I'll create script in /etc/init.d only. And I got inspiration from here - https://unix.stackexchange.com/a/20361/29677 .

Basic idea to simuate my appplication is to use

  • screen -d -m -S test_screen to startup
  • screen -S test_screen -X quit for shutdown
  • and screen –list for status (kind of)

But when I tried /etc/init.d/test_screen start I got

Reloading systemd:                                         [  OK  ]
Starting test_screen (via systemctl):  Failed to start test_screen.service: Unit not found.
                                                       [FAILED]

So it seems I have to create unit.

I tried with https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/sect-Managing_Services_with_systemd-Unit_Files.html , so I have my unit file in /etc/systemd/system:

# cat test_screen.service
[Unit]
Description=Testing `screen` service

[Service]
Type=simple
ExecStart=/bin/screen -d -m -S test_screen
ExecStop=/bin/screen -S test_screen -X quit
Environment=
Restart=always

[Install]
WantedBy=default.target

First question is, should I have /etc/init.d/test_screen start as ExecStart or not? Definitely it won't be one liner...

Anyway, it is not running. In /var/log/messages I see

Sep 19 10:54:58 somehostname systemd: Started Testing `screen` service.
Sep 19 10:54:58 somehostname systemd: Starting Testing `screen` service...
Sep 19 10:54:58 somehostname systemd: test_screen.service holdoff time over, scheduling restart.
Sep 19 10:54:58 somehostname systemd: Started Testing `screen` service.
Sep 19 10:54:58 somehostname systemd: Starting Testing `screen` service...
Sep 19 10:54:58 somehostname systemd: test_screen.service holdoff time over, scheduling restart.
Sep 19 10:54:58 somehostname systemd: Started Testing `screen` service.
Sep 19 10:54:58 somehostname systemd: Starting Testing `screen` service...
Sep 19 10:54:59 somehostname systemd: test_screen.service holdoff time over, scheduling restart.
Sep 19 10:54:59 somehostname systemd: Started Testing `screen` service.
Sep 19 10:54:59 somehostname systemd: Starting Testing `screen` service...
Sep 19 10:54:59 somehostname systemd: test_screen.service holdoff time over, scheduling restart.
Sep 19 10:54:59 somehostname systemd: Started Testing `screen` service.
Sep 19 10:54:59 somehostname systemd: Starting Testing `screen` service...
Sep 19 10:54:59 somehostname systemd: test_screen.service holdoff time over, scheduling restart.
Sep 19 10:54:59 somehostname systemd: start request repeated too quickly for test_screen.service
Sep 19 10:54:59 somehostname systemd: Failed to start Testing `screen` service.
Sep 19 10:54:59 somehostname systemd: Unit test_screen.service entered failed state.
Sep 19 10:54:59 somehostname systemd: test_screen.service failed.

How can I find the reason, why it is entering failed state? All suggestions are welcome.

  • 1
    Why do you need to use screen? Systemd is already capable of backgrounding processes for you so there is no need for terminal multiplexers like screen. – Michael Daffin Sep 19 '17 at 9:57
  • @MichaelDaffin I picked screen just to be able to test with something simple, because I have no experience with startup scripts so far... – Betlista Sep 19 '17 at 10:27
  • Can you give an example of the application you are trying to run? Does it background itself? Sounds like you are using screen as a hack to get around your process not backgrounding itself for old style init scripts but this is not required in systemd. More details on what you are trying to achieve overall would give you better answers. – Michael Daffin Sep 19 '17 at 11:06
  • As a target solution I'm not going to use screen at all, it will be IBM WAS, but for MCVE I cannot ask you to install WAS... – Betlista Sep 19 '17 at 11:09
  • 1
    The reason I ask is there is a difference between Type=simple and Type=forking depending on how your actual application is run will change how you should write the service file. For screen you will want Type=forking but this wont always be true. – Michael Daffin Sep 19 '17 at 11:39
0

It seems, that I solved it for screen...

Firstly I removed that Restart=always parameter.

To make it work I also had to add RemainAfterExit=True.

With old init scripts it was clear where to have the code. I do not really know what is a proper place to put the rest of code. Should I simply call my script from ExecStart=?


My additional findings during learning.

status

There is a good question (I meant I was interested too), how to implement status checking - systemd custom status message?

Short answer is, it works (somehow) out f the box = you do not need to care much.

So, for my test_screen service I can call systemctl status test_screen.service and I'll get

● test_screen.service - Testing `screen` service
   Loaded: loaded (/etc/systemd/system/test_screen.service; disabled; vendor preset: disabled)
   Active: active (running) since Wed 2017-09-20 12:48:34 CEST; 1s ago
  Process: 36633 ExecStart=/bin/screen -d -m -S test_screen (code=exited, status=0/SUCCESS)
 Main PID: 36634 (screen)
   CGroup: /system.slice/test_screen.service
           ├─36634 /bin/SCREEN -d -m -S test_screen
           └─36635 /bin/sh

Sep 20 12:48:34 somehostname systemd[1]: Starting Testing `screen` service...
Sep 20 12:48:34 somehostname systemd[1]: Started Testing `screen` service.

...strange is, that when I stop it, for status I got failed:

● test_screen.service - Testing `screen` service
   Loaded: loaded (/etc/systemd/system/test_screen.service; disabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Wed 2017-09-20 12:51:00 CEST; 1s ago
  Process: 36805 ExecStop=/bin/screen -S test_screen -X quit (code=exited, status=0/SUCCESS)
  Process: 36633 ExecStart=/bin/screen -d -m -S test_screen (code=exited, status=0/SUCCESS)
 Main PID: 36634 (code=exited, status=1/FAILURE)

Sep 20 12:48:34 somehostname systemd[1]: Starting Testing `screen` service...
Sep 20 12:48:34 somehostname systemd[1]: Started Testing `screen` service.
Sep 20 12:51:00 somehostname systemd[1]: Stopping Testing `screen` service...
Sep 20 12:51:00 somehostname systemd[1]: test_screen.service: main process exited, code=exited, status=1/FAILURE
Sep 20 12:51:00 somehostname systemd[1]: Stopped Testing `screen` service.
Sep 20 12:51:00 somehostname systemd[1]: Unit test_screen.service entered failed state.
Sep 20 12:51:00 somehostname systemd[1]: test_screen.service failed.

to overcome that I had to have RemainAfterExit=True (because I tried the suggestion to have Type=forking and I commented out that RemainAfterExit option).

list-unit-files

I had an issue, that I'm not able to reproduce now - when I tried systemctl start the response was something like "No unit file", so I was wondering if there is a need to register it somehow.

No, you do not need to. You can execute systemctl list-unit-files --type=service and you should see your unit there. My problem was, that ExecStart parameter was wrong. When I tried the same now I have easier to understand message:

$ systemctl start test_screen.service
Job for test_screen.service failed because the control process exited with error code. See "systemctl status test_screen.service" and "journalctl -xe" for details.

$ systemctl status test_screen.service
● test_screen.service - Testing `screen` service
   Loaded: loaded (/etc/systemd/system/test_screen.service; disabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Wed 2017-09-20 12:55:53 CEST; 1min 3s ago
  Process: 37344 ExecStart=/bin/screen2 -d -m -S test_screen (code=exited, status=203/EXEC)
 Main PID: 36634 (code=exited, status=1/FAILURE)

Sep 20 12:55:53 somehostname systemd[1]: Starting Testing `screen` service...
Sep 20 12:55:53 somehostname systemd[37344]: Failed at step EXEC spawning /bin/screen2: No such file or directory
Sep 20 12:55:53 somehostname systemd[1]: test_screen.service: control process exited, code=exited status=203
Sep 20 12:55:53 somehostname systemd[1]: Failed to start Testing `screen` service.
Sep 20 12:55:53 somehostname systemd[1]: Unit test_screen.service entered failed state.
Sep 20 12:55:53 somehostname systemd[1]: test_screen.service failed.

Executing script

I tried to modify my test_screen to call script

$ cat /etc/systemd/system/test_screen_script.service
[Unit]
Description=Testing `screen` service

[Service]
Type=forking
ExecStart=/root/test_screen_start.sh
ExecStop=/root/test_screen_stop.sh
#Environment=
#Restart=always
RemainAfterExit=True

[Install]
WantedBy=default.target

while scripts are just wrapped for previous calls

$ cat /root/test_screen_start.sh
/bin/screen -d -m -S test_screen
$ cat /root/test_screen_stop.sh
/bin/screen -S test_screen -X quit

when I did that, it is not starting up:

$ systemctl start test_screen_script
Job for test_screen_script.service failed because the control process exited with error code. See "systemctl status test_screen_script.service" and "journalctl -xe" for details.

$ systemctl status test_screen_script.service
● test_screen_script.service - Testing `screen` service
   Loaded: loaded (/etc/systemd/system/test_screen_script.service; disabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Wed 2017-09-20 15:47:59 CEST; 8s ago
  Process: 63582 ExecStart=/root/test_screen_start.sh (code=exited, status=203/EXEC)
 Main PID: 60698 (code=exited, status=0/SUCCESS)

Sep 20 15:47:59 somehostname systemd[1]: Starting Testing `screen` service...
Sep 20 15:47:59 somehostname systemd[63582]: Failed at step EXEC spawning /root/test_screen_start.sh: Exec format error
Sep 20 15:47:59 somehostname systemd[1]: test_screen_script.service: control process exited, code=exited status=203
Sep 20 15:47:59 somehostname systemd[1]: Failed to start Testing `screen` service.
Sep 20 15:47:59 somehostname systemd[1]: Unit test_screen_script.service entered failed state.
Sep 20 15:47:59 somehostname systemd[1]: test_screen_script.service failed.

It would be good is someone can describe the reason. Fix for that is to add #!/bin/bash.

References

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.