How to automatically start services with systemd in Yocto

cancel
Showing results for 
Search instead for 
Did you mean: 

How to automatically start services with systemd in Yocto

Jump to solution
18,556 Views
dougbailey
Contributor III

I am upgrading a product I have developed to the latest iMX6 BSP that is using Yocto Morty. One big change with the Morty based BSP is the use of Systemd in place of System V Init files.

I read that systemd is supposed to be backaward compatible with the SysV Init files but I do not see this occur. I see that the generated service files are created but the services themselves are not started at boot up.

To get around this, I am regenerating the init files using "*.service" files handled by Systemd. I can generate the files but I need to find a way to specifiy the services that start at bootstrap from the Yocto recipes. I can do it by creating a symlink to the service file from /etc/systemd/system/multi-user.target.wants/ directory. However, I read that manually creating these symlinks is not suggested.

What is the preferred way within Yocto to create systemd service files that are automatically activated at boot?

Regards 

Doug Bailey

Labels (2)
1 Solution
9,845 Views
ryanpabis
Contributor II

Thanks Doug.  Not sure exactly what fixed it for me but this is what I did and it work.

NOTE: Like many others I had a sysvinit script and then let the systemd-sysv-generator create a wrapper for me which I called dl-mgr.service.  This service starts and stops the dl-mgr.sh script.  You can find these files in (/run/systemd/generator.late/) if you don't have a .service file yet.

SRC_URI = "file://dl-mgr.sh \
                     file://dl-mgr.service \"

inherit update-rc.d systemd

SYSTEMD_PACKAGES = "${PN}"
INITSCRIPT_PACKAGES = "${PN}"

SYSTEMD_SERVICE_${PN} = "dl-mgr.service"

I then added this to my do_install section

install -d ${D}${libexecdir}
install -m 0755 ${WORKDIR}/dl-mgr.sh ${D}${libexecdir}/dl-mgr.sh
install -d ${D}${systemd_system_unitdir}
install -m 0644 ${WORKDIR}/dl-mgr.service ${D}${systemd_system_unitdir}

As well as this to the end of the .bb file

FILES_${PN} += "${libexecdir}/dl-mgr.sh"
FILES_${PN} += "${systemd_system_unitdir}/dl-mgr.service"

And then finally, i updated my dl-mgr.service (the one that was autogenerated) to include this.

ExecStart=/usr/libexec/dl-mgr.sh start
ExecStop=/usr/libexec/dl-mgr.sh stop

[Install]

WantedBy=multi-user.target

View solution in original post

0 Kudos
8 Replies
9,844 Views
gusarambula
NXP TechSupport
NXP TechSupport

Hello Doug Bailey,

There are some documents online that may be of help, like the following thread on a third-party forum. I hope it helps!

https://stackoverflow.com/questions/45614578/enable-systemd-services-using-yocto

Regards,

9,844 Views
dougbailey
Contributor III

Thanks for the information.  It's a big help. 

0 Kudos
9,844 Views
ryanpabis
Contributor II

Did you ever get this to work?  I am having the same problem.  The only way I can get my services to start at boot is by creating the symlink.  Even after following the link posted by gusarambula

0 Kudos
9,844 Views
dougbailey
Contributor III

I ended up using a symlink when I wanted to force the startup in the build process.  

I added the following into my do_install function: 

if ${@bb.utils.contains('DISTRO_FEATURES','systemd','true','false',d)}; then
    install -d ${D}/etc/systemd/system/multi-user.target.wants
    install -m 644 ${WORKDIR}/resetswx.service ${D}/etc/systemd/system/resetswx.service
    ## Add following link if you want auto start of service
    ## ln -s /etc/systemd/system/resetswx.service ${D}/etc/systemd/system/multi-user.target.wants/resetswx.service

fi 

0 Kudos
9,846 Views
ryanpabis
Contributor II

Thanks Doug.  Not sure exactly what fixed it for me but this is what I did and it work.

NOTE: Like many others I had a sysvinit script and then let the systemd-sysv-generator create a wrapper for me which I called dl-mgr.service.  This service starts and stops the dl-mgr.sh script.  You can find these files in (/run/systemd/generator.late/) if you don't have a .service file yet.

SRC_URI = "file://dl-mgr.sh \
                     file://dl-mgr.service \"

inherit update-rc.d systemd

SYSTEMD_PACKAGES = "${PN}"
INITSCRIPT_PACKAGES = "${PN}"

SYSTEMD_SERVICE_${PN} = "dl-mgr.service"

I then added this to my do_install section

install -d ${D}${libexecdir}
install -m 0755 ${WORKDIR}/dl-mgr.sh ${D}${libexecdir}/dl-mgr.sh
install -d ${D}${systemd_system_unitdir}
install -m 0644 ${WORKDIR}/dl-mgr.service ${D}${systemd_system_unitdir}

As well as this to the end of the .bb file

FILES_${PN} += "${libexecdir}/dl-mgr.sh"
FILES_${PN} += "${systemd_system_unitdir}/dl-mgr.service"

And then finally, i updated my dl-mgr.service (the one that was autogenerated) to include this.

ExecStart=/usr/libexec/dl-mgr.sh start
ExecStop=/usr/libexec/dl-mgr.sh stop

[Install]

WantedBy=multi-user.target

0 Kudos
2,725 Views
Sourabh1107
Contributor I

Hello @ryanpabis  thanks for the solution. I am trying to achieve the same to start my custom script during boot-up. If I have 2 scripts to be executed once rootfs is mounted or during boot-up how should I include 2 files in image recipe? Should I create 2 separate systemd service files? Can you please let me know how to do this? Assuming script names are custom-script1.sh and custom-script2.sh

Your help will be much appreciated.

Thanks in advance.

0 Kudos
9,845 Views
la_basco
Contributor I

I believe the important lines related to enabling the service at startup -- that made your recipe work are:


1.) in your recipe:
inherit update-rc.d 
systemd 


2.) in your service file

[Install]

WantedBy=multi-user.target


Explanation:
1. This line in the recipe, particularly, inherit systemd, makes use of the systemd.bbclass located in poky/meta/classes where the default directive is to enable services as seen from the lines:

# Whether to enable or disable the services on installation.
SYSTEMD_AUTO_ENABLE ??= "enable"


2. This line is important because in the process of enabling the service, it specifies -- in what systemd target directory the symlink will be installed. In this case, the symlink should be in etc/systemd/system/multi-user.target.wants directory.

0 Kudos
9,845 Views
dougbailey
Contributor III

Whereas my solution is more of a hack, this looks like a better way to implement the service. 

Thanks for posting this.  I will use it in the future. 

0 Kudos