1 Reply Latest reply on Sep 24, 2016 6:34 AM by Kiran.Pradeep

    How to execute my own application instead of login service (systemd)?

    ctan94x_intel

      Case description

      - I would like to launch my own application (instead of login service) after Linux (WRL8) starting. I don't want to be disturbed by login prompt in my application display.

      - I would like also to be able to start, by my application, the login service later.

      How can I do that?

       

      Solution

      Here is how I would do it (not saying that this is the best or the only way):

       

      First, the general idea

       

      Since you may want to log in later, you should not stop the login service.

      I would suggest to rather stop it from enabling logins on any console such that you can later enable the consoles you like.

       

      The number of consoles depends on the target. You might have have serial consoles (depending on your target, something like ttyS0) and depending on your kernel config you may also have virtual terminals (ttyX).

       

      Once you have disabled login on any consoles, your Linux will not be accessible (unless you have an SSHd  or other remote login service running).

       

      Once you have prepared that, you can create your own systemd service that will start your application on boot and then your application (running as root) can later start logins on any console you like.

       

      Few explanations and remarks

       

      Login is handled via systemd-logind. logind in turn uses getty@.service and serial-getty@.service to spawn logins on different consoles.

      There are predefined consoles to spawn targets for and there are so called automatically spawned virtual terminals (autoVTs).

      So first, you need to ensure that autoVTs are turned off. Then you need to get rid of the predefined consoles.

       

      getty@.service and serial-getty@.service are actually templates. The "real" services are later called getty@tty1.service or serial-getty@ttyS0.service. Masking the services is not good option, as it would disallow you to later enable them.

       

      This is all about general systemd handling and not at all Wind River specific.

       

      I assume that you are looking for offline ways to achive your goal. That means, modifications of the rootFs and config files, so that you can embed them

      into bitbake recipes or fs_final scripts. Online actions like using systemctl are no options.

       

      Disable autoVTs

       

      In the rootFS, edit /etc/systemd/logind.conf and ensure the following settings are applied (by default, no setting is explicitly set, so should be able to simple append the lines to the file):

       

        NAutoVTs=0

        ReserveVT=0

       

      Disable predefined terminals

       

      Delete any incarnation of getty@service and serial-getty@.service from /etc/systemd/system/getty.target.wants

      In a vanilla x86_64 rootFS, this would be getty@tty1.service and serial-getty@ttyS0.service. Removing these symlinks is the same as running, for example, "systemctl disable getty@tty1.service" ; in a live system.

       

      Now, your Linux will not have any local terminal active.

       

      Create your own service description

       

      Create a .service file in /etc/systemd/system. for example, /etc/systemd/system/my.service.

       

      The actual configuration depends on your applications and I have to refer you to the systemd documentation for all the details.

      I will try to explain it using an example.

       

      <my.service>

      [Unit]

      Description=My Service

      After=systemd-user-sessions.service plymouth-quit-wait.service

      After=rc-local.service

       

      [Service]

      Type=idle

      ExecStart=/root/my_service.sh

       

      [Install]

      WantedBy=multi-user.target

      </my.service>

       

      This service is pretty simple. Its "After" directives are the same as the ones of getty, which should start it about the same

      time as the logins would normally be started.

      Its type is set to "idle" which is a not-so-elegant way to make sure it only starts when all other services (that have the same "after"

      settings) are done. This should ensure that console output is not mixed.

      Then you see that I simply start a shell script (this could be your application). Note that there is no need to fork or anything.

      Systemd will ensure things run in parallel.

      Finally, you see that this script shall belong to the multi-user target.

       

      Enable your service for auto-start

       

      Add a symlink to /etc/systemd/system/my.service into /etc/systemd/system/multi-user.target.wants, so that it looks like this:

       

      # ls -l etc/systemd/system/multi-user.target.wants/

      total 0

      lrwxrwxrwx. 1 root root 13 Sep  2 10:02 my.service -> ../my.service

      [...] # there might be more than just that

       

      This is the same as running "systemctl enable my.service" in a live system

       

      And that's it. Now your system will not have any interactive logins and run your application right after boot.

       

      Some word regarding the application

       

      The application now runs as a systemd service. That means that its standard out and standard error will go

      to the system log and not to any console. Also, there is no standard input.

       

      So your application will need to explicitly open consoles for reading and writing.

       

      For example, my simple "application" does it like this:

       

      <my_service.sh>

      #!/bin/sh

       

      TTY=/dev/ttyS0

      TTYSVC=serial-gettyATttyS0.service

      #                  ^^ I had to write "AT" to prevent

      # Wind Answer from corrupting the formatting here.

      # It must be an "@", of course.

       

      exec 42<> $TTY

      echo "Please enter the magic number" > $TTY

      read -u 42 NUMBER

      exec 42>&-

      if [ $NUMBER -eq 42 ]; then

          systemctl start $TTYSVC

      else

          echo "BANG YOU ARE DEAD" > $TTY

      fi

       

      </my_service.sh>

       

      So you see that it works with the serial console of my system.

      It will ask for user input, and only if 42 is entered, the normal login will appear.

      If not, the system will be locked (at least for local access).

       

      Last Validated Info:

      BSP: MI3.1

      Version: RCPL0018

      Device: DK300