diff --git a/files/etc/crontabs.upgrademode/root b/files/etc/crontabs.upgrademode/root new file mode 100644 index 00000000..a2b4b396 --- /dev/null +++ b/files/etc/crontabs.upgrademode/root @@ -0,0 +1,3 @@ +*/5 * * * * /usr/local/bin/fccid +* * * * * /usr/local/bin/rssi_monitor + diff --git a/files/usr/local/bin/linkled b/files/usr/local/bin/linkled index 7d3c4bad..b1bf668f 100755 --- a/files/usr/local/bin/linkled +++ b/files/usr/local/bin/linkled @@ -30,13 +30,46 @@ case "$BOARD_TYPE" in esac -{ - while true; do - sleep 5; - if echo /neighbors | nc 127.0.0.1 2006 2>/dev/null | grep -q YES; then - echo 1 > "$LINK1LED/brightness" - else - echo 0 > "$LINK1LED/brightness" - fi - done; -} & +firmware_upgrade_mode() { + # Put the LED in "upgrade" mode + echo timer > "$LINK1LED/trigger" + echo 100 > "$LINK1LED/delay_on" + echo 100 > "$LINK1LED/delay_off" + echo 1 > "$LINK1LED/brightness" + +} + + +reset_led() { + # Reset the LED to a blank state + echo none > "$LINK1LED/trigger" + echo 0 > "$LINK1LED/brightness" +} + + +link_state() { + { + reset_led + + while true; do + sleep 5; + if echo /neighbors | nc 127.0.0.1 2006 2>/dev/null | grep -q YES; then + echo 1 > "$LINK1LED/brightness" + else + echo 0 > "$LINK1LED/brightness" + fi + done; + } & # Push into the background +} + +case $1 in + "upgrade" ) + firmware_upgrade_mode + ;; + "restore" ) + reset_led + ;; + *) + link_state + ;; +esac diff --git a/files/usr/local/bin/uploadctlservices b/files/usr/local/bin/uploadctlservices new file mode 100755 index 00000000..d3cc7bc0 --- /dev/null +++ b/files/usr/local/bin/uploadctlservices @@ -0,0 +1,73 @@ +#!/bin/sh + +# Alphabetical except where noted below +# log needs to start before cron (and maybe others) to be detected for logging. +serviceslist="log cron dropbear linkled odhcpd snmpd vtund vtundsrv xinetd" + +start_upgrade_mode() { + + touch /tmp/.upgrade_mode + + # drop the page cache to take pressure of tmps when uploading file + echo 3 > /proc/sys/vm/drop_caches + + #Kill processes + + for name in $serviceslist + do + "/etc/init.d/${name}" stop + done + + # Switch to a limited crontab list + /usr/sbin/crond -b -c /etc/crontabs.upgrademode -l 5 + + # Some services need to kill the last remaining processes + killall -9 dropbear + + # Put the LED in "upgrade" mode + /usr/local/bin/linkled upgrade + + # Purge the /tmp/ filesystem of unneeded files. + rm -Rf /tmp/node.history /tmp/olsrd.log /tmp/olsrd.watchdog /tmp/snrlog/ /tmp/snr.dat /tmp/web/firmware.list /tmp/.uci + +} + +remove_opkg_lists() { + rm -Rf /tmp/opkg-lists/ +} + +return_to_operating_mode() { + + killall -9 crond + + # If anything goes wrong after this point return the error code to the calling process + # as we could be in an unstable state. + set -e + + # Start up the services we stopped + for name in $serviceslist + do + "/etc/init.d/${name}" start + done + + rm /tmp/.upgrade_mode + +} + + +case $1 in + "upgrade" ) + start_upgrade_mode + remove_opkg_lists + ;; + "opkginstall" ) + start_upgrade_mode + ;; + "restore" ) + return_to_operating_mode + ;; + *) + echo "This program is not intended to be called by users." + ;; +esac + diff --git a/files/www/cgi-bin/admin b/files/www/cgi-bin/admin index 37587363..9ee2806d 100755 --- a/files/www/cgi-bin/admin +++ b/files/www/cgi-bin/admin @@ -152,6 +152,8 @@ if($parms{button_ul_fw} and -f "/tmp/web/upload/file") push @fw_output, "Firmware CANNOT be updated\n"; push @fw_output, "firmware file is not valid\n"; $fw_install = 0; + unlink("$tmpdir/firmware"); + system("/usr/local/bin/uploadctlservices","restore") and push @fw_output, "Failed to restart all services, please reboot this node.\n"; } } elsif($parms{firmfile} =~ /^patch\S+\.tgz$/) # firmware patch @@ -162,6 +164,8 @@ if($parms{button_ul_fw} and -f "/tmp/web/upload/file") { push @fw_output, "Firmware CANNOT be updated\n"; push @fw_output, "the uploaded file is not recognized\n"; + unlink("$tmpdir/firmware"); + system("/usr/local/bin/uploadctlservices","restore") and push @fw_output, "Failed to restart all services, please reboot this node.\n"; } } @@ -171,6 +175,7 @@ if($parms{button_dl_fw} and $parms{dl_fw} ne "default") if(get_default_gw() ne "none") { unlink "$tmpdir/firmware"; + system("/usr/local/bin/uploadctlservices","upgrade"); $ok = 0; foreach $serverpath (@serverpaths) { @@ -196,6 +201,8 @@ if($parms{button_dl_fw} and $parms{dl_fw} ne "default") push @fw_output, "Firmware CANNOT be updated\n"; push @fw_output, "firmware file is not valid\n"; $fw_install = 0; + unlink("$tmpdir/firmware"); + system("/usr/local/bin/uploadctlservices","restore") and push @fw_output, "Failed to restart all services, please reboot this node.\n"; } } elsif($parms{dl_fw} =~ /^patch\S+\.tgz$/) # firmware patch @@ -216,12 +223,16 @@ if($parms{button_dl_fw} and $parms{dl_fw} ne "default") push @fw_output, "Firmware CANNOT be updated\n"; push @fw_output, "patch file is not valid\n"; $patch_install = 0; + unlink("$tmpdir/firmware"); + system("/usr/local/bin/uploadctlservices","restore") and push @fw_output, "Failed to restart all services, please reboot this node.\n"; } } else { push @fw_output, "Firmware CANNOT be updated\n"; push @fw_output, "the downloaded file is not recognized\n"; + unlink("$tmpdir/firmware"); + system("/usr/local/bin/uploadctlservices","restore") and push @fw_output, "Failed to restart all services, please reboot this node.\n"; } } else @@ -388,6 +399,10 @@ if($patch_install and -f "$tmpdir/firmware") push(@fw_output, `cat $tmpdir/patch.out`) if $parms{dev}; push @fw_output, "Done.\n"; } + + unlink("$tmpdir/firmware"); + system("/usr/local/bin/uploadctlservices","restore") and push @fw_output, "Failed to restart all services, please reboot this node.\n"; + } @@ -411,6 +426,8 @@ if($parms{button_ul_pkg} and -f "/tmp/web/upload/file") system "mv -f /tmp/web/upload/file /tmp/web/upload/newpkg.ipk"; push @pkg_output, `opkg -force-overwrite install /tmp/web/upload/newpkg.ipk 2>&1`; system "rm -rf /tmp/opkg-*"; + unlink("/tmp/web/upload/newpkg.ipk"); + system("/usr/local/bin/uploadctlservices","restore") and push @pkg_output, "Failed to restart all services, please reboot this node.\n"; } # download package @@ -418,7 +435,9 @@ if($parms{button_dl_pkg} and $parms{dl_pkg} ne "default") { if(get_default_gw() ne "none") { + system("/usr/local/bin/uploadctlservices","opkginstall"); push @pkg_output, `opkg -force-overwrite install $parms{dl_pkg} 2>&1`; + system("/usr/local/bin/uploadctlservices","restore") and push @pkg_output, "Failed to restart all services, please reboot this node.\n"; } else { @@ -490,6 +509,8 @@ if($parms{button_ul_key} and -f "/tmp/web/upload/file") { push @key_output, "Key installed.\n"; } + unlink("/tmp/web/upload/file"); + system("/usr/local/bin/uploadctlservices","restore") and push @key_output, "Failed to restart all services, please reboot this node.\n"; } # remove key diff --git a/files/www/cgi-bin/perlfunc.pm b/files/www/cgi-bin/perlfunc.pm index 305c0552..33793bb4 100644 --- a/files/www/cgi-bin/perlfunc.pm +++ b/files/www/cgi-bin/perlfunc.pm @@ -212,8 +212,8 @@ sub read_postdata $line = fgets(10); push(@parse_errors, "not blank: '$line'") unless $line eq "\r\n"; $tmp = ""; - # drop the page cache to take pressure of tmps when uploading file - `echo 3 > /proc/sys/vm/drop_caches`; + # Put us in upgrade mode (purge files, shutdown services) + system("/usr/local/bin/uploadctlservices","upgrade"); system "mkdir -p /tmp/web/upload"; open($handle, ">/tmp/web/upload/file"); while(1) diff --git a/files/www/help.html b/files/www/help.html index e1704982..cfe75cf0 100644 --- a/files/www/help.html +++ b/files/www/help.html @@ -681,6 +681,13 @@ for download, but don't do this frivolously. The package information database gets stored locally and will use about 100KB of space in flash memory. The average user will probably never have to use this function.

+ +

+NOTE: When uploading any file (Firmware, Patch, or Package) a node operating +as a tunnel client or server will shutdown the tunnels before accepting the +file for upload. If your connection path to the node being updated requires +you to connect via a tunnel on the node the upload will not succeed. +

The Remove Package list shows all packages on the node. Selecting a package and clicking Remove will remove