Scripts and /etc/rc.local on bootup



  • @Costas-Costas In your original post, you say:

    I have some bash scripts ...

    Do you specifically use bash?
    The Omega standardly uses ash as its shell, though bash can be installed.

    In general, ash and bash are pretty well compatible with ash being a bit more light weight.
    I have been unable to ascertain significant differences in usage between the two and (so far) have had no problems assuming ash behaviours the same as bash so have never bothered to install bash

    A brief run down of the ash shell (also known as the Almquist shell) can be found here: https://en.wikipedia.org/wiki/Almquist_shell
    It is also the basis of the dash shell used by Debian and Ubuntu



  • @Kit-Bishop I haven't installed bash and I am using the default Omega ash.

    I guess it doesn't matter that the scripts start with:

    #!/bin/sh
    

    It's not that the scripts will not run it's just that some built in commands (e.g. LED control with echo command) are not running on bootup from /etc/rc.local but after bootup they run for . /etc/rc.local

    I will try sleep etc but syslog doesn't show any entries at the moment. Do I need to set a logging level?



  • Thank you @fossette and @Kit-Bishop the 'ash' scripts are now running on bootup.

    It turned out to be a path issue.
    I was running the scripts as a child process within node.js and the complex scripts had full paths but I had missed them off the basic change LED status scripts.

    I also worked out that logread provides access to the system log and further details are available at https://wiki.openwrt.org/doc/howto/log.essentials

    This leads on to 1 or 2 related questions.
    Another child process 'ash script in node.js calls is this command

    reboot -d 1

    It appears that because /etc/rc.local and my node.js processes are still running it will not accept the reboot request (even with the correct path for the script).

    If I manually kill the process then the Omega (2+) will reboot but I need an automated procedure.

    Does any one know how I might do this? I believe there are some fancy grep routines that could run in a script and kill the /etc/rc.local process but I was hoping for something a little more straightforward than that.

    The final point relates to the system clock. If I kill the /etc/rc.local it seems to crash the system time and reset at approx 111 minutes prior to the real clock time. I could understand it if it was out by 120 minutes as this is my timezone adjustment.

    Where is the Omega picking up this weird system time following the kill process?
    For reference /etc/config/system has the correct settings for timezone etc.



  • @Costas-Costas , if you launch your script from /etc/rc.local using &, /etc/rc.local will eventually terminate by itself. You just need to have a long enough sleep command inside your script.



  • @fossette I found that I didn't need sleep or & for my scripts to run, it was simply a bad path.

    Just to add a few more details the current routine is:

    An ash script in /etc/rc.local calls another ash script that runs a node.js script.
    All this is done without sleep and &.
    The node.js script never stops as it needs to run at all times unless the reboot command is requested from the Smartphone app that is tied to the script.
    I will try with a single ash script rather than the two I am currently using as it might work better with the correct path's. Will also test out & to see if that will let me run the reboot command.



  • No amount of sleep or & works with node.js.
    node.js is notoriously difficult to start on boot up for regular linux systems and normally requires forever and forever-service.
    Not sure if this is available for Omega hardware but I can reliably start node.js with the 2 ash scripts. First script being in /etc/rc.local

    I just can't reboot the Omega via a script when node.js is started with the 2 scripts from bootup.

    Maybe I'll have to go hunting for the grep and kill process routine.
    Does anyone happen to have an ash script for finding and killing a process for example called rstomega ?



  • Ok I think I have worked out the command.

    kill $(ps | grep '[r]'c.local | awk '{print $1}')
    

    Will test in my scripts but this procedure does seem to trash the time settings.



  • Working script to reboot Omega when scripts are started with /etc/rc.local

    #!/bin/sh
    # reboot Omega script by Costas for scripts started with /etc/rc.local
    pid1=$(ps | grep '[r]'c.local | awk '{print $1}')
    echo $pid1 >> /root/reboots.txt
    echo "Process number to kill is:" $pid1
    kill -9 $pid1
    sleep 20
    reboot -d 1
    # line above DOESN'T WORK FOR SCRIPTS STARTED WITH /etc/rc.local
    # unless you kill /etc/rc.local first
    echo "Please wait for your Omega to reboot"
    

    I just need to know why the system reboot time for the Omega is set at 13:16:43 (maybe firmware build time perhaps). Will start a new thread for this.



  • Putting things in rc.local is a bit of an expedient measure, and the shutdown issue starts to show the limitiations.

    Formally, the way you're supposed to configure long-running services on a system with this type of setup is to make an entry for each one in /etc/init.d which can be setup both with commands to run on startup and on shutdown, and also gives you command line access to start/stop the service.

    https://wiki.openwrt.org/doc/techref/initscripts



  • @Chris-Stratton in due course I will look at /etc/init.d but I never want to stop the service. What I want to be able to do is reboot the Omega. Maybe a regular reboot -d 1 will work if I use /etc/init.d for node.js rather than /etc/rc.local



  • @Costas-Costas said in Scripts and /etc/rc.local on bootup:

    @Chris-Stratton in due course I will look at /etc/init.d but I never want to stop the service.

    Actually stopping the service appears to be exactly what you need to do in order to cleanly reboot - which is why the formal method creates both startup scripts that run automatically on startup, and shutdown scripts that run automatically on shutdown (to power-off or reboot).

    Another reason for being able to start/stop it at the command line is if you are doing work on the system - for example if you want to copy a new version of the executable and configuration files and then start it up again using those, without doing a reboot.



  • @Chris-Stratton actually you are right and as long as my script then includes the reboot -d 1 I should be fine.

    The Omega is a remote device controlled by a Smartphone app (Blynk) so once node.js is terminated there is no control from the app. Therefore the only command that can be issued after terminating node.js is reboot. No system admin or the like, just a reboot so the app has control again of the Omega.



  • The complication that you face in trying to do a custom shutdown is that you'll be shutting down the thing that begins your reboot, before it needs to begin it. That can be done, but requires that the commands not be tied to their parent process, so that they can outlive its death.

    Perhaps what you should be doing is triggering the system reboot command, and letting that shut down your service and everything else automatically, in configured order, and (if everything is setup right) then reboot.

    FWIW if you anticipate frequent reboots or unexpected power loss, and have limited or no need for persistent storage modifiable at runtime, I'd consider running the system from a ram disk, which makes a hard reboot safe. On the downside that means that any need for persistent storage has to be explicitly handled; on the upside, you get to control exactly how the storage is done and when it is flushed to a shutdown-safe state.



  • Tried that, doesn't work.

    reboot -d 1 will not reboot an Omega that is running my script from /etc/rc.local.
    Need to test if it will reboot a /etc/init.d script.

    Not expecting to have to do reboots but I like to know it's available remotely if required.



  • @Costas-Costas said in Scripts and /etc/rc.local on bootup:

    Tried that, doesn't work.

    reboot -d 1 will not reboot an Omega that is running my script from /etc/rc.local.

    Because it has no way of stopping that script to get the system to a safely rebootable state. Or more importantly its children - the script itself should have done its work and completed shortly after boot, not continued to run.

    Need to test if it will reboot a /etc/init.d script.

    When properly setup, a properly setup and invoked reboot command should run the shutdown side of your script to top your custom service, get the system to a safely rebootable state, then reboot it.

    You can of course invent new ways of doing things; the point is that there's already a mechanism for doing this, which is available if the system and your extensions to it are correctly configured.



  • Warning init.d in the wrong hands is dangerous!

    @Chris-Stratton I set up init.d, but badly and now I'm locked out of the Omega (2+).

    I removed the & from the node.js call because I thought it was making the script restart when I stopped it. I think actually the node.js script has inbuilt restart as the service should run at all times.

    In the init.d script I set START=40 and I'm guessing this is before ssh kicks in and without the & my perpetual node.js script has taken over control of the Omega.

    I still have Smartphone control of the Omega, excluding reboot but I can't make any further changes to it. I don't use any of those dock things.

    What is the process for resetting the Omega now that i'm locked out?



  • @Costas-Costas said in Scripts and /etc/rc.local on bootup:

    Warning init.d in the wrong hands is dangerous!

    root access in the wrong hands is dangerous, but less so on a system with so little corruptible state (until you get to interacting with the uboot and firmware partitions)

    @Chris-Stratton I set up init.d, but badly and now I'm locked out of the Omega (2+).

    Only if you rely on the network for maintenance while developing, which would be a problem sooner or later anyway. This is what safe mode on the serial console is for - it boots without the overlay containing your changes.

    Or you can do a factory reset via the button.

    Given the way these systems store changes, you need to be backing up your work anyway.



  • @Chris-Stratton I will try console access shortly but I did try"reset" earlier without success.
    I have the latest firmware. Should reset just be held to ground for up to 30 seconds and does it only kick in if you do it on reboot?



  • @Chris-Stratton console access worked just fine, phew.

    Will changing START=40 to something like START = 100 allow ssh to kick in before my init.d script?
    I have added the & to my node.js call but I'm not convinced it will work because the node.js script is self perpetuating.

    Still interested to know from anyone how reset to factory firmware is done with the rst pin.



  • @Costas-Costas said in Scripts and /etc/rc.local on bootup:

    @Chris-Stratton console access worked just fine, phew.

    Will changing START=40 to something like START = 100 allow ssh to kick in before my init.d script?

    That's probably not a workable goal - even if you get the ssh server up first, you may not have network connected yet, have had a chance to use it yet, etc.

    Generally, if you are going to have a system with only radio access, you first test heavily on a system that has serial console access, and changes only make it o the radio-based system after they have been well proven.

    More complex systems sometimes include an auto-rollback to an older stable version or a maintenance mode (in your case, ssh but not node red), for example by leaving indications behind that can be seen on startup after a crash. It looks like the MT7688 has some registers intended for this kind of usage, which is simpler than trying to do it with magic values in main memory and then having to make sure that they don't get lost in DDR re-initialization, or startup memory walking.

    Essentially you could do something like this:

    • on boot, if register is blank set it to UNCOMMANDED_REBOOT_1
    • if it is already UNCOMMANDED_REBOOT_1 set it to UNCOMMANDED_REBOOT_2
    • if it is UNCOMMANDED_REBOOT_2 startup in safe mode.

    When commanding a reboot, first set the register to REBOOT_COMMANDED so it is clear that this was intentional and not a crash.


Log in to reply
 

Looks like your connection to Onion Community was lost, please wait while we try to reconnect.