OpenWrt Forum Archive

Topic: [Solved] Reboot automatically after executing uci-defaults script?

The content of this topic has been archived on 2 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

I place a script in /etc/uci-defaults in my own compiled firmware for auto configuring everything for the router at first boot, to avoid the hassle of manually configuring after every sysupgrade or reverting settings to factory defaults. I'm not sure whether this is the best choice, but I found it quite convenient for me.

My question is, how can I automatically reboot my router after the uci-defaults script is executed? Adding `reboot` to the script leads to an infinite loop, probably because the script does not exit properly, and then it is not deleted and therefore executed again during the next boot.

I have this question because sometimes I need to upgrade the router remotely via SSH (I know this is not recommended, but I have to), and I find that sometimes a reboot is needed to make the router work properly after the auto configuration, while a cold reset is not an option. I searched in the forum before posting, and I found this thread which has a very similar question, but it has been unanswered for a year.

I'm wondering if anyone knows how to achieve this, or have better suggestions. Thanks a lot in advance!

Update:
Unfortunately, I have tried all the methods provided below, but I still encounter an infinite reboot. So here is my script named 99-uci-703, I will appreciate if you can tell me how to modify the script.

#!/bin/sh

test -f /root/wakeup.sh && exit 0

uci batch <<EOF
    set system.@system[0].hostname='WR703N'
    set system.@system[0].conloglevel=8
    set system.@system[0].cronloglevel=8
    set system.@system[0].timezone=HKT-8
    set system.@system[0].zonename='Asia/Hong Kong'
    delete system.ntp.server
    add_list system.ntp.server='0.asia.pool.ntp.org'
    add_list system.ntp.server='time.asia.apple.com'
    add_list system.ntp.server='time.windows.com'
    commit system
EOF

uci batch <<EOF
    # set dropbear.@dropbear[0].Interface=lan
    set dropbear.@dropbear[0].Port=22
    set dropbear.@dropbear[0].PasswordAuth=off
    set dropbear.@dropbear[0].RootPasswordAuth=off
    set dropbear.@dropbear[0].GatewayPorts=on
    commit dropbear
EOF
/etc/init.d/dropbear start
/etc/init.d/dropbear enable

uci batch <<EOF
    add firewall rule
    set firewall.@rule[-1].name='Allow-SSH'
    set firewall.@rule[-1].src=wan
    set firewall.@rule[-1].target=ACCEPT
    set firewall.@rule[-1].proto=tcp
    set firewall.@rule[-1].dest_port=22
    commit firewall
EOF
/etc/init.d/firewall restart

uci batch <<EOF
    set wireless.radio0.disabled=0
    set wireless.radio0.channel=6
    set wireless.radio0.hwmode=11g
    set wireless.radio0.htmode=HT20
    set wireless.radio0.txpower=20
    set wireless.radio0.country=HK
    set wireless.@wifi-iface[0].disabled=0
    set wireless.@wifi-iface[0].network=lan
    set wireless.@wifi-iface[0].mode=ap
    set wireless.@wifi-iface[0].ssid=myssid
    set wireless.@wifi-iface[0].encryption='psk2+ccmp'
    set wireless.@wifi-iface[0].key='mypassword'
    # set wireless.@wifi-iface[0].macfilter=allow
    # add_list wireless.@wifi-iface[0].maclist=AA:BB:CC:DD:EE:FF
    # set wireless.@wifi-iface[0].hidden=1
    commit wireless
EOF

uci batch <<EOF
    set dhcp.lan.leasetime=12h
    set dhcp.lan.start=101
    set dhcp.lan.limit=99
    set dhcp.lan.ra_management=1
    add dhcp host
    set dhcp.@host[0]=host
    set dhcp.@host[0].name=Evan-PC
    set dhcp.@host[0].mac=11:11:11:11:11:11
    set dhcp.@host[0].ip=192.168.128.2
    add dhcp host
    set dhcp.@host[1]=host
    set dhcp.@host[1].name=Evan-phone
    set dhcp.@host[1].mac=22:22:22:22:22:22
    set dhcp.@host[1].ip=192.168.128.3
    commit dhcp
EOF
/etc/init.d/dnsmasq restart

uci batch <<EOF
    delete network.globals
    set network.lan=interface
    delete network.lan.ifname
    delete network.lan.type
    set network.lan.proto=static
    set network.lan.ipaddr=192.168.128.1
    set network.lan.netmask=255.255.255.0
    set network.wan=interface
    set network.wan.ifname=eth0
    set network.wan.proto=dhcp
    set network.wan.macaddr=01:23:45:67:89:AB
    set network.wan6=interface
    set network.wan6.proto=6to4
    commit network
EOF
wifi
/etc/init.d/network restart

uci batch <<EOF
    set ddns.myddns_ipv4.enabled=1
    set ddns.myddns_ipv4.service_name='No-IP.com'
    set ddns.myddns_ipv4.username=myusername
    set ddns.myddns_ipv4.password=mypassword
    set ddns.myddns_ipv4.domain='mydomain.ddns.net'
    set ddns.myddns_ipv4.ip_source=network
    set ddns.myddns_ipv4.force_interval=24
    set ddns.myddns_ipv4.force_unit=hours
    set ddns.myddns_ipv4.check_interval=10
    set ddns.myddns_ipv4.check_unit=minutes
    commit ddns
EOF
/etc/init.d/ddns start
/etc/init.d/ddns enable

cat <<'EOF' >/root/wakeup.sh
#!/bin/sh

/usr/bin/etherwake -D -i "eth0.2" "12:34:56:78:90:AB"

EOF

chmod +x /root/wakeup.sh

(crontab -l ; echo '30 6 * * * reboot')| crontab -
/etc/init.d/cron start
/etc/init.d/cron enable

(sleep 10 ; reboot )&
exit 0

Update 2:

DBAA wrote:

I don't think you should be rebooting. Very little is run before these scripts are executed.  Only  /etc/rc.d/S00sysfixtime -> ../init.d/sysfixtime runs before /etc/rc.d/S10boot -> ../init.d/boot which is what runs the uci-defaults scripts. You also need to get rid of starting or restarting services in your script - let them be started normally latter on in the boot.

I got it. I read about the boot process of OpenWrt and now I understand why I should not reboot in a uci-defaults script. I also removed those "starting services", and compiled a new firmware with the modified script. So far I have not encounter any problem.
Thanks everyone for your help!:)

(Last edited by wyf88 on 11 Jan 2016, 16:26)

1)
How about including a line to manually delete this uci-defaults script just before the reboot line?

And you need to make sure that the other uci-defaults actions have been properly run. So this should probably be named like 99-something.

2)
You might also try using & to spawn a new shell, sleeping a while and then rebooting:

(sleep 10 ; reboot )&

For example, I am using this in /etc/rc.local to have a delayd logging action:

(sleep 15 ; logger -t "syslog" - ntp client should have set time by now -)&

3)
Completely other approach would be to include the config files themselves in the build as custom files <buildroot>/files/etc/network etc.. That would be suitable if you are building for one single personal router.

(Last edited by hnyman on 5 Jan 2016, 12:03)

hnyman wrote:

1)
How about including a line to manually delete this uci-defaults script just before the reboot line?

And you need to make sure that the other uci-defaults actions have been properly run. So this should probably be named like 99-something.

2)
You might also try using & to spawn a new shell, sleeping a while and then rebooting:

(sleep 10 ; reboot )&

For example, I am using this in /etc/rc.local to have a delayd logging action:

(sleep 15 ; logger -t "syslog" - ntp client should have set time by now -)&

3)
Completely other approach would be to include the config files themselves in the build as custom files <buildroot>/files/etc/network etc.. That would be suitable if you are building for one single personal router.

Thanks a lot hnyman! I have tried both:
1) insert a `(sleep 10 ; reboot )&` before `exit 0` and
2) include a line to remove the script before reboot,
but both of them led to an infinite reboot anyway. And I have several different routers to maintain, so I would prefer the auto configuration through a script.

Actually I learnt a lot about the use of uci-defaults and other stuffs from your previous threads. Thanks again for that! smile

(Last edited by wyf88 on 13 Jan 2016, 15:59)

The fact that your uci-defaults script is ran every time the router is rebooted is cause for concern imho.

If you post sanitized script it might not be a worst idea to have another set of eyes on it. I'd start with renaming the script to 99-something to ensure it's executed last and has higher chance of completing.

Also, not sure if that would help in your case, but when I needed to dl and run reghack just once I ended up adding the code to the uci-defaults script to create the hotplug script for WAN being up, downloading and running reghack files, deleting hotplug script on successful reghack completion and then rebooting the router.

test for existence of bogus file
if it exists exit with success
otherwise touch bogus file and reboot.

something like this in arokh builds.

I would recommend the same as anomeome.

stangri wrote:

The fact that your uci-defaults script is ran every time the router is rebooted is cause for concern imho.

If you post sanitized script it might not be a worst idea to have another set of eyes on it. I'd start with renaming the script to 99-something to ensure it's executed last and has higher chance of completing.

Also, not sure if that would help in your case, but when I needed to dl and run reghack just once I ended up adding the code to the uci-defaults script to create the hotplug script for WAN being up, downloading and running reghack files, deleting hotplug script on successful reghack completion and then rebooting the router.

I think this should work. Thank you for sharing your experience!
As for the naming of the script, I've looked into the wiki of UCI, but there's not an explicit explanation to the naming. I guess the scripts with filenames beginning with letters will be executed after those beginning with numbers, but I will change to file name to begin with 99 anyway.

(Last edited by wyf88 on 11 Jan 2016, 05:12)

anomeome wrote:

test for existence of bogus file
if it exists exit with success
otherwise touch bogus file and reboot.

something like this in arokh builds.

tmo26 wrote:

I would recommend the same as anomeome.

I've looked into the build of arokh. It does have something like `test -f /etc/.arokh && exit 0` in the front of his 99-arokh in the uci-defaults folder, but it doesn't have a `reboot` after configuration.
I tried to include a test at the beginning of my script and conduct reboot in the end, but still it led to an infinite reboot.

(Last edited by wyf88 on 11 Jan 2016, 05:15)

Unfortunately, I have tried all the methods provided below, but I still encounter an infinite reboot. So I post my script and I will appreciate if anyone can tell me how to modify the script.

I don't think you should be rebooting. Very little is run before these scripts are executed.  Only  /etc/rc.d/S00sysfixtime -> ../init.d/sysfixtime runs before /etc/rc.d/S10boot -> ../init.d/boot which is what runs the uci-defaults scripts. You also need to get rid of starting or restarting services in your script - let them be started normally latter on in the boot.

(Last edited by DBAA on 11 Jan 2016, 08:14)

use a flag it you must action a reboot ....

/etc/uci-defaults/01_make_reboot_flag

#!/bin/sh

## Create the /etc/config/reboot file and set the flag ##
touch /etc/config/reboot
echo "config reboot 'flags'" > /etc/config/reboot
echo "option reboot_flag '1' >>  /etc/config/reboot

exit 0

/etc/uci-defaults/02_your_reboot_script

#!/bin/sh

## GET THE FLAG VALUE ##
flag=`uci get reboot.flags.reboot_flag`

{ .... do your work ....}

## IF FLAG IS SET, UNSET IT AND REBOOT ELSE EXIT NORMALLY ##
if [ $flag -gt 0 ]
 then
  uci set reboot.flags.reboot_flag=0
  uci commit
  reboot
elif [ $flag -lt 1 ]
  then
 return 0
fi

should do the trick smile

(Last edited by hostle19 on 11 Jan 2016, 08:19)

hostle19 wrote:

use a flag it you must action a reboot ....

/etc/uci-defaults/01_make_reboot_flag

#!/bin/sh

## Create the /etc/config/reboot file and set the flag ##
touch /etc/config/reboot
echo "config reboot 'flags'" > /etc/config/reboot
echo "option reboot_flag '1' >>  /etc/config/reboot

exit 0

/etc/uci-defaults/02_your_reboot_script

#!/bin/sh

## GET THE FLAG VALUE ##
flag=`uci get reboot.flags.reboot_flag`

{ .... do your work ....}

## IF FLAG IS SET, UNSET IT AND REBOOT ELSE EXIT NORMALLY ##
if [ $flag -gt 0 ]
 then
  uci set reboot.flags.reboot_flag=0
  uci commit
  reboot
elif [ $flag -lt 1 ]
  then
 return 0
fi

should do the trick smile

That's really a smart idea, thanks a lot!

DBAA wrote:

I don't think you should be rebooting. Very little is run before these scripts are executed.  Only  /etc/rc.d/S00sysfixtime -> ../init.d/sysfixtime runs before /etc/rc.d/S10boot -> ../init.d/boot which is what runs the uci-defaults scripts. You also need to get rid of starting or restarting services in your script - let them be started normally latter on in the boot.

I got it. I read about the boot process of OpenWrt and now I understand why you say that I should not reboot in my script. I also removed those starting services, and compiled a new firmware with the modified script. So far I have not encounter any problem.
Thanks a lot for your help!

The discussion might have continued from here.