3
votes

I have a server to launch at system boot time using a Yocto compatible file system on an embedded target. The file system uses systemd for its service system.

My server uses a systemd template unit file, and I am having trouble getting it enabled. We use the template to supply a full path name of a sqlite database file that the server uses. The template unit file is named:

/lib/systemd/system/[email protected]

Its contents:

[Unit]
    Description=Data Server application (with DB=%I)
    After=syslog.target
[Service]
    Type=simple
    ExecStart=/opt/ndc/DataServer --DEBUG --databaseFile=%I
    Restart=always
    RestartSec=2
[Install]
    WantedBy=multi-user.target

The database file is in /var/lib/ndc/DataServer.DB, so I created a symbolic link in /lib/systemd/system:

# ln -s [email protected] [email protected]

When I run:

# systemctl start [email protected]

The server launches with the correct parameter, finds the database, and executes in the background as expected. So I tried to enable the service template so that it will launch the service during system boot-time:

# systemctl enable [email protected]
    Failed to execute operation: No such file or directory

Since that failed, I tried enabling the template file itself:

# systemctl enable TDI_DataServer@
    ln -s '/lib/systemd/system/[email protected]''/etc/systemd/system/multi-user.target.wants/[email protected]'

On the surface, the system seems happy, but at boot time, systemd does not execute the launch of TDI_DataServer correctly. It seems to supply the "multi-user" parameter (maybe from the WantedBy target in the unit file?) to the unit file.

Here is the systemctl status:

$ systemctl status -l TDI*
    ● [email protected] - Data Server application (with DB=multi/user)
       Loaded: loaded (/lib/systemd/system/[email protected]; enabled)
       Active: activating (auto-restart) (Result: signal) since Sat 2000-02-05 20:41:05 UTC; 1s ago
      Process: 2951 ExecStart=/opt/ndc/DataServer --DEBUG --databaseFile=%I (code=killed, signal=ABRT)
     Main PID: 2951 (code=killed, signal=ABRT)

    Feb 05 20:41:05 mityomapl138 DataServer[2951]: [949783265:2047] NOTICE:  per-conn mem: 136 + 2140 headers + protocol rx buf
    Feb 05 20:41:05 mityomapl138 DataServer[2951]: [949783265:2056] NOTICE:  Listening on port 4243
    Feb 05 20:41:05 mityomapl138 systemd[1]: [email protected]: main process exited, code=killed, status=6/ABRT
    Feb 05 20:41:05 mityomapl138 systemd[1]: Unit [email protected] entered failed state.
    Feb 05 20:41:05 mityomapl138 DataServer[2951]: 2000:02:05 20:41:05: WSServer connected on socket tcp://localhost:5556
    Feb 05 20:41:05 mityomapl138 DataServer[2951]: 2000:02:05 20:41:05:  bound to socket inproc://clients
    Feb 05 20:41:05 mityomapl138 DataServer[2951]: 2000:02:05 20:41:05: DatabaseWorker using database multi/user
    Feb 05 20:41:05 mityomapl138 DataServer[2951]: unable to open database file
    Feb 05 20:41:05 mityomapl138 DataServer[2951]: terminate called after throwing an instance of 'SQLite::Exception'
    Feb 05 20:41:05 mityomapl138 DataServer[2951]: what():  unable to open database file

● TDI_DataServer.service
       Loaded: loaded (/etc/init.d/TDI_DataServer)
       Active: inactive (dead)

Am I missing something? Any help would be much appreciated.

2
Note: If I put my own symlink in the /etc/systemd/system/multi-user.target.wants directory named "[email protected]", everything works fine. It's just that "systemctl enable" is supposed to do that for mef1fan44

2 Answers

3
votes

It appears there is indeed a bug in the systemctl parsing of the %I parameter supplied to the unit file. As stated above, the following command fails:

# systemctl enable [email protected]

However, if I change the name of our database file in /var/lib/ndc from "DataServer.DB" to "DataServer.db" (i.e. lowercase after the dot,) and I issue the following command:

# systemctl enable [email protected]

...everything works fine. The symbolic link gets created in /etc/systemd/system/multi-user.target.wants, and on the next reboot of the system, our DataServer service finds its database and runs happily.

I've notified our third party file system provider about this. It's probably something the folks at Yocto and the maintainers of systemd would be interested in.

0
votes

Instead of

# systemctl enable [email protected]

try

# systemctl enable [email protected]

I know that current systemd supports either but I'm guessing that at some point you had to be explicit with the .service portion and that's what you're running into here. Saying what Yocto version the filesystem is based on would help here, thanks!