1

I want to execute a script which is present in rootfs everytime system boots to indicate successful update and reset bootloader variables.

For example, the "custom-script" script in present in /etc as:

/etc
----/init.d
-----------custom-script.sh

The first step I did is to install this script in rootfs of the linux image. I have created a recipe in my custom Yocto layer. meta-custom\recipes-support\images layer directory is as follows:

.
├── files
│   ├── custom-script.sh
└── core-image-base.bb

The core-image-base.bb is:

DESCRIPTION = "Install script to Rootfs"
SUMMARY = "Install script to Rootfs and run after boot"
LICENSE = "CLOSED"

SRC_URI = "file://custom-script.sh"

do_install_append() {
    install -d 644 ${D}${sysconfdir}/init.d
    install -m 0755 ${WORKDIR}/custom-script.sh ${D}${sysconfdir}/init.d/custom-script.sh

FILES_${PN} = "${sysconfdir}/init.d"

And in the conf/layer.conf I added IMAGE_INSTALL_append = " core-image-base".

Now I want to execute this script every time the linux system boots (afrer successfully loading rootfs). Can someone please help me to accomplish this? As per my understanding, I can use systemd services to do this and this service should be executed each time the system boots. Any help would be much appreciated.

Thanks in advance.

P.S: I am using Ubuntu 20.04 and this is my first time using systemd services in Yocto with Dunfell version.

Preeti
  • 535
  • 1
  • 6
  • 30
  • A script that executes *"everytime system boots"* is not a *"post install script"*. The *"install"* is performed only one time. If there has been a (prior) *"successful update"*, then you'll need a method of providing that information to the system. – sawdust Dec 30 '21 at 21:18
  • Okay, but can we use systemd services to execute the script? If not, then can you please let me know how to achieve this? – Preeti Dec 31 '21 at 08:42
  • The aim is to make sure that, once updated Linux OS is up and running, I need to have a script executed which disables the "bootcounter" value. If this script is not called each time rootfs is successfully loaded then bootcounter value is incremented and after few reboots, a rollback is initialized. – Preeti Dec 31 '21 at 08:49
  • Post install script as the name suggest is for performing some actions after the packages are placed in the root-file-system or after a package is installed. Post install script does not perform boot script execution. I recommend you refer https://askubuntu.com/questions/919054/how-do-i-run-a-single-command-at-startup-using-systemd – Gaurav Pathak Jan 02 '22 at 08:13
  • Please refer https://wiki.yoctoproject.org/wiki/Cookbook:Appliance:Startup_Scripts to understand how to add a custom startup script – Gaurav Pathak Jan 02 '22 at 08:16
  • Hi Gaurav, Thanks for the info. I think the confusion is in "post install" words. I have updated post to indicate "custom script". Basically I want this script to be called "everytime system boots". As per my understanding, we can use systemd services to execute these scripts once rootfs has been successfully loaded. Please let me know how we can achieve this. – Preeti Jan 02 '22 at 21:21

1 Answers1

2

In order to make your custom-script.sh execute at Boot time (every time the system boots) using init.d, your custom-script.sh should have the following format

#!/bin/bash
# description: Description comes here....

# Source function library.
. /etc/init.d/functions

start() {
    # code to start app comes here
    # insert any kernel modules prior to 
    # executing/spawning any process that depends
    # on the LKM

}

stop() {
    # code to stop app comes here 
    # example: killproc program_name
    # Kill all the process started in start() function
    # remove any LKM inserted using insmod in start()

}

case "$1" in 
    start)
       start
       ;;
    stop)
       stop
       ;;
    restart)
       stop
       start
       ;;
    status)
       # code to check status of app comes here 
       # example: status program_name
       ;;
    *)
       echo "Usage: $0 {start|stop|status|restart}"
esac

exit 0 

Then you also need to add a symbolic link to your custom-script.sh in desired run-level directory e.g. /etc/rc3.d or /etc/rc5.d etc.

To add a symbolic link you need to edit core-image-base.bb (you can use your custom *.bb file as well):

DESCRIPTION = "Install script to Rootfs"
SUMMARY = "Install script to Rootfs and run after boot"
LICENSE = "CLOSED"

SRC_URI = "file://custom-script.sh"

do_install_append() {
    install -d 644 ${D}${sysconfdir}/init.d
    install -m 0755 ${WORKDIR}/custom-script.sh ${D}${sysconfdir}/init.d/custom-script.sh
    ln -sf ../init.d/custom-script.sh ${D}${sysconfdir}/rc4.d/S99custom-script.sh
    ln -sf ../init.d/custom-script.sh ${D}${sysconfdir}/rc4.d/K99custom-script.sh
}

FILES_${PN} = "${sysconfdir}/init.d"

So, I think you are missing a symbolic link to the desired run-level directory, and maybe you need to write your custom script to have a start() and stop() functions at least.

If you are using systemd, please refer Enable systemd services using yocto

Gaurav Pathak
  • 1,065
  • 11
  • 28
  • Hi Gaurav, I have a doubt regarding custom-script. Can the script be a simple script without `start()` and `stop()` functions? And also can I use `systemd service` to do the same for example, something like `install -m 644 ${WORKDIR}/custom-script.service ${D}${systemd_unitdir}/system`? – Preeti Jan 12 '22 at 14:45
  • 1
    Definitely you can install a systemd unit file, but I first suggest you to please read a little about systemd service files https://www.digitalocean.com/community/tutorials/understanding-systemd-units-and-unit-files Please refer [this link](https://stackoverflow.com/questions/45614578/enable-systemd-services-using-yocto) to understand how to add a systemd unit service using yocto. – Gaurav Pathak Jan 13 '22 at 07:10
  • 1
    And to answer your question, I think the init daemon startup library needs a start() and stop() function even if they are empty, otherwise it may throw an error. I am not sure, maybe you can experiment with it and post it here for others to clear their doubt as well :-) – Gaurav Pathak Jan 13 '22 at 07:16
  • Hello Gaurav, I tried to execute your solution to establish symbolic link to custom-script but I got the bitbake error as `DEBUG: Executing shell function do_install ln: failed to create symbolic link '/root/build-swu-v2/tmp/work/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/post-install-initscript/1.0-r0/image/etc/rc4.d/S99custom-script.sh': No such file or directory WARNING: exit code 1 from a shell command. ERROR: Execution of '/root/build-swu-v2/tmp/work/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/post-install-initscript/1.0-r0/temp/run.do_install.20665' failed with exit code 1` – Preeti Jan 13 '22 at 10:46
  • And the dir `build-swu-v2/tmp/work/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/post-install-initscript/1.0-r0/image/etc` contains only `init.d` with custom-script.sh inside. There is no `rc4.d` dir. Do I need to install `rc4.d` in `do_install()` with something like `install -d 644 ${D}${sysconfdir}/rc4.d`? Please do let me know. – Preeti Jan 13 '22 at 10:51
  • Does it have any directory starting with `rc` e.g. `rc0.d`, `rc1.d` etc.? – Gaurav Pathak Jan 13 '22 at 11:19
  • No, just `init.d` – Preeti Jan 13 '22 at 11:58
  • 1
    Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/241032/discussion-between-gaurav-pathak-and-preeti). – Gaurav Pathak Jan 13 '22 at 12:57
  • Hello @Gaurav, I have a doubt here: How to check whether these scripts are executed after system boot?For example, `S99custom-script.sh` and `K99custom-script.sh` files are available in `rc4.d` but I am not sure how I should check whether these startup scripts are called successfully? Is there a way to list all the scripts executed after booting? – Preeti Feb 08 '22 at 15:56